diff --git a/.asf.yaml b/.asf.yaml deleted file mode 100644 index daa5a020..00000000 --- a/.asf.yaml +++ /dev/null @@ -1,8 +0,0 @@ -github: - homepage: https://datasketches.apache.org - ghp_branch: gh-pages - ghp_path: /docs - - features: - # Enable issue management - issues: true diff --git a/.github/workflows/build_wheels.yml b/.github/workflows/build_wheels.yml deleted file mode 100644 index 0a78c0c2..00000000 --- a/.github/workflows/build_wheels.yml +++ /dev/null @@ -1,122 +0,0 @@ -name: Build Python Wheels - -on: - workflow_dispatch: - -env: - BUILD_TYPE: Release - MIN_CIBUILDWHEEL_VERSION: 2.22.0 - PYTHON_VERSION: 3.x - -jobs: - build_sdist: - name: Source distribution - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - uses: actions/setup-python@v5 - name: Install Python - with: - python-version: ${{ env.PYTHON_VERSION }} - - - name: Install build package - run: python -m pip install build --user - - - name: Build sdist - run: python -m build --sdist --outdir dist - - - uses: actions/upload-artifact@v4 - with: - name: sdist - path: dist/*.tar.gz - compression-level: 0 # contents are already compressed - - - build_wheels: - name: ${{ matrix.config.name }} - runs-on: ${{ matrix.config.os }} - strategy: - matrix: - config: - - { - name: "MacOS Latest (Intel)", - os: macos-latest, - cibw-arch: macosx_x86_64 - } - - { - name: "MacOS Latest (Apple Silicon)", - os: macos-latest, - cibw-arch: macosx_arm64 - } - - { - name: "Ubuntu Latest (x86_64, manylinux)", - os: ubuntu-latest, - cibw-arch: manylinux_x86_64, - } - - { - name: "Ubuntu Latest (ARM64, manylinux)", - os: ubuntu-latest, - cibw-arch: manylinux_aarch64, - use-qemu: true - } - - { - name: "Ubuntu Latest (x86_64, musllinux)", - os: ubuntu-latest, - cibw-arch: musllinux_x86_64 - } - - { - name: "Ubuntu Latest (ARM64, musllinux)", - os: ubuntu-latest, - cibw-arch: musllinux_aarch64, - use-qemu: true - } - - { - name: "Windows Latest", - os: windows-latest, - cibw-arch: win_amd64 - } - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: ${{ env.PYTHON_VERSION }} - - - name: Set up QEMU for linux/arm64 builds - if: runner.os == 'Linux' && matrix.config.use-qemu == true - uses: docker/setup-qemu-action@v3 - with: - platforms: arm64 - - - name: Install Python dependencies - run: python -m pip install cibuildwheel~=${{ env.MIN_CIBUILDWHEEL_VERSION }} - - - name: Build wheels - run: python -m cibuildwheel --output-dir dist - env: - CIBW_ENVIRONMENT_MACOS: CMAKE_OSX_ARCHITECTURES=${{ matrix.config.cibw-arch == 'macosx_x86_64' && 'x86_64' || matrix.config.cibw-arch == 'macosx_arm64' && 'arm64' || '' }} - CIBW_BUILD: "*-${{ matrix.config.cibw-arch }}" - MACOSX_DEPLOYMENT_TARGET: "10.14" # min supporting c++17 - - - uses: actions/upload-artifact@v4 - with: - name: wheels-${{ matrix.config.os }}-${{ matrix.config.cibw-arch }} - path: ./dist/*.whl - compression-level: 0 # contents are already compressed - - - aggregate_artifacts: - name: Aggregate artifacts - runs-on: ubuntu-latest - needs: [build_sdist, build_wheels] - steps: - - name: Merge Artifacts - uses: actions/upload-artifact/merge@v4 - with: - name: python_wheels - compression-level: 0 - delete-merged: true diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index ae2699c4..00000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: Continuous Integration - -on: [push, pull_request] - -env: - BUILD_TYPE: Release - -jobs: - build: - name: ${{ matrix.config.name }} - runs-on: ${{ matrix.config.os }} - strategy: - fail-fast: false - matrix: - config: - - { - name: "MacOS Latest, Clang", - os: macos-latest, - test_target: test, - cc: "clang", cxx: "clang++" - } - - { - name: "Ubuntu Latest, GCC", - os: ubuntu-latest, - test_target: test, - cc: "gcc", cxx: "g++" - } - - { - name: "Windows Latest, MSVC", - os: windows-latest, - test_target: RUN_TESTS, - cc: "cl", cxx: "cl", - environment_script: "C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Auxiliary/Build/vcvars64.bat" - } - - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Set up Python 3.x - uses: actions/setup-python@v5 - # 3.x uses the latest minor version of python3. This may break briefly when there is a new version - # but dependent libraries (e.g. numpy) have not yet released a compatible update. - # May need to enable version pinning (e.g. 3.10) temporarily at times. - with: - python-version: '3.x' - - name: Install Python dependencies - run: python -m pip install --upgrade pip setuptools wheel tox - - name: Build and run Python tests - run: python -m tox diff --git a/.github/workflows/sphinx.yml b/.github/workflows/sphinx.yml deleted file mode 100644 index 12e864f6..00000000 --- a/.github/workflows/sphinx.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: Sphinx - -on: - push: - branches: - - main - workflow_dispatch: - -jobs: - build-documentation: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Install Python - uses: actions/setup-python@v5 - with: - python-version: '3.x' - - name: Install Datasketches and Sphinx - run: python -m pip install . sphinx sphinx-rtd-theme - - name: Run Sphinx - run: cd docs; make html - - name: Pages Deployment - uses: peaceiris/actions-gh-pages@v3.9.3 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./docs/build/html - destination_dir: docs/${{ github.ref_name }} - enable_jekyll: false - allow_empty_commit: false - force_orphan: false - publish_branch: gh-pages diff --git a/.gitignore b/.gitignore deleted file mode 100644 index f601b9b7..00000000 --- a/.gitignore +++ /dev/null @@ -1,22 +0,0 @@ -# Eclipse project files -.cproject -.project -.settings/ - -# Visual Studio Code -.vscode/ - -# OSX files -.DS_Store - -# Python created files -.eggs/ -.tox/ -dist/ -datasketches.egg-info/ -datasketches/__pycache__/ -tests/__pycache__/ - -# build aritfacts -build/ -docs/build/ \ No newline at end of file diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index 2e74346b..00000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,135 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -cmake_minimum_required(VERSION 3.16.0) - -string(TIMESTAMP DT %Y%m%d UTC) -string(TIMESTAMP HHMM %H%M UTC) -configure_file(version.cfg.in version.cfg @ONLY) -file(STRINGS ${CMAKE_CURRENT_BINARY_DIR}/version.cfg BASE_VERSION) - -project(DataSketchesPython - VERSION ${BASE_VERSION} - LANGUAGES CXX) - -message("Configuring DataSketches Python version ${BASE_VERSION}") - -include(GNUInstallDirs) -include(CMakeDependentOption) - -set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) - -set(CMAKE_MACOSX_RPATH ON) - -set(CMAKE_CXX_STANDARD 17) - -# enable compiler warnings globally -# derived from https://foonathan.net/blog/2018/10/17/cmake-warnings.html -# and https://arne-mertz.de/2018/07/cmake-properties-options/ -if (MSVC) - add_compile_options(/W4) - set(CMAKE_DEBUG_POSTFIX "d") -else() - add_compile_options(-Wall -pedantic -W -Wextra) -endif() - -if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "9.0") - add_compile_options(-Wimplicit-fallthrough=3) -endif() - -# Code generation options, to ensure shaerd libraries work and are portable -set(CMAKE_POSITION_INDEPENDENT_CODE ON) -set(CMAKE_C_EXTENSIONS OFF) -set(CMAKE_CXX_EXTENSIONS OFF) - -if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.18.0") -find_package(Python 3.8 - REQUIRED COMPONENTS Interpreter Development.Module NumPy - OPTIONAL_COMPONENTS Development.SABIModule) -else() -find_package(Python COMPONENTS Interpreter Development NumPy REQUIRED) -endif() - -if(Python_VERSION VERSION_LESS "3.8") - message(FATAL_ERROR "DataSketches requires at least Python3.8") -endif() - -execute_process( - COMMAND "${Python_EXECUTABLE}" -m nanobind --cmake_dir - OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE NB_DIR) -list(APPEND CMAKE_PREFIX_PATH "${NB_DIR}") -find_package(nanobind CONFIG REQUIRED) - -nanobind_add_module(python MODULE LTO NOMINSIZE STABLE_ABI NB_STATIC) - -set_target_properties(python PROPERTIES - PREFIX "" - OUTPUT_NAME _datasketches -) - -target_include_directories(python - PUBLIC - $/include> - $ -) - -# ensure we make a .so on Mac rather than .dylib -if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - set_target_properties(python PROPERTIES SUFFIX ".so") -endif() - -target_sources(python - PRIVATE - src/datasketches.cpp - src/hll_wrapper.cpp - src/kll_wrapper.cpp - src/cpc_wrapper.cpp - src/fi_wrapper.cpp - src/theta_wrapper.cpp - src/tuple_wrapper.cpp - src/vo_wrapper.cpp - src/ebpps_wrapper.cpp - src/req_wrapper.cpp - src/quantiles_wrapper.cpp - src/density_wrapper.cpp - src/ks_wrapper.cpp - src/count_wrapper.cpp - src/tdigest_wrapper.cpp - src/vector_of_kll.cpp - src/py_serde.cpp -) - -cmake_policy(SET CMP0097 NEW) -include(ExternalProject) -ExternalProject_Add(datasketches - GIT_REPOSITORY https://github.com/apache/datasketches-cpp.git - GIT_TAG 5.2.0 - GIT_SHALLOW true - GIT_SUBMODULES "" - INSTALL_DIR /tmp/datasketches - CMAKE_ARGS -DBUILD_TESTS=OFF -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX=/tmp/datasketches -) -ExternalProject_Get_property(datasketches INSTALL_DIR) -set(datasketches_INSTALL_DIR ${INSTALL_DIR}) -message("Source dir of datasketches = ${datasketches_INSTALL_DIR}") -message("Numpy include dir(s): ${Python_NumPy_INCLUDE_DIRS}") -target_include_directories(python - PRIVATE - ${datasketches_INSTALL_DIR}/include/DataSketches - ${Python_NumPy_INCLUDE_DIRS} - ) -add_dependencies(python datasketches Python::NumPy) diff --git a/LICENSE b/LICENSE deleted file mode 100644 index c8582e5d..00000000 --- a/LICENSE +++ /dev/null @@ -1,285 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - - -APPENDIX A: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - ------------------------------------------------------------- - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - ------------------------------------------------------------- - - - -APPENDIX B: Additional licenses relevant to this product. - - This product includes a number of source files with code that has been - adapted from 3rd party sources including sources that may be subject - to different copyright notices and license terms. Your use of - the source code for these subcomponents is subject to the terms and - conditions of the following licenses. - - - - ============================================================= - MIT License - ============================================================= - Original source code: - https://github.com/benjaminjack/python_cpp_example - ------------------------------------------------------------- - Copyright (c) 2017 Benjamin R. Jack - - MIT License (https://opensource.org/licenses/MIT): - - 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. - ------------------------------------------------------------- - Code locations: - * https://github.com/apache/datasketches-python/blob/master/setup.py - that is adapted from the above. - - - ============================================================= - BSD License - ============================================================= - Original source code: - https://github.com/wjakob/nanobind/blob/master/LICENSE - - Copyright (c) 2022 Wenzel Jakob , All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index 37ab2fc0..00000000 --- a/MANIFEST.in +++ /dev/null @@ -1,27 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - - -# build/config files -include version.cfg.in -#include pybind11Path.cmd -include CMakeLists.txt - -# content files -include src/* -include include/* -include tests/* diff --git a/NOTICE b/NOTICE deleted file mode 100644 index 1668e075..00000000 --- a/NOTICE +++ /dev/null @@ -1,12 +0,0 @@ -Apache DataSketches Python -Copyright 2025 The Apache Software Foundation - -Copyright 2015-2018 Yahoo Inc. -Copyright 2019-2020 Verizon Media -Copyright 2021- Yahoo Inc. - -This product includes software developed at -The Apache Software Foundation (http://www.apache.org/). - -Prior to moving to ASF, the software for this project was developed at -Yahoo Inc. (https://developer.yahoo.com). diff --git a/README.md b/README.md deleted file mode 100644 index 99614966..00000000 --- a/README.md +++ /dev/null @@ -1,106 +0,0 @@ -Apache DataSketchs Logo - -# The Apache DataSketches Library for Python - -This is the official version of the [Apache DataSketches](https://datasketches.apache.org) Python library. - -In the analysis of big data there are often problem queries that don’t scale because they require huge compute resources and time to generate exact results. Examples include count distinct, quantiles, most-frequent items, joins, matrix computations, and graph analysis. - -If approximate results are acceptable, there is a class of specialized algorithms, called streaming algorithms, or sketches that can produce results orders-of magnitude faster and with mathematically proven error bounds. For interactive queries there may not be other viable alternatives, and in the case of real-time analysis, sketches are the only known solution. - -This package provides a variety of sketches as described below. Wherever a specific type of sketch exists in Apache DataSketches packages for other languages, the sketches will be portable between languages (for platforms with the same endianness). - -## Building and Installation - -Once cloned, the library can be installed by running `python3 -m pip install .` in the project root directory which will also install the necessary dependencies, namely NumPy and [Nanobind](https://github.com/wjakob/nanobind). - -If you prefer to call the `setup.py` build script directly, which is discouraged, you must first install `nanobind` and `numpy`, as well as any other dependencies listed under the build-system section in `pyproject.toml`. - -The library is also available from PyPI via `python3 -m pip install datasketches`. - -## Usage - -Having installed the library, loading the Apache DataSketches Library in Python is simple: `import datasketches`. - -The unit tests are mostly structured in a tutorial style and can be used as a reference example for how to feed data into and query the different types of sketches. - -## Available Sketch Classes - -- KLL (Absolute Error Quantiles) - - `kll_ints_sketch` - - `kll_floats_sketch` - - `kll_doubles_sketch` - - `kll_items_sketch` -- Quantiles (Absolute Error Quantiles, inferior algorithm) - - `quantiles_ints_sketch` - - `quantiles_floats_sketch` - - `quantiles_doubles_sketch` - - `quantiles_items_sketch` -- REQ (Relative Error Quantiles) - - `req_ints_sketch` - - `req_floats_sketch` - - `req_items_sketch` -- Frequent Items - - `frequent_strings_sketch` - - `frequent_items_sketch` - - Error types are `frequent_items_error_type.{NO_FALSE_NEGATIVES | NO_FALSE_POSITIVES}` -- Theta - - `update_theta_sketch` - - `compact_theta_sketch` (cannot be instantiated directly) - - `theta_union` - - `theta_intersection` - - `theta_a_not_b` - - `theta_jaccard_similarity` -- Tuple - - `update_tuple_sketch` - - `compact_tuple_sketch` (cannot be instantiated directly) - - `tuple_union` - - `tuple_intersection` - - `tuple_a_not_b` - - `tuple_jaccard_similarity` -- HLL - - `hll_sketch` - - `hll_union` - - Target HLL types are `tgt_hll_type.{HLL_4 | HLL_6 | HLL_8}` -- CPC - - `cpc_sketch` - - `cpc_union` -- VarOpt Sampling - - `var_opt_sketch` - - `var_opt_union` -- EBPPS Sampling (Exactly proportional to weight) - - `ebpps_sketch` -- Vector of KLL - - `vector_of_kll_ints_sketches` - - `vector_of_kll_floats_sketches` -- Kolmogorov-Smirnov Test - - `ks_test` applied to a pair of matched-type Absolute Error quantiles sketches -- Kernel Density - - `density_sketch` -- Count-min sketch - - `count_min_sketch` -- t-digest - - tdigest_float - - tdigest_double - -## Known Differences from C++ - -The Python API largely mirrors the C++ API, with a few minor exceptions: The primary known differences are that Python on modern platforms does not support unsigned integer values or numeric values with fewer than 64 bits. As a result, you may not be able to produce identical sketches from within Python as you can with Java and C++. Loading those sketches after they have been serialized from another language will work as expected. - -The Vector of KLL object is currently exclusive to python, and holds an array of independent KLL sketches. This is useful for creating a set of KLL sketches over a vector and has been designed to allow input as either a vector or a matrix of multiple vectors. - -We have also removed reliance on a builder class for theta sketches as Python allows named arguments to the constructor, not strictly positional arguments. - -## Developer Instructions - -The only developer-specific instructions relate to running unit tests. - -### Unit tests - -The Python unit tests are run via `tox`, with no arguments, from the project root directory. Tox creates a temporary virtual environment in which to build and run the unit tests. In the event you are missing the necessary package, tox may be installed with `python3 -m pip install --upgrade tox`. - -## License - -The Apache DataSketches Library is distributed under the Apache 2.0 License. - -There may be precompiled binaries provided as a convenience and distributed through PyPI via [https://pypi.org/project/datasketches/] contain compiled code from [nanobind](https://github.com/wjakob/nanobind), which is distributed under a BSD license. diff --git a/datasketches/KernelFunction.py b/datasketches/KernelFunction.py deleted file mode 100644 index b78c0b3d..00000000 --- a/datasketches/KernelFunction.py +++ /dev/null @@ -1,39 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -import numpy as np - -from _datasketches import KernelFunction - -# This file provides an example Python Kernel Function implementation. -# -# Each implementation must extend the KernelFunction class -# and define the __call__ method - -class GaussianKernel(KernelFunction): - '''Implements a basic Gaussian kernel - - :param bandwidth: The kernel bandwidth, default 1.0 - :type bandwidth: float - ''' - def __init__(self, bandwidth: float=1.0): - KernelFunction.__init__(self) - self._bw = bandwidth - self._scale = -0.5 * (bandwidth ** -2) - - def __call__(self, a: np.ndarray, b: np.ndarray) -> float: - return np.exp(self._scale * np.linalg.norm(a - b)**2) diff --git a/datasketches/PySerDe.py b/datasketches/PySerDe.py deleted file mode 100644 index fcaddfeb..00000000 --- a/datasketches/PySerDe.py +++ /dev/null @@ -1,110 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -from _datasketches import PyObjectSerDe - -import struct - -# This file provides several Python SerDe implementation examples. -# -# Each implementation must extend the PyObjectSerDe class and define -# three methods: -# * get_size(item) returns an int of the number of bytes needed to -# serialize the given item -# * to_bytes(item) returns a bytes object representing a serialized -# version of the given item -# * from_bytes(data, offset) takes a bytes object (data) and an offset -# indicating where in the data array to start reading. The method -# returns a tuple with the newly reconstructed object and the -# total number of bytes beyond the offset read from the input data. - -class PyStringsSerDe(PyObjectSerDe): - '''Implements a simple string-encoding scheme where a string is - written as ` `, with no null termination. - This format allows pre-allocating each string, at the cost of - additional storage. Using this format, the serialized string consumes - ``4 + len(item)`` bytes.''' - def get_size(self, item): - return int(4 + len(item)) - - def to_bytes(self, item: str): - b = bytearray() - b.extend(len(item).to_bytes(4, 'little')) - b.extend(map(ord,item)) - return bytes(b) - - def from_bytes(self, data: bytes, offset: int): - num_chars = int.from_bytes(data[offset:offset+3], 'little') - if (num_chars < 0 or num_chars > offset + len(data)): - raise IndexError(f'num_chars read must be non-negative and not larger than the buffer. Found {num_chars}') - str = data[offset+4:offset+4+num_chars].decode() - return (str, 4+num_chars) - -class PyIntsSerDe(PyObjectSerDe): - '''Implements an integer encoding scheme where each integer is written - as a 32-bit (4 byte) little-endian value.''' - def get_size(self, item): - return int(4) - - def to_bytes(self, item): - return struct.pack(' int: - return int(0) - - def update_summary(self, summary: int, update: int) -> int: - summary += update - return summary - - def __call__(self, summary: int, update: int) -> int: - summary += update - return summary - - -class MaxIntPolicy(TuplePolicy): - '''Implements a MAX rule, where the largest integer value is always kept.''' - - def __init__(self): - TuplePolicy.__init__(self) - - def create_summary(self) -> int: - return int(-sys.maxsize-1) - - def update_summary(self, summary: int, update: int) -> int: - return max(summary, update) - - def __call__(self, summary: int, update: int) -> int: - return max(summary, update) - - -class MinIntPolicy(TuplePolicy): - '''Implements a MIN rule, where the smallest integer value is always kept.''' - - def __init__(self): - TuplePolicy.__init__(self) - - def create_summary(self) -> int: - return int(sys.maxsize) - - def update_summary(self, summary: int, update: int) -> int: - return min(summary, update) - - def __call__(self, summary: int, update: int) -> int: - return min(summary, update) diff --git a/datasketches/__init__.py b/datasketches/__init__.py deleted file mode 100644 index 63a44374..00000000 --- a/datasketches/__init__.py +++ /dev/null @@ -1,30 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -"""The Apache DataSketches Library for Python - -Provided under the Apache License, Version 2.0 - -""" - -name = 'datasketches' - -from _datasketches import * - -from .PySerDe import * -from .TuplePolicy import * -from .KernelFunction import * diff --git a/docs/.nojekyll b/docs/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/docs/5.0.0/.buildinfo b/docs/5.0.0/.buildinfo new file mode 100644 index 00000000..6a08c6b8 --- /dev/null +++ b/docs/5.0.0/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. +config: c2b4fc476624577343da93a20886cb56 +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/docs/source/distinct_counting/cpc.rst b/docs/5.0.0/_sources/distinct_counting/cpc.rst.txt similarity index 100% rename from docs/source/distinct_counting/cpc.rst rename to docs/5.0.0/_sources/distinct_counting/cpc.rst.txt diff --git a/docs/source/distinct_counting/hyper_log_log.rst b/docs/5.0.0/_sources/distinct_counting/hyper_log_log.rst.txt similarity index 100% rename from docs/source/distinct_counting/hyper_log_log.rst rename to docs/5.0.0/_sources/distinct_counting/hyper_log_log.rst.txt diff --git a/docs/source/distinct_counting/index.rst b/docs/5.0.0/_sources/distinct_counting/index.rst.txt similarity index 100% rename from docs/source/distinct_counting/index.rst rename to docs/5.0.0/_sources/distinct_counting/index.rst.txt diff --git a/docs/source/distinct_counting/theta.rst b/docs/5.0.0/_sources/distinct_counting/theta.rst.txt similarity index 100% rename from docs/source/distinct_counting/theta.rst rename to docs/5.0.0/_sources/distinct_counting/theta.rst.txt diff --git a/docs/source/distinct_counting/tuple.rst b/docs/5.0.0/_sources/distinct_counting/tuple.rst.txt similarity index 100% rename from docs/source/distinct_counting/tuple.rst rename to docs/5.0.0/_sources/distinct_counting/tuple.rst.txt diff --git a/docs/source/frequency/count_min_sketch.rst b/docs/5.0.0/_sources/frequency/count_min_sketch.rst.txt similarity index 100% rename from docs/source/frequency/count_min_sketch.rst rename to docs/5.0.0/_sources/frequency/count_min_sketch.rst.txt diff --git a/docs/source/frequency/frequent_items.rst b/docs/5.0.0/_sources/frequency/frequent_items.rst.txt similarity index 100% rename from docs/source/frequency/frequent_items.rst rename to docs/5.0.0/_sources/frequency/frequent_items.rst.txt diff --git a/docs/source/frequency/index.rst b/docs/5.0.0/_sources/frequency/index.rst.txt similarity index 100% rename from docs/source/frequency/index.rst rename to docs/5.0.0/_sources/frequency/index.rst.txt diff --git a/docs/source/helper/index.rst b/docs/5.0.0/_sources/helper/index.rst.txt similarity index 100% rename from docs/source/helper/index.rst rename to docs/5.0.0/_sources/helper/index.rst.txt diff --git a/docs/source/helper/jaccard.rst b/docs/5.0.0/_sources/helper/jaccard.rst.txt similarity index 100% rename from docs/source/helper/jaccard.rst rename to docs/5.0.0/_sources/helper/jaccard.rst.txt diff --git a/docs/source/helper/kernel.rst b/docs/5.0.0/_sources/helper/kernel.rst.txt similarity index 100% rename from docs/source/helper/kernel.rst rename to docs/5.0.0/_sources/helper/kernel.rst.txt diff --git a/docs/source/helper/ks_test.rst b/docs/5.0.0/_sources/helper/ks_test.rst.txt similarity index 100% rename from docs/source/helper/ks_test.rst rename to docs/5.0.0/_sources/helper/ks_test.rst.txt diff --git a/docs/source/helper/serde.rst b/docs/5.0.0/_sources/helper/serde.rst.txt similarity index 100% rename from docs/source/helper/serde.rst rename to docs/5.0.0/_sources/helper/serde.rst.txt diff --git a/docs/source/helper/tuple_policy.rst b/docs/5.0.0/_sources/helper/tuple_policy.rst.txt similarity index 100% rename from docs/source/helper/tuple_policy.rst rename to docs/5.0.0/_sources/helper/tuple_policy.rst.txt diff --git a/docs/source/index.rst b/docs/5.0.0/_sources/index.rst.txt similarity index 100% rename from docs/source/index.rst rename to docs/5.0.0/_sources/index.rst.txt diff --git a/docs/5.0.0/_sources/quantiles/index.rst.txt b/docs/5.0.0/_sources/quantiles/index.rst.txt new file mode 100644 index 00000000..b1928f67 --- /dev/null +++ b/docs/5.0.0/_sources/quantiles/index.rst.txt @@ -0,0 +1,26 @@ +Quantiles Sketches +================== + +Quantile estimation is useful for understanding the distribution of data values in a stream. The sketches currently +in the library are designed to answer queries about the `rank` of an item in the stream of items. That is, when +applying a global ordering on all the items, what is the portion of items seen so far that are less than (alternatively, +less-than-or-equal-to) the given item. Using straightforward logic, they can also estimate the item at a given rank +in the stream. + +These sketches may be used to compute approximate histograms, Probability Mass Functions (PMFs), or +Cumulative Distribution Functions (CDFs). + +The library provides three types of quantiles sketches, each of which has generic items as well as versions +specific to a given numeric type (e.g. integer or floating point values). All three types provide error +bounds on rank estimation with proven probabilistic error distributions. + + * KLL: Provides uniform rank estimation error over the entire range + * REQ: Provides relative rank error estimates, which decreases approaching either the high or low end values. + * Classic quantiles: Largely deprecated in favor of KLL, also provides uniform rank estimation error. Included largely for backwards compatibility with historic data. + +.. toctree:: + :maxdepth: 1 + + kll + req + quantiles_depr \ No newline at end of file diff --git a/docs/5.0.0/_sources/quantiles/kll.rst.txt b/docs/5.0.0/_sources/quantiles/kll.rst.txt new file mode 100644 index 00000000..0e54b443 --- /dev/null +++ b/docs/5.0.0/_sources/quantiles/kll.rst.txt @@ -0,0 +1,171 @@ +KLL Sketch +---------- + +.. currentmodule:: datasketches + +Implementation of a very compact quantiles sketch with lazy compaction scheme +and nearly optimal accuracy per retained item. +See `Optimal Quantile Approximation in Streams`. + +This is a stochastic streaming sketch that enables near real-time analysis of the +approximate distribution of items from a very large stream in a single pass, requiring only +that the items are comparable. +The analysis is obtained using `get_quantile()` function or the +inverse functions `get_rank()`, `get_pmf()` (Probability Mass Function), and `get_cdf()` +(Cumulative Distribution Function). + +As of May 2020, this implementation produces serialized sketches which are binary-compatible +with the equivalent Java implementation only when template parameter `T = float` +(32-bit single precision values). + +Given an input stream of `N` items, the `natural rank` of any specific +item is defined as its index `(1 to N)` in inclusive mode +or `(0 to N-1)` in exclusive mode +in the hypothetical sorted stream of all `N` input items. + +The `normalized rank` (`rank`) of any specific item is defined as its +`natural rank` divided by `N`. +Thus, the `normalized rank` is between zero and one. +In the documentation for this sketch `natural rank` is never used so any +reference to just `rank` should be interpreted to mean `normalized rank`. + +This sketch is configured with a parameter `k`, which affects the size of the sketch +and its estimation error. + +The estimation error is commonly called `epsilon` (or `eps`) and is a fraction +between zero and one. Larger values of `k` result in smaller values of `epsilon`. +Epsilon is always with respect to the rank and cannot be applied to the +corresponding items. + +The relationship between the `normalized rank` and the corresponding items can be viewed +as a two-dimensional monotonic plot with the `normalized rank` on one axis and the +corresponding items on the other axis. If the y-axis is specified as the item-axis and +the x-axis as the `normalized rank`, then `y = get_quantile(x)` is a monotonically +increasing function. + +The function `get_quantile(rank)` translates ranks into +corresponding quantiles. The functions `get_rank(item)`, +`get_cdf(...)` (Cumulative Distribution Function), and `get_pmf(...)` +(Probability Mass Function) perform the opposite operation and translate items into ranks. + +The `get_pmf(...)` function has about 13 to 47% worse rank error (depending +on `k`) than the other queries because the mass of each "bin" of the PMF has +"double-sided" error from the upper and lower edges of the bin as a result of a subtraction, +as the errors from the two edges can sometimes add. + +The default `k` of 200 yields a "single-sided" `epsilon` of about 1.33% and a +"double-sided" (PMF) `epsilon` of about 1.65%. + +A `get_quantile(rank)` query has the following guarantees: +- Let `q = get_quantile(r)` where `r` is the rank between zero and one. +- The quantile `q` will be an item from the input stream. +- Let `true_rank` be the true rank of `q` derived from the hypothetical sorted +stream of all `N` items. +- Let `eps = get_normalized_rank_error(false)`. +- Then `r - eps ≤ true_rank ≤ r + eps` with a confidence of 99%. Note that the +error is on the rank, not the quantile. + +A `get_rank(item)` query has the following guarantees: +- Let `r = get_rank(i)` where `i` is an item between the min and max items of +the input stream. +- Let `true_rank` be the true rank of `i` derived from the hypothetical sorted +stream of all `N` items. +- Let `eps = get_normalized_rank_error(false)`. +- Then `r - eps ≤ true_rank ≤ r + eps` with a confidence of 99%. + +A `get_pmf()` query has the following guarantees: +- Let `{r1, r2, ..., r(m+1)} = get_pmf(s1, s2, ..., sm)` where `s1, s2` are +split points (items from the input domain) between the min and max items of +the input stream. +- Let `mass_i = estimated mass between s_i and s_i+1`. +- Let `true_mass` be the true mass between the items of `s_i`, +`s_i+1` derived from the hypothetical sorted stream of all `N` items. +- Let `eps = get_normalized_rank_error(true)`. +- then `mass - eps ≤ true_mass ≤ mass + eps` with a confidence of 99%. +- `r(m+1)` includes the mass of all points larger than `s_m`. + +A `get_cdf(...)` query has the following guarantees; +- Let `{r1, r2, ..., r(m+1)} = get_cdf(s1, s2, ..., sm)` where `s1, s2, ...` are +split points (items from the input domain) between the min and max items of +the input stream. +- Let `mass_i = r_(i+1) - r_i`. +- Let `true_mass` be the true mass between the true ranks of `s_i`, +`s_i+1` derived from the hypothetical sorted stream of all `N` items. +- Let `eps = get_normalized_rank_error(true)`. +- then `mass - eps ≤ true_mass ≤ mass + eps` with a confidence of 99%. +- `1 - r(m+1)` includes the mass of all points larger than `s_m`. + +From the above, it might seem like we could make some estimates to bound the +`item` returned from a call to `get_quantile()`. The sketch, however, does not +let us derive error bounds or confidences around items. Because errors are independent, we +can approximately bracket a value as shown below, but there are no error estimates available. +Additionally, the interval may be quite large for certain distributions. +- Let `q = get_quantile(r)`, the estimated quantile of rank `r`. +- Let `eps = get_normalized_rank_error(false)`. +- Let `q_lo = estimated quantile of rank (r - eps)`. +- Let `q_hi = estimated quantile of rank (r + eps)`. +- Then `q_lo ≤ q ≤ q_hi`, with 99% confidence. + +.. note:: + For the :class:`kll_items_sketch`, objects must be comparable with ``__lt__``. + +.. note:: + Serializing and deserializing a :class:`kll_items_sketch` requires the use of a :class:`PyObjectSerDe`. + + +.. autoclass:: kll_ints_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_normalized_rank_error + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_normalized_rank_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: kll_floats_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_normalized_rank_error + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_normalized_rank_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: kll_doubles_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_normalized_rank_error + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_normalized_rank_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: kll_items_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_normalized_rank_error + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_normalized_rank_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + diff --git a/docs/source/quantiles/quantiles_depr.rst b/docs/5.0.0/_sources/quantiles/quantiles_depr.rst.txt similarity index 100% rename from docs/source/quantiles/quantiles_depr.rst rename to docs/5.0.0/_sources/quantiles/quantiles_depr.rst.txt diff --git a/docs/source/quantiles/req.rst b/docs/5.0.0/_sources/quantiles/req.rst.txt similarity index 100% rename from docs/source/quantiles/req.rst rename to docs/5.0.0/_sources/quantiles/req.rst.txt diff --git a/docs/source/sampling/ebpps.rst b/docs/5.0.0/_sources/sampling/ebpps.rst.txt similarity index 100% rename from docs/source/sampling/ebpps.rst rename to docs/5.0.0/_sources/sampling/ebpps.rst.txt diff --git a/docs/source/sampling/index.rst b/docs/5.0.0/_sources/sampling/index.rst.txt similarity index 100% rename from docs/source/sampling/index.rst rename to docs/5.0.0/_sources/sampling/index.rst.txt diff --git a/docs/source/sampling/varopt.rst b/docs/5.0.0/_sources/sampling/varopt.rst.txt similarity index 100% rename from docs/source/sampling/varopt.rst rename to docs/5.0.0/_sources/sampling/varopt.rst.txt diff --git a/docs/source/vector/density_sketch.rst b/docs/5.0.0/_sources/vector/density_sketch.rst.txt similarity index 100% rename from docs/source/vector/density_sketch.rst rename to docs/5.0.0/_sources/vector/density_sketch.rst.txt diff --git a/docs/source/vector/index.rst b/docs/5.0.0/_sources/vector/index.rst.txt similarity index 100% rename from docs/source/vector/index.rst rename to docs/5.0.0/_sources/vector/index.rst.txt diff --git a/docs/5.0.0/_static/_sphinx_javascript_frameworks_compat.js b/docs/5.0.0/_static/_sphinx_javascript_frameworks_compat.js new file mode 100644 index 00000000..81415803 --- /dev/null +++ b/docs/5.0.0/_static/_sphinx_javascript_frameworks_compat.js @@ -0,0 +1,123 @@ +/* Compatability shim for jQuery and underscores.js. + * + * Copyright Sphinx contributors + * Released under the two clause BSD licence + */ + +/** + * small helper function to urldecode strings + * + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL + */ +jQuery.urldecode = function(x) { + if (!x) { + return x + } + return decodeURIComponent(x.replace(/\+/g, ' ')); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s === 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node, addItems) { + if (node.nodeType === 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && + !jQuery(node.parentNode).hasClass(className) && + !jQuery(node.parentNode).hasClass("nohighlight")) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.className = className; + } + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + if (isInSVG) { + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + var bbox = node.parentElement.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": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} diff --git a/docs/5.0.0/_static/basic.css b/docs/5.0.0/_static/basic.css new file mode 100644 index 00000000..f316efcb --- /dev/null +++ b/docs/5.0.0/_static/basic.css @@ -0,0 +1,925 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- 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: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +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/docs/5.0.0/_static/css/badge_only.css b/docs/5.0.0/_static/css/badge_only.css new file mode 100644 index 00000000..c718cee4 --- /dev/null +++ b/docs/5.0.0/_static/css/badge_only.css @@ -0,0 +1 @@ +.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}} \ No newline at end of file diff --git a/docs/5.0.0/_static/css/fonts/Roboto-Slab-Bold.woff b/docs/5.0.0/_static/css/fonts/Roboto-Slab-Bold.woff new file mode 100644 index 00000000..6cb60000 Binary files /dev/null and b/docs/5.0.0/_static/css/fonts/Roboto-Slab-Bold.woff differ diff --git a/docs/5.0.0/_static/css/fonts/Roboto-Slab-Bold.woff2 b/docs/5.0.0/_static/css/fonts/Roboto-Slab-Bold.woff2 new file mode 100644 index 00000000..7059e231 Binary files /dev/null and b/docs/5.0.0/_static/css/fonts/Roboto-Slab-Bold.woff2 differ diff --git a/docs/5.0.0/_static/css/fonts/Roboto-Slab-Regular.woff b/docs/5.0.0/_static/css/fonts/Roboto-Slab-Regular.woff new file mode 100644 index 00000000..f815f63f Binary files /dev/null and b/docs/5.0.0/_static/css/fonts/Roboto-Slab-Regular.woff differ diff --git a/docs/5.0.0/_static/css/fonts/Roboto-Slab-Regular.woff2 b/docs/5.0.0/_static/css/fonts/Roboto-Slab-Regular.woff2 new file mode 100644 index 00000000..f2c76e5b Binary files /dev/null and b/docs/5.0.0/_static/css/fonts/Roboto-Slab-Regular.woff2 differ diff --git a/docs/5.0.0/_static/css/fonts/fontawesome-webfont.eot b/docs/5.0.0/_static/css/fonts/fontawesome-webfont.eot new file mode 100644 index 00000000..e9f60ca9 Binary files /dev/null and b/docs/5.0.0/_static/css/fonts/fontawesome-webfont.eot differ diff --git a/docs/5.0.0/_static/css/fonts/fontawesome-webfont.svg b/docs/5.0.0/_static/css/fonts/fontawesome-webfont.svg new file mode 100644 index 00000000..855c845e --- /dev/null +++ b/docs/5.0.0/_static/css/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/5.0.0/_static/css/fonts/fontawesome-webfont.ttf b/docs/5.0.0/_static/css/fonts/fontawesome-webfont.ttf new file mode 100644 index 00000000..35acda2f Binary files /dev/null and b/docs/5.0.0/_static/css/fonts/fontawesome-webfont.ttf differ diff --git a/docs/5.0.0/_static/css/fonts/fontawesome-webfont.woff b/docs/5.0.0/_static/css/fonts/fontawesome-webfont.woff new file mode 100644 index 00000000..400014a4 Binary files /dev/null and b/docs/5.0.0/_static/css/fonts/fontawesome-webfont.woff differ diff --git a/docs/5.0.0/_static/css/fonts/fontawesome-webfont.woff2 b/docs/5.0.0/_static/css/fonts/fontawesome-webfont.woff2 new file mode 100644 index 00000000..4d13fc60 Binary files /dev/null and b/docs/5.0.0/_static/css/fonts/fontawesome-webfont.woff2 differ diff --git a/docs/5.0.0/_static/css/fonts/lato-bold-italic.woff b/docs/5.0.0/_static/css/fonts/lato-bold-italic.woff new file mode 100644 index 00000000..88ad05b9 Binary files /dev/null and b/docs/5.0.0/_static/css/fonts/lato-bold-italic.woff differ diff --git a/docs/5.0.0/_static/css/fonts/lato-bold-italic.woff2 b/docs/5.0.0/_static/css/fonts/lato-bold-italic.woff2 new file mode 100644 index 00000000..c4e3d804 Binary files /dev/null and b/docs/5.0.0/_static/css/fonts/lato-bold-italic.woff2 differ diff --git a/docs/5.0.0/_static/css/fonts/lato-bold.woff b/docs/5.0.0/_static/css/fonts/lato-bold.woff new file mode 100644 index 00000000..c6dff51f Binary files /dev/null and b/docs/5.0.0/_static/css/fonts/lato-bold.woff differ diff --git a/docs/5.0.0/_static/css/fonts/lato-bold.woff2 b/docs/5.0.0/_static/css/fonts/lato-bold.woff2 new file mode 100644 index 00000000..bb195043 Binary files /dev/null and b/docs/5.0.0/_static/css/fonts/lato-bold.woff2 differ diff --git a/docs/5.0.0/_static/css/fonts/lato-normal-italic.woff b/docs/5.0.0/_static/css/fonts/lato-normal-italic.woff new file mode 100644 index 00000000..76114bc0 Binary files /dev/null and b/docs/5.0.0/_static/css/fonts/lato-normal-italic.woff differ diff --git a/docs/5.0.0/_static/css/fonts/lato-normal-italic.woff2 b/docs/5.0.0/_static/css/fonts/lato-normal-italic.woff2 new file mode 100644 index 00000000..3404f37e Binary files /dev/null and b/docs/5.0.0/_static/css/fonts/lato-normal-italic.woff2 differ diff --git a/docs/5.0.0/_static/css/fonts/lato-normal.woff b/docs/5.0.0/_static/css/fonts/lato-normal.woff new file mode 100644 index 00000000..ae1307ff Binary files /dev/null and b/docs/5.0.0/_static/css/fonts/lato-normal.woff differ diff --git a/docs/5.0.0/_static/css/fonts/lato-normal.woff2 b/docs/5.0.0/_static/css/fonts/lato-normal.woff2 new file mode 100644 index 00000000..3bf98433 Binary files /dev/null and b/docs/5.0.0/_static/css/fonts/lato-normal.woff2 differ diff --git a/docs/5.0.0/_static/css/theme.css b/docs/5.0.0/_static/css/theme.css new file mode 100644 index 00000000..19a446a0 --- /dev/null +++ b/docs/5.0.0/_static/css/theme.css @@ -0,0 +1,4 @@ +html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden],audio:not([controls]){display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;text-decoration:none}ins,mark{color:#000}mark{background:#ff0;font-style:italic;font-weight:700}.rst-content code,.rst-content tt,code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:after,q:before{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,ol,ul{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure,form{margin:0}label{cursor:pointer}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{body,html,section{background:none!important}*{box-shadow:none!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}.rst-content .toctree-wrapper>p.caption,h2,h3,p{orphans:3;widows:3}.rst-content .toctree-wrapper>p.caption,h2,h3{page-break-after:avoid}}.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .eqno .headerlink:before,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .eqno .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a button.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-left.toctree-expand,.wy-menu-vertical li button.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .eqno .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a button.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-right.toctree-expand,.wy-menu-vertical li button.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .eqno .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a button.pull-left.toctree-expand,.wy-menu-vertical li.on a button.pull-left.toctree-expand,.wy-menu-vertical li button.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .eqno .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a button.pull-right.toctree-expand,.wy-menu-vertical li.on a button.pull-right.toctree-expand,.wy-menu-vertical li button.pull-right.toctree-expand{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li button.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content .eqno a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content p a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li a button.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content .eqno .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content p .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li button.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content .eqno .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a button.toctree-expand,.btn .wy-menu-vertical li.on a button.toctree-expand,.btn .wy-menu-vertical li button.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content .eqno .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a button.toctree-expand,.nav .wy-menu-vertical li.on a button.toctree-expand,.nav .wy-menu-vertical li button.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .eqno .btn .headerlink,.rst-content .eqno .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p .btn .headerlink,.rst-content p .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn button.toctree-expand,.wy-menu-vertical li.current>a .btn button.toctree-expand,.wy-menu-vertical li.current>a .nav button.toctree-expand,.wy-menu-vertical li .nav button.toctree-expand,.wy-menu-vertical li.on a .btn button.toctree-expand,.wy-menu-vertical li.on a .nav button.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .eqno .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li button.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .eqno .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li button.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .eqno .btn .fa-large.headerlink,.rst-content .eqno .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p .btn .fa-large.headerlink,.rst-content p .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn button.fa-large.toctree-expand,.wy-menu-vertical li .nav button.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .eqno .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li button.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .eqno .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li button.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .eqno .btn .fa-spin.headerlink,.rst-content .eqno .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p .btn .fa-spin.headerlink,.rst-content p .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn button.fa-spin.toctree-expand,.wy-menu-vertical li .nav button.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content .eqno .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li button.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content .eqno .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li button.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content .eqno .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li button.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content .eqno .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini button.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.rst-content section ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.rst-content section ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.rst-content section ul li p:last-child,.rst-content section ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.rst-content section ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.rst-content section ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.rst-content section ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content .section ol.arabic,.rst-content .toctree-wrapper ol,.rst-content .toctree-wrapper ol.arabic,.rst-content section ol,.rst-content section ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol.arabic li,.rst-content .section ol li,.rst-content .toctree-wrapper ol.arabic li,.rst-content .toctree-wrapper ol li,.rst-content section ol.arabic li,.rst-content section ol li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol.arabic li ul,.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content .toctree-wrapper ol.arabic li ul,.rst-content .toctree-wrapper ol li p:last-child,.rst-content .toctree-wrapper ol li ul,.rst-content section ol.arabic li ul,.rst-content section ol li p:last-child,.rst-content section ol li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol.arabic li ul li,.rst-content .section ol li ul li,.rst-content .toctree-wrapper ol.arabic li ul li,.rst-content .toctree-wrapper ol li ul li,.rst-content section ol.arabic li ul li,.rst-content section ol li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs>li{display:inline-block;padding-top:5px}.wy-breadcrumbs>li.wy-breadcrumbs-aside{float:right}.rst-content .wy-breadcrumbs>li code,.rst-content .wy-breadcrumbs>li tt,.wy-breadcrumbs>li .rst-content tt,.wy-breadcrumbs>li code{all:inherit;color:inherit}.breadcrumb-item:before{content:"/";color:#bbb;font-size:13px;padding:0 6px 0 3px}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li button.toctree-expand{display:block;float:left;margin-left:-1.2em;line-height:18px;color:#4d4d4d;border:none;background:none;padding:0}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover button.toctree-expand,.wy-menu-vertical li.on a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand{display:block;line-height:18px;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{padding:.4045em 1.618em .4045em 4.045em}.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{padding:.4045em 1.618em .4045em 5.663em}.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a{padding:.4045em 1.618em .4045em 7.281em}.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a{padding:.4045em 1.618em .4045em 8.899em}.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a{padding:.4045em 1.618em .4045em 10.517em}.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a{padding:.4045em 1.618em .4045em 12.135em}.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a{padding:.4045em 1.618em .4045em 13.753em}.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a{padding:.4045em 1.618em .4045em 15.371em}.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 1.618em .4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 button.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 button.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover button.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active button.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em;max-width:100%}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search>a:hover{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.version{margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .eqno .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content .eqno .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}.rst-content .toctree-wrapper>p.caption,.rst-content h1,.rst-content h2,.rst-content h3,.rst-content h4,.rst-content h5,.rst-content h6{margin-bottom:24px}.rst-content img{max-width:100%;height:auto}.rst-content div.figure,.rst-content figure{margin-bottom:24px}.rst-content div.figure .caption-text,.rst-content figure .caption-text{font-style:italic}.rst-content div.figure p:last-child.caption,.rst-content figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center,.rst-content figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img,.rst-content section>a>img,.rst-content section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp,.rst-content div.highlight span.linenos{user-select:none;pointer-events:none}.rst-content div.highlight span.linenos{display:inline-block;padding-left:0;padding-right:12px;margin-right:12px;border-right:1px solid #e6e9ea}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li,.rst-content .toctree-wrapper ol.loweralpha,.rst-content .toctree-wrapper ol.loweralpha>li,.rst-content section ol.loweralpha,.rst-content section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li,.rst-content .toctree-wrapper ol.upperalpha,.rst-content .toctree-wrapper ol.upperalpha>li,.rst-content section ol.upperalpha,.rst-content section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*,.rst-content .toctree-wrapper ol li>*,.rst-content .toctree-wrapper ul li>*,.rst-content section ol li>*,.rst-content section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child,.rst-content .toctree-wrapper ol li>:first-child,.rst-content .toctree-wrapper ul li>:first-child,.rst-content section ol li>:first-child,.rst-content section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child,.rst-content .toctree-wrapper ol li>p,.rst-content .toctree-wrapper ol li>p:last-child,.rst-content .toctree-wrapper ul li>p,.rst-content .toctree-wrapper ul li>p:last-child,.rst-content section ol li>p,.rst-content section ol li>p:last-child,.rst-content section ul li>p,.rst-content section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child,.rst-content .toctree-wrapper ol li>p:only-child,.rst-content .toctree-wrapper ol li>p:only-child:last-child,.rst-content .toctree-wrapper ul li>p:only-child,.rst-content .toctree-wrapper ul li>p:only-child:last-child,.rst-content section ol li>p:only-child,.rst-content section ol li>p:only-child:last-child,.rst-content section ul li>p:only-child,.rst-content section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul,.rst-content .toctree-wrapper ol li>ol,.rst-content .toctree-wrapper ol li>ul,.rst-content .toctree-wrapper ul li>ol,.rst-content .toctree-wrapper ul li>ul,.rst-content section ol li>ol,.rst-content section ol li>ul,.rst-content section ul li>ol,.rst-content section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul,.rst-content .toctree-wrapper ol.simple li>*,.rst-content .toctree-wrapper ol.simple li ol,.rst-content .toctree-wrapper ol.simple li ul,.rst-content .toctree-wrapper ul.simple li>*,.rst-content .toctree-wrapper ul.simple li ol,.rst-content .toctree-wrapper ul.simple li ul,.rst-content section ol.simple li>*,.rst-content section ol.simple li ol,.rst-content section ol.simple li ul,.rst-content section ul.simple li>*,.rst-content section ul.simple li ol,.rst-content section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink{opacity:0;font-size:14px;font-family:FontAwesome;margin-left:.5em}.rst-content .code-block-caption .headerlink:focus,.rst-content .code-block-caption:hover .headerlink,.rst-content .eqno .headerlink:focus,.rst-content .eqno:hover .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink:focus,.rst-content .toctree-wrapper>p.caption:hover .headerlink,.rst-content dl dt .headerlink:focus,.rst-content dl dt:hover .headerlink,.rst-content h1 .headerlink:focus,.rst-content h1:hover .headerlink,.rst-content h2 .headerlink:focus,.rst-content h2:hover .headerlink,.rst-content h3 .headerlink:focus,.rst-content h3:hover .headerlink,.rst-content h4 .headerlink:focus,.rst-content h4:hover .headerlink,.rst-content h5 .headerlink:focus,.rst-content h5:hover .headerlink,.rst-content h6 .headerlink:focus,.rst-content h6:hover .headerlink,.rst-content p.caption .headerlink:focus,.rst-content p.caption:hover .headerlink,.rst-content p .headerlink:focus,.rst-content p:hover .headerlink,.rst-content table>caption .headerlink:focus,.rst-content table>caption:hover .headerlink{opacity:1}.rst-content p a{overflow-wrap:anywhere}.rst-content .wy-table td p,.rst-content .wy-table td ul,.rst-content .wy-table th p,.rst-content .wy-table th ul,.rst-content table.docutils td p,.rst-content table.docutils td ul,.rst-content table.docutils th p,.rst-content table.docutils th ul,.rst-content table.field-list td p,.rst-content table.field-list td ul,.rst-content table.field-list th p,.rst-content table.field-list th ul{font-size:inherit}.rst-content .btn:focus{outline:2px solid}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .citation-reference>span.fn-bracket,.rst-content .footnote-reference>span.fn-bracket{display:none}.rst-content .hlist{width:100%}.rst-content dl dt span.classifier:before{content:" : "}.rst-content dl dt span.classifier-delimiter{display:none!important}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:auto minmax(80%,95%)}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{display:inline-grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{display:grid;grid-template-columns:auto auto minmax(.65rem,auto) minmax(40%,95%)}html.writer-html5 .rst-content aside.citation>span.label,html.writer-html5 .rst-content aside.footnote>span.label,html.writer-html5 .rst-content div.citation>span.label{grid-column-start:1;grid-column-end:2}html.writer-html5 .rst-content aside.citation>span.backrefs,html.writer-html5 .rst-content aside.footnote>span.backrefs,html.writer-html5 .rst-content div.citation>span.backrefs{grid-column-start:2;grid-column-end:3;grid-row-start:1;grid-row-end:3}html.writer-html5 .rst-content aside.citation>p,html.writer-html5 .rst-content aside.footnote>p,html.writer-html5 .rst-content div.citation>p{grid-column-start:4;grid-column-end:5}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{margin-bottom:24px}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.citation>dt>span.brackets:before,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.citation>dt>span.brackets:after,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a{word-break:keep-all}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a:not(:first-child):before,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.citation>dd p,html.writer-html5 .rst-content dl.footnote>dd p{font-size:.9rem}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{padding-left:1rem;padding-right:1rem;font-size:.9rem;line-height:1.2rem}html.writer-html5 .rst-content aside.citation p,html.writer-html5 .rst-content aside.footnote p,html.writer-html5 .rst-content div.citation p{font-size:.9rem;line-height:1.2rem;margin-bottom:12px}html.writer-html5 .rst-content aside.citation span.backrefs,html.writer-html5 .rst-content aside.footnote span.backrefs,html.writer-html5 .rst-content div.citation span.backrefs{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content aside.citation span.backrefs>a,html.writer-html5 .rst-content aside.footnote span.backrefs>a,html.writer-html5 .rst-content div.citation span.backrefs>a{word-break:keep-all}html.writer-html5 .rst-content aside.citation span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content aside.footnote span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content div.citation span.backrefs>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content aside.citation span.label,html.writer-html5 .rst-content aside.footnote span.label,html.writer-html5 .rst-content div.citation span.label{line-height:1.2rem}html.writer-html5 .rst-content aside.citation-list,html.writer-html5 .rst-content aside.footnote-list,html.writer-html5 .rst-content div.citation-list{margin-bottom:24px}html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content aside.footnote-list aside.footnote,html.writer-html5 .rst-content div.citation-list>div.citation,html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content aside.footnote-list aside.footnote code,html.writer-html5 .rst-content aside.footnote-list aside.footnote tt,html.writer-html5 .rst-content aside.footnote code,html.writer-html5 .rst-content aside.footnote tt,html.writer-html5 .rst-content div.citation-list>div.citation code,html.writer-html5 .rst-content div.citation-list>div.citation tt,html.writer-html5 .rst-content dl.citation code,html.writer-html5 .rst-content dl.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c;white-space:normal}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040;overflow-wrap:normal}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}.rst-content dl dd>ol:last-child,.rst-content dl dd>p:last-child,.rst-content dl dd>table:last-child,.rst-content dl dd>ul:last-child{margin-bottom:0}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px;max-width:100%}html.writer-html4 .rst-content dl:not(.docutils) .k,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .k{font-style:italic}html.writer-html4 .rst-content dl:not(.docutils) .descclassname,html.writer-html4 .rst-content dl:not(.docutils) .descname,html.writer-html4 .rst-content dl:not(.docutils) .sig-name,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .sig-name{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#000}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel,.rst-content .menuselection{font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .guilabel,.rst-content .menuselection{border:1px solid #7fbbe3;background:#e7f2fa}.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>.kbd,.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>kbd{color:inherit;font-size:80%;background-color:#fff;border:1px solid #a6a6a6;border-radius:4px;box-shadow:0 2px grey;padding:2.4px 6px;margin:auto 0}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block} \ No newline at end of file diff --git a/docs/5.0.0/_static/doctools.js b/docs/5.0.0/_static/doctools.js new file mode 100644 index 00000000..4d67807d --- /dev/null +++ b/docs/5.0.0/_static/doctools.js @@ -0,0 +1,156 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Base JavaScript utilities for all Sphinx HTML documentation. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"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/docs/5.0.0/_static/documentation_options.js b/docs/5.0.0/_static/documentation_options.js new file mode 100644 index 00000000..e21c068c --- /dev/null +++ b/docs/5.0.0/_static/documentation_options.js @@ -0,0 +1,13 @@ +const DOCUMENTATION_OPTIONS = { + VERSION: '0.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/docs/5.0.0/_static/file.png b/docs/5.0.0/_static/file.png new file mode 100644 index 00000000..a858a410 Binary files /dev/null and b/docs/5.0.0/_static/file.png differ diff --git a/docs/5.0.0/_static/jquery.js b/docs/5.0.0/_static/jquery.js new file mode 100644 index 00000000..c4c6022f --- /dev/null +++ b/docs/5.0.0/_static/jquery.js @@ -0,0 +1,2 @@ +/*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=y.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=y.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),y.elements=c+" "+a,j(b)}function f(a){var b=x[a[v]];return b||(b={},w++,a[v]=w,x[w]=b),b}function g(a,c,d){if(c||(c=b),q)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():u.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||t.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),q)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return y.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(y,b.frag)}function j(a){a||(a=b);var d=f(a);return!y.shivCSS||p||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),q||i(a,d),a}function k(a){for(var b,c=a.getElementsByTagName("*"),e=c.length,f=RegExp("^(?:"+d().join("|")+")$","i"),g=[];e--;)b=c[e],f.test(b.nodeName)&&g.push(b.applyElement(l(b)));return g}function l(a){for(var b,c=a.attributes,d=c.length,e=a.ownerDocument.createElement(A+":"+a.nodeName);d--;)b=c[d],b.specified&&e.setAttribute(b.nodeName,b.nodeValue);return e.style.cssText=a.style.cssText,e}function m(a){for(var b,c=a.split("{"),e=c.length,f=RegExp("(^|[\\s,>+~])("+d().join("|")+")(?=[[\\s,>+~#.:]|$)","gi"),g="$1"+A+"\\:$2";e--;)b=c[e]=c[e].split("}"),b[b.length-1]=b[b.length-1].replace(f,g),c[e]=b.join("}");return c.join("{")}function n(a){for(var b=a.length;b--;)a[b].removeNode()}function o(a){function b(){clearTimeout(g._removeSheetTimer),d&&d.removeNode(!0),d=null}var d,e,g=f(a),h=a.namespaces,i=a.parentWindow;return!B||a.printShived?a:("undefined"==typeof h[A]&&h.add(A),i.attachEvent("onbeforeprint",function(){b();for(var f,g,h,i=a.styleSheets,j=[],l=i.length,n=Array(l);l--;)n[l]=i[l];for(;h=n.pop();)if(!h.disabled&&z.test(h.media)){try{f=h.imports,g=f.length}catch(o){g=0}for(l=0;g>l;l++)n.push(f[l]);try{j.push(h.cssText)}catch(o){}}j=m(j.reverse().join("")),e=k(a),d=c(a,j)}),i.attachEvent("onafterprint",function(){n(e),clearTimeout(g._removeSheetTimer),g._removeSheetTimer=setTimeout(b,500)}),a.printShived=!0,a)}var p,q,r="3.7.3",s=a.html5||{},t=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,u=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,v="_html5shiv",w=0,x={};!function(){try{var a=b.createElement("a");a.innerHTML="",p="hidden"in a,q=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){p=!0,q=!0}}();var y={elements:s.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:r,shivCSS:s.shivCSS!==!1,supportsUnknownElements:q,shivMethods:s.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=y,j(b);var z=/^$|\b(?:all|print)\b/,A="html5shiv",B=!q&&function(){var c=b.documentElement;return!("undefined"==typeof b.namespaces||"undefined"==typeof b.parentWindow||"undefined"==typeof c.applyElement||"undefined"==typeof c.removeNode||"undefined"==typeof a.attachEvent)}();y.type+=" print",y.shivPrint=o,o(b),"object"==typeof module&&module.exports&&(module.exports=y)}("undefined"!=typeof window?window:this,document); \ No newline at end of file diff --git a/docs/5.0.0/_static/js/html5shiv.min.js b/docs/5.0.0/_static/js/html5shiv.min.js new file mode 100644 index 00000000..cd1c674f --- /dev/null +++ b/docs/5.0.0/_static/js/html5shiv.min.js @@ -0,0 +1,4 @@ +/** +* @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed +*/ +!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.3-pre",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b),"object"==typeof module&&module.exports&&(module.exports=t)}("undefined"!=typeof window?window:this,document); \ No newline at end of file diff --git a/docs/5.0.0/_static/js/theme.js b/docs/5.0.0/_static/js/theme.js new file mode 100644 index 00000000..1fddb6ee --- /dev/null +++ b/docs/5.0.0/_static/js/theme.js @@ -0,0 +1 @@ +!function(n){var e={};function t(i){if(e[i])return e[i].exports;var o=e[i]={i:i,l:!1,exports:{}};return n[i].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=n,t.c=e,t.d=function(n,e,i){t.o(n,e)||Object.defineProperty(n,e,{enumerable:!0,get:i})},t.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},t.t=function(n,e){if(1&e&&(n=t(n)),8&e)return n;if(4&e&&"object"==typeof n&&n&&n.__esModule)return n;var i=Object.create(null);if(t.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:n}),2&e&&"string"!=typeof n)for(var o in n)t.d(i,o,function(e){return n[e]}.bind(null,o));return i},t.n=function(n){var e=n&&n.__esModule?function(){return n.default}:function(){return n};return t.d(e,"a",e),e},t.o=function(n,e){return Object.prototype.hasOwnProperty.call(n,e)},t.p="",t(t.s=0)}([function(n,e,t){t(1),n.exports=t(3)},function(n,e,t){(function(){var e="undefined"!=typeof window?window.jQuery:t(2);n.exports.ThemeNav={navBar:null,win:null,winScroll:!1,winResize:!1,linkScroll:!1,winPosition:0,winHeight:null,docHeight:null,isRunning:!1,enable:function(n){var t=this;void 0===n&&(n=!0),t.isRunning||(t.isRunning=!0,e((function(e){t.init(e),t.reset(),t.win.on("hashchange",t.reset),n&&t.win.on("scroll",(function(){t.linkScroll||t.winScroll||(t.winScroll=!0,requestAnimationFrame((function(){t.onScroll()})))})),t.win.on("resize",(function(){t.winResize||(t.winResize=!0,requestAnimationFrame((function(){t.onResize()})))})),t.onResize()})))},enableSticky:function(){this.enable(!0)},init:function(n){n(document);var e=this;this.navBar=n("div.wy-side-scroll:first"),this.win=n(window),n(document).on("click","[data-toggle='wy-nav-top']",(function(){n("[data-toggle='wy-nav-shift']").toggleClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift")})).on("click",".wy-menu-vertical .current ul li a",(function(){var t=n(this);n("[data-toggle='wy-nav-shift']").removeClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift"),e.toggleCurrent(t),e.hashChange()})).on("click","[data-toggle='rst-current-version']",(function(){n("[data-toggle='rst-versions']").toggleClass("shift-up")})),n("table.docutils:not(.field-list,.footnote,.citation)").wrap("
"),n("table.docutils.footnote").wrap("
"),n("table.docutils.citation").wrap("
"),n(".wy-menu-vertical ul").not(".simple").siblings("a").each((function(){var t=n(this);expand=n(''),expand.on("click",(function(n){return e.toggleCurrent(t),n.stopPropagation(),!1})),t.prepend(expand)}))},reset:function(){var n=encodeURI(window.location.hash)||"#";try{var e=$(".wy-menu-vertical"),t=e.find('[href="'+n+'"]');if(0===t.length){var i=$('.document [id="'+n.substring(1)+'"]').closest("div.section");0===(t=e.find('[href="#'+i.attr("id")+'"]')).length&&(t=e.find('[href="#"]'))}if(t.length>0){$(".wy-menu-vertical .current").removeClass("current").attr("aria-expanded","false"),t.addClass("current").attr("aria-expanded","true"),t.closest("li.toctree-l1").parent().addClass("current").attr("aria-expanded","true");for(let n=1;n<=10;n++)t.closest("li.toctree-l"+n).addClass("current").attr("aria-expanded","true");t[0].scrollIntoView()}}catch(n){console.log("Error expanding nav for anchor",n)}},onScroll:function(){this.winScroll=!1;var n=this.win.scrollTop(),e=n+this.winHeight,t=this.navBar.scrollTop()+(n-this.winPosition);n<0||e>this.docHeight||(this.navBar.scrollTop(t),this.winPosition=n)},onResize:function(){this.winResize=!1,this.winHeight=this.win.height(),this.docHeight=$(document).height()},hashChange:function(){this.linkScroll=!0,this.win.one("hashchange",(function(){this.linkScroll=!1}))},toggleCurrent:function(n){var e=n.closest("li");e.siblings("li.current").removeClass("current").attr("aria-expanded","false"),e.siblings().find("li.current").removeClass("current").attr("aria-expanded","false");var t=e.find("> ul li");t.length&&(t.removeClass("current").attr("aria-expanded","false"),e.toggleClass("current").attr("aria-expanded",(function(n,e){return"true"==e?"false":"true"})))}},"undefined"!=typeof window&&(window.SphinxRtdTheme={Navigation:n.exports.ThemeNav,StickyNav:n.exports.ThemeNav}),function(){for(var n=0,e=["ms","moz","webkit","o"],t=0;t0 + 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/docs/5.0.0/_static/minus.png b/docs/5.0.0/_static/minus.png new file mode 100644 index 00000000..d96755fd Binary files /dev/null and b/docs/5.0.0/_static/minus.png differ diff --git a/docs/5.0.0/_static/plus.png b/docs/5.0.0/_static/plus.png new file mode 100644 index 00000000..7107cec9 Binary files /dev/null and b/docs/5.0.0/_static/plus.png differ diff --git a/docs/5.0.0/_static/pygments.css b/docs/5.0.0/_static/pygments.css new file mode 100644 index 00000000..84ab3030 --- /dev/null +++ b/docs/5.0.0/_static/pygments.css @@ -0,0 +1,75 @@ +pre { line-height: 125%; } +td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +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: #3D7B7B; font-style: italic } /* Comment */ +.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .k { color: #008000; font-weight: bold } /* Keyword */ +.highlight .o { color: #666666 } /* Operator */ +.highlight .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */ +.highlight .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #9C6500 } /* Comment.Preproc */ +.highlight .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */ +.highlight .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */ +.highlight .gr { color: #E40000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #008400 } /* Generic.Inserted */ +.highlight .go { color: #717171 } /* Generic.Output */ +.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #0044DD } /* Generic.Traceback */ +.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #008000 } /* Keyword.Pseudo */ +.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #B00040 } /* Keyword.Type */ +.highlight .m { color: #666666 } /* Literal.Number */ +.highlight .s { color: #BA2121 } /* Literal.String */ +.highlight .na { color: #687822 } /* Name.Attribute */ +.highlight .nb { color: #008000 } /* Name.Builtin */ +.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */ +.highlight .no { color: #880000 } /* Name.Constant */ +.highlight .nd { color: #AA22FF } /* Name.Decorator */ +.highlight .ni { color: #717171; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #0000FF } /* Name.Function */ +.highlight .nl { color: #767600 } /* Name.Label */ +.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #19177C } /* Name.Variable */ +.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mb { color: #666666 } /* Literal.Number.Bin */ +.highlight .mf { color: #666666 } /* Literal.Number.Float */ +.highlight .mh { color: #666666 } /* Literal.Number.Hex */ +.highlight .mi { color: #666666 } /* Literal.Number.Integer */ +.highlight .mo { color: #666666 } /* Literal.Number.Oct */ +.highlight .sa { color: #BA2121 } /* Literal.String.Affix */ +.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */ +.highlight .sc { color: #BA2121 } /* Literal.String.Char */ +.highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */ +.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #BA2121 } /* Literal.String.Double */ +.highlight .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */ +.highlight .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */ +.highlight .sx { color: #008000 } /* Literal.String.Other */ +.highlight .sr { color: #A45A77 } /* Literal.String.Regex */ +.highlight .s1 { color: #BA2121 } /* Literal.String.Single */ +.highlight .ss { color: #19177C } /* Literal.String.Symbol */ +.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */ +.highlight .fm { color: #0000FF } /* Name.Function.Magic */ +.highlight .vc { color: #19177C } /* Name.Variable.Class */ +.highlight .vg { color: #19177C } /* Name.Variable.Global */ +.highlight .vi { color: #19177C } /* Name.Variable.Instance */ +.highlight .vm { color: #19177C } /* Name.Variable.Magic */ +.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/docs/5.0.0/_static/searchtools.js b/docs/5.0.0/_static/searchtools.js new file mode 100644 index 00000000..92da3f8b --- /dev/null +++ b/docs/5.0.0/_static/searchtools.js @@ -0,0 +1,619 @@ +/* + * searchtools.js + * ~~~~~~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for the full-text search. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"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] = 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, + }; +} + +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] = item; + + let listItem = document.createElement("li"); + 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 = _( + "Search finished, found ${resultCount} page(s) matching the search query." + ).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]. +// 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 [".headerlinks", "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.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]. + 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) { + let score = Math.round(100 * queryLower.length / title.length) + normalResults.push([ + docNames[file], + titles[file] !== title ? `${titles[file]} > ${title}` : title, + id !== null ? "#" + id : "", + null, + score, + filenames[file], + ]); + } + } + } + + // 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], + ]; + 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]], + ]); + }; + 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], + ]); + } + 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/docs/5.0.0/_static/sphinx_highlight.js b/docs/5.0.0/_static/sphinx_highlight.js new file mode 100644 index 00000000..8a96c69a --- /dev/null +++ b/docs/5.0.0/_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/docs/5.0.0/distinct_counting/cpc.html b/docs/5.0.0/distinct_counting/cpc.html new file mode 100644 index 00000000..6b7c53e3 --- /dev/null +++ b/docs/5.0.0/distinct_counting/cpc.html @@ -0,0 +1,270 @@ + + + + + + + Compressed Probabilistic Counting (CPC) — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Compressed Probabilistic Counting (CPC)

+

High performance C++ implementation of Compressed Probabilistic Counting (CPC) Sketch. +This is a unique-counting sketch that implements the Compressed Probabilistic Counting (CPC, a.k.a FM85) algorithms developed by Kevin Lang in his paper +Back to the Future: an Even More Nearly Optimal Cardinality Estimation Algorithm. +This sketch is extremely space-efficient when serialized. +In an apples-to-apples empirical comparison against compressed HyperLogLog sketches, this new algorithm simultaneously wins on the two dimensions of the space/accuracy tradeoff and produces sketches that are smaller than the entropy of HLL, so no possible implementation of compressed HLL can match its space efficiency for a given accuracy. As described in the paper this sketch implements a newly developed ICON estimator algorithm that survives unioning operations, another well-known estimator, the Historical Inverse Probability (HIP) estimator does not. +The update speed performance of this sketch is quite fast and is comparable to the speed of HLL. +The unioning (merging) capability of this sketch also allows for merging of sketches with different configurations of K. +For additional security this sketch can be configured with a user-specified hash seed.

+
+
+class cpc_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.cpc_sketch
+

Reads a bytes object and returns the corresponding cpc_sketch

+
+ +

Non-static Methods:

+
+
+__init__(self, lg_k: int = 11, seed: int = 9001) None
+

Creates a new CPC sketch

+
+
Parameters:
+
    +
  • lg_k (int, optional) – base 2 logarithm of the number of bins in the sketch

  • +
  • seed (int, optional) – seed value for the hash function

  • +
+
+
+
+ +
+
+get_estimate
+

Estimate of the distinct count of the input stream

+
+ +
+
+get_lower_bound
+

Returns an approximate lower bound on the estimate for kappa values in {1, 2, 3}, roughly corresponding to standard deviations

+
+ +
+
+get_upper_bound
+

Returns an approximate upper bound on the estimate for kappa values in {1, 2, 3}, roughly corresponding to standard deviations

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+property lg_k
+

Configured lg_k of this sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, datum: int) -> None

  2. +
+

Updates the sketch with the given 64-bit integer value

+
    +
  1. update(self, datum: float) -> None

  2. +
+

Updates the sketch with the given 64-bit floating point

+
    +
  1. update(self, datum: str) -> None

  2. +
+

Updates the sketch with the given string

+
+ +
+ +
+
+class cpc_union(*args, **kwargs)
+
+
+__init__(self, lg_k: int, seed: int = 9001) None
+
+ +
+
+get_result
+

Returns a CPC sketch with the result of the union

+
+ +
+
+update
+

Updates the union with the provided CPC sketch

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.0/distinct_counting/hyper_log_log.html b/docs/5.0.0/distinct_counting/hyper_log_log.html new file mode 100644 index 00000000..c28cf5e9 --- /dev/null +++ b/docs/5.0.0/distinct_counting/hyper_log_log.html @@ -0,0 +1,426 @@ + + + + + + + HyperLogLog (HLL) — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

HyperLogLog (HLL)

+

This is a high performance implementation of Phillipe Flajolet’s HLL sketch but with significantly improved error behavior.

+

If the ONLY use case for sketching is counting uniques and merging, the HLL sketch is a reasonable choice, although the highest performing in terms of accuracy for storage space consumed is CPC (Compressed Probabilistic Counting). For large enough counts, this HLL version (with HLL_4) can be 2 to 16 times smaller than the Theta sketch family for the same accuracy.

+

This implementation offers three different types of HLL sketch, each with different trade-offs with accuracy, space and performance. +These types are specified with the target_hll_type parameter.

+

In terms of accuracy, all three types, for the same lg_config_k, have the same error distribution as a function of n, the number of unique values fed to the sketch. +The configuration parameter lg_config_k is the log-base-2 of k, where k is the number of buckets or slots for the sketch.

+

During warmup, when the sketch has only received a small number of unique items (up to about 10% of k), this implementation leverages a new class of estimator algorithms with significantly better accuracy.

+
+
+class tgt_hll_type
+

Target HLL flavor

+
+
+HLL_4 : 4 bits per entry
+
+ +
+
+HLL_6 : 6 bits per entry
+
+ +
+
+HLL_8 : 8 bits per entry
+
+ +
+ +
+
+class hll_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.hll_sketch
+

Reads a bytes object and returns the corresponding hll_sketch

+
+ +
+
+get_max_updatable_serialization_bytes(lg_k: int, tgt_type: _datasketches.tgt_hll_type) int
+

Provides a likely upper bound on serialization size for the given parameters

+
+ +
+
+get_rel_err(upper_bound: bool, unioned: bool, lg_k: int, num_std_devs: int) float
+

Returns the a priori relative error bound for the given parameters

+
+ +

Non-static Methods:

+
+
+__init__(self, lg_k: int, tgt_type: _datasketches.tgt_hll_type = _datasketches.tgt_hll_type.HLL_8, start_max_size: bool = False) None
+

Constructs a new HLL sketch

+
+
Parameters:
+
    +
  • lg_config_k (int) – A full sketch can hold 2^lg_config_k rows. Must be between 7 and 21, inclusive,

  • +
  • tgt_type (tgt_hll_type) – The HLL mode to use, if/when the sketch reaches estimation mode

  • +
  • start_full_size (bool) – Indicates whether to start in HLL mode, keeping memory use constant (if HLL_6 or HLL_8) at the cost of much higher initial memory use. Default (and recommended) is False.

  • +
+
+
+
+ +
+
+get_compact_serialization_bytes
+

Returns the size of the serialized sketch when compressing the exception table if HLL_4

+
+ +
+
+get_estimate
+

Estimate of the distinct count of the input stream

+
+ +
+
+get_lower_bound
+

Returns the approximate lower error bound given the specified number of standard deviations in {1, 2, 3}

+
+ +
+
+get_updatable_serialization_bytes
+

Returns the size of the serialized sketch

+
+ +
+
+get_upper_bound
+

Returns the approximate upper error bound given the specified number of standard deviations in {1, 2, 3}

+
+ +
+
+is_compact
+

True if the sketch is compact, otherwise False

+
+ +
+
+is_empty
+

True if the sketch is empty, otherwise False

+
+ +
+
+property lg_config_k
+

Configured lg_k value for the sketch

+
+ +
+
+reset
+

Resets the sketch to the empty state in coupon collection mode

+
+ +
+
+serialize_compact
+

Serializes the sketch into a bytes object, compressing the exception table if HLL_4

+
+ +
+
+serialize_updatable
+

Serializes the sketch into a bytes object

+
+ +
+
+property tgt_type
+

The HLL type (4, 6, or 8) when in estimation mode

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, datum: int) -> None

  2. +
+

Updates the sketch with the given integral value

+
    +
  1. update(self, datum: float) -> None

  2. +
+

Updates the sketch with the given floating point value

+
    +
  1. update(self, datum: str) -> None

  2. +
+

Updates the sketch with the given string value

+
+ +
+ +
+
+class hll_union(*args, **kwargs)
+

Static Methods:

+
+
+get_rel_err(upper_bound: bool, unioned: bool, lg_k: int, num_std_devs: int) float
+

Returns the a priori relative error bound for the given parameters

+
+ +

Non-static Methods:

+
+
+__init__(self, lg_max_k: int) None
+

Construct an hll_union object if the given size.

+
+
Parameters:
+

lg_max_k (int) – The maximum size, in log2, of k. Must be between 7 and 21, inclusive.

+
+
+
+ +
+
+get_estimate
+

Estimate of the distinct count of the input stream

+
+ +
+
+get_lower_bound
+

Returns the approximate lower error bound given the specified number of standard deviations in {1, 2, 3}

+
+ +
+
+get_result
+

Returns a sketch of the target type representing the current union state

+
+ +
+
+get_upper_bound
+

Returns the approximate upper error bound given the specified number of standard deviations in {1, 2, 3}

+
+ +
+
+is_empty
+

True if the union is empty, otherwise False

+
+ +
+
+property lg_config_k
+

Configured lg_k value for the union

+
+ +
+
+reset
+

Resets the union to the empty state

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, sketch: _datasketches.hll_sketch) -> None

  2. +
+

Updates the union with the given HLL sketch

+
    +
  1. update(self, datum: int) -> None

  2. +
+

Updates the union with the given integral value

+
    +
  1. update(self, datum: float) -> None

  2. +
+

Updates the union with the given floating point value

+
    +
  1. update(self, datum: str) -> None

  2. +
+

Updates the union with the given string value

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.0/distinct_counting/index.html b/docs/5.0.0/distinct_counting/index.html new file mode 100644 index 00000000..e75799a9 --- /dev/null +++ b/docs/5.0.0/distinct_counting/index.html @@ -0,0 +1,152 @@ + + + + + + + Distinct Counting — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Distinct Counting

+

Distinct counting is one of the earliest tasks to which sketches were applied. The concept is simple: +Provide an estimate of the number of unique elements in a set of data. One of the earliest solutions came +from Flajolet and Martin in 1985 with their seminal work +Probabilistic counting Algorithms for Data Base Applications.

+

The DataSketches library offers several types of distinct counting sketches, each with different properties.

+
+
    +
  • hll_sketch: Hyper Log Log, a well-known sketch for distinct counting but no longer state-of-the-art.

  • +
  • cpc_sketch: Provides a better accuracy-space trade-off than HLL, but with a somewhat larger footprint while in-memory.

  • +
  • theta_sketch: Theta sketch, a type of k-minimum value sketch, which provide good performance with intersection and set difference operations.

  • +
  • tuple_sketch: Tuple sketch, which is similar to a theta sketch but supports additional data stored with each key.

  • +
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.0/distinct_counting/theta.html b/docs/5.0.0/distinct_counting/theta.html new file mode 100644 index 00000000..71610cc4 --- /dev/null +++ b/docs/5.0.0/distinct_counting/theta.html @@ -0,0 +1,440 @@ + + + + + + + Theta Sketch — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Theta Sketch

+

Theta sketches are used for distinct counting.

+

The theta package contains the basic sketch classes that are members of the Theta Sketch Framework. +There is a separate Tuple package for many of the sketches that are derived from the same algorithms defined in the Theta Sketch Framework paper.

+

The Theta Sketch sketch is a space-efficient method for estimating cardinalities of sets. +It can also easily handle set operations (such as union, intersection, difference) while maintaining good accuracy. +Theta sketch is a practical variant of the K-Minimum Values sketch which avoids the need to sort the stored +hash values on every insertion to the sketch. +It has better error properties than the HyperLogLog sketch for set operations beyond the simple union.

+

Set operations (union, intersection, A-not-B) are performed through the use of dedicated objects.

+

Several Jaccard similarity +measures can be computed between theta sketches with the theta_jaccard_similarity class.

+
+
+class theta_sketch
+

An abstract base class for theta sketches

+
+
+get_estimate
+

Estimate of the distinct count of the input stream

+
+ +
+
+get_lower_bound
+

Returns an approximate lower bound on the estimate at standard deviations in {1, 2, 3}

+
+ +
+
+get_seed_hash
+

Returns a hash of the seed used in the sketch

+
+ +
+
+get_upper_bound
+

Returns an approximate upper bound on the estimate at standard deviations in {1, 2, 3}

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if sketch is in estimation mode, otherwise False

+
+ +
+
+is_ordered
+

Returns True if the sketch entries are sorted, otherwise False

+
+ +
+
+property num_retained
+

The number of items currently in the sketch

+
+ +
+
+property theta
+

Theta (effective sampling rate) as a fraction from 0 to 1

+
+ +
+
+property theta64
+

Theta as 64-bit value

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+ +
+
+class update_theta_sketch(*args, **kwargs)
+
+
+__init__(self, lg_k: int = 12, p: float = 1.0, seed: int = 9001) None
+

Creates an update_theta_sketch using the provided parameters

+
+
Parameters:
+
    +
  • lg_k (int, optional) – base 2 logarithm of the maximum size of the sketch. Default 12.

  • +
  • p (float, optional) – an initial sampling rate to use. Default 1.0

  • +
  • seed (int, optional) – the seed to use when hashing values

  • +
+
+
+
+ +
+
+compact
+

Returns a compacted form of the sketch, optionally sorting it

+
+ +
+
+reset
+

Resets the sketch to the initial empty state

+
+ +
+
+trim
+

Removes retained entries in excess of the nominal size k (if any)

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, datum: int) -> None

  2. +
+

Updates the sketch with the given integral value

+
    +
  1. update(self, datum: float) -> None

  2. +
+

Updates the sketch with the given floating point value

+
    +
  1. update(self, datum: str) -> None

  2. +
+

Updates the sketch with the given string

+
+ +
+ +
+
+class compact_theta_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, seed: int = 9001) _datasketches.compact_theta_sketch
+

Reads a bytes object and returns the corresponding compact_theta_sketch

+
+ +

Non-static Methods:

+
+
+__init__(self, arg0: _datasketches.theta_sketch, arg1: bool, /) None
+

Creates a compact_theta_sketch from an existing theta_sketch.

+
+
Parameters:
+
    +
  • other (theta_sketch) – a source theta_sketch

  • +
  • ordered (bool) – whether the incoming sketch entries are sorted. Default True

  • +
+
+
+
+ +
+
+serialize
+

Serializes the sketch into a bytes object

+
+ +
+ +
+
+class theta_union(*args, **kwargs)
+
+
+__init__(self, lg_k: int = 12, p: float = 1.0, seed: int = 9001) None
+

Creates a theta_union using the provided parameters

+
+
Parameters:
+
    +
  • lg_k (int, optional) – base 2 logarithm of the maximum size of the union. Default 12.

  • +
  • p (float, optional) – an initial sampling rate to use. Default 1.0

  • +
  • seed (int, optional) – the seed to use when hashing values. Must match all sketch seeds.

  • +
+
+
+
+ +
+
+get_result
+

Returns the sketch corresponding to the union result

+
+ +
+
+update
+

Updates the union with the given sketch

+
+ +
+ +
+
+class theta_intersection(*args, **kwargs)
+
+
+__init__(self, seed: int = 9001) None
+

Creates a theta_intersection using the provided parameters

+
+
Parameters:
+

seed (int, optional) – the seed to use when hashing values. Must match all sketch seeds

+
+
+
+ +
+
+get_result
+

Returns the sketch corresponding to the intersection result

+
+ +
+
+has_result
+

Returns True if the intersection has a valid result, otherwise False

+
+ +
+
+update
+

Intersections the provided sketch with the current intersection state

+
+ +
+ +
+
+class theta_a_not_b(*args, **kwargs)
+
+
+__init__(self, seed: int = 9001) None
+

Creates a tuple_a_not_b object

+
+
Parameters:
+

seed (int, optional) – the seed to use when hashing values. Must match all sketch seeds.

+
+
+
+ +
+
+compute
+

Returns a sketch with the result of applying the A-not-B operation on the given inputs

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.0/distinct_counting/tuple.html b/docs/5.0.0/distinct_counting/tuple.html new file mode 100644 index 00000000..48bcfd61 --- /dev/null +++ b/docs/5.0.0/distinct_counting/tuple.html @@ -0,0 +1,478 @@ + + + + + + + Tuple Sketch — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Tuple Sketch

+

Tuple sketches are an extension of Theta sketches, meaning they provide estimate of distinct counts, that +allow the keeping of arbitrary summaries associated with each retained key +(for example, a count for every key). The use of a tuple_sketch requires a TuplePolicy which +defines how summaries are created, updated, merged, or intersected. The library provides a few basic +examples of TuplePolicy implementations, but the right custom summary and policy can allow very +complicated analysis to be performed quite easily.

+

Set operations (union, intersection, A-not-B) are performed through the use of dedicated objects.

+

Several Jaccard similarity +measures can be computed between theta sketches with the tuple_jaccard_similarity class.

+
+

Note

+

Serializing and deserializing this sketch requires the use of a PyObjectSerDe.

+
+
+
+class tuple_sketch
+

An abstract base class for tuple sketches.

+
+
+DEFAULT_SEED = 9001
+
+ +
+
+get_estimate
+

Estimate of the distinct count of the input stream

+
+ +
+
+get_lower_bound
+

Returns an approximate lower bound on the estimate at standard deviations in {1, 2, 3}

+
+ +
+
+get_seed_hash
+

Returns a hash of the seed used in the sketch

+
+ +
+
+get_upper_bound
+

Returns an approximate upper bound on the estimate at standard deviations in {1, 2, 3}

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if sketch is in estimation mode, otherwise False

+
+ +
+
+is_ordered
+

Returns True if the sketch entries are sorted, otherwise False

+
+ +
+
+property num_retained
+

The number of items currently in the sketch

+
+ +
+
+property theta
+

Theta (effective sampling rate) as a fraction from 0 to 1

+
+ +
+
+property theta64
+

Theta as 64-bit value

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+ +
+
+class update_tuple_sketch(*args, **kwargs)
+
+
+__init__(self, policy: _datasketches.TuplePolicy, lg_k: int = 12, p: float = 1.0, seed: int = 9001) None
+

Creates an update_tuple_sketch using the provided parameters

+
+
Parameters:
+
    +
  • policy (TuplePolicy) – a policy to use when updating

  • +
  • lg_k (int, optional) – base 2 logarithm of the maximum size of the sketch. Default 12.

  • +
  • p (float, optional) – an initial sampling rate to use. Default 1.0

  • +
  • seed (int, optional) – the seed to use when hashing values

  • +
+
+
+
+ +
+
+compact
+

Returns a compacted form of the sketch, optionally sorting it

+
+ +
+
+reset
+

Resets the sketch to the initial empty state

+
+ +
+
+trim
+

Removes retained entries in excess of the nominal size k (if any)

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, datum: int, value: object) -> None

  2. +
+

Updates the sketch with the given integral item and summary value

+
    +
  1. update(self, datum: float, value: object) -> None

  2. +
+

Updates the sketch with the given floating point item and summary value

+
    +
  1. update(self, datum: str, value: object) -> None

  2. +
+

Updates the sketch with the given string item and summary value

+
+ +
+ +
+
+class compact_tuple_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe, seed: int = 9001) _datasketches.compact_tuple_sketch
+

Reads a bytes object and returns the corresponding compact_tuple_sketch

+
+ +

Non-static Methods:

+
+
+__init__(self, other: _datasketches.tuple_sketch, ordered: bool = True) None
+
+__init__(self, other: _datasketches.theta_sketch, summary: object) None
+

Overloaded function.

+
    +
  1. __init__(self, other: _datasketches.tuple_sketch, ordered: bool = True) -> None

  2. +
+

Creates a compact_tuple_sketch from an existing tuple_sketch.

+
+
Parameters:
+
    +
  • other (tuple_sketch) – a sourch tuple_sketch

  • +
  • ordered (bool, optional) – whether the incoming sketch entries are sorted. Default True

  • +
+
+
+
    +
  1. __init__(self, other: _datasketches.theta_sketch, summary: object) -> None

  2. +
+

Creates a compact_tuple_sketch from a theta_sketch using a fixed summary value.

+
+
Parameters:
+
    +
  • other (theta_sketch) – a source theta sketch

  • +
  • summary (object) – a summary to use for every sketch entry

  • +
+
+
+
+ +
+
+serialize
+

Serializes the sketch into a bytes object

+
+ +
+ +
+
+class tuple_union(*args, **kwargs)
+
+
+__init__(self, policy: _datasketches.TuplePolicy, lg_k: int = 12, p: float = 1.0, seed: int = 9001) None
+

Creates a tuple_union using the provided parameters

+
+
Parameters:
+
    +
  • policy (TuplePolicy) – a policy to use when unioning entries

  • +
  • lg_k (int, optional) – base 2 logarithm of the maximum size of the union. Default 12.

  • +
  • p (float, optional) – an initial sampling rate to use. Default 1.0

  • +
  • seed (int, optional) – the seed to use when hashing values. Must match any sketch seeds.

  • +
+
+
+
+ +
+
+get_result
+

Returns the sketch corresponding to the union result

+
+ +
+
+reset
+

Resets the sketch to the initial empty

+
+ +
+
+update
+

Updates the union with the given sketch

+
+ +
+ +
+
+class tuple_intersection(*args, **kwargs)
+
+
+__init__(self, policy: _datasketches.TuplePolicy, seed: int = 9001) None
+

Creates a tuple_intersection using the provided parameters

+
+
Parameters:
+
    +
  • policy (TuplePolicy) – a policy to use when intersecting entries

  • +
  • seed (int, optional) – the seed to use when hashing values. Must match any sketch seeds

  • +
+
+
+
+ +
+
+get_result
+

Returns the sketch corresponding to the intersection result

+
+ +
+
+has_result
+

Returns True if the intersection has a valid result, otherwise False

+
+ +
+
+update
+

Intersects the provided sketch with the current intersection state

+
+ +
+ +
+
+class tuple_a_not_b(*args, **kwargs)
+
+
+__init__(self, seed: int = 9001) None
+

Creates a tuple_a_not_b object

+
+
Parameters:
+

seed (int, optional) – the seed to use when hashing values. Must match any sketch seeds.

+
+
+
+ +
+
+compute
+

Returns a sketch with the result of applying the A-not-B operation on the given inputs

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.0/frequency/count_min_sketch.html b/docs/5.0.0/frequency/count_min_sketch.html new file mode 100644 index 00000000..c6a8e366 --- /dev/null +++ b/docs/5.0.0/frequency/count_min_sketch.html @@ -0,0 +1,303 @@ + + + + + + + CountMin Sketch — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

CountMin Sketch

+

The CountMin sketch, as described in Cormode and Muthukrishnan in +http://dimacs.rutgers.edu/~graham/pubs/papers/cm-full.pdf, +is used for approximate Frequency Estimation. +For an item \(x\) with frequency \(f_x\), the sketch provides an estimate, \(\hat{f_x}\), +such that \(f_x \approx \hat{f_x}.\) +The sketch guarantees that \(f_x \le \hat{f_x}\) and provides a probabilistic upper bound which is dependent on the size parameters. +The sketch provides an estimate of the occurrence frequency for any queried item but, in contrast +to the Frequent Items Sketch, this sketch does not provide a list of +heavy hitters.

+
+
+class count_min_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.count_min_sketch
+

Reads a bytes object and returns the corresponding count_min_sketch

+
+ +
+
+suggest_num_buckets(relative_error: float) int
+

Suggests the number of buckets needed to achieve an accuracy within the provided relative_error. For example, when relative_error = 0.05, the returned frequency estimates satisfy the ‘relative_error’ guarantee that never overestimates the weights but may underestimate the weights by 5% of the total weight in the sketch. Returns the number of hash buckets at every level of the sketch required in order to obtain the specified relative error.

+
+ +
+
+suggest_num_hashes(confidence: float) int
+

Suggests the number of hashes needed to achieve the provided confidence. For example, with 95% confidence, frequency estimates satisfy the ‘relative_error’ guarantee. Returns the number of hash functions that are required in order to achieve the specified confidence of the sketch. confidence = 1 - delta, with delta denoting the sketch failure probability.

+
+ +

Non-static Methods:

+
+
+get_estimate
+

Overloaded function.

+
    +
  1. get_estimate(self, item: int) -> float

  2. +
+

Returns an estimate of the frequency of the provided 64-bit integer value

+
    +
  1. get_estimate(self, item: str) -> float

  2. +
+

Returns an estimate of the frequency of the provided string

+
+ +
+
+get_lower_bound
+

Overloaded function.

+
    +
  1. get_lower_bound(self, item: int) -> float

  2. +
+

Returns a lower bound on the estimate for the given 64-bit integer value

+
    +
  1. get_lower_bound(self, item: str) -> float

  2. +
+

Returns a lower bound on the estimate for the provided string

+
+ +
+
+get_relative_error
+

Returns the maximum permissible error for any frequency estimate query

+
+ +
+
+get_serialized_size_bytes
+

Returns the size in bytes of the serialized image of the sketch

+
+ +
+
+get_upper_bound
+

Overloaded function.

+
    +
  1. get_upper_bound(self, item: int) -> float

  2. +
+

Returns an upper bound on the estimate for the given 64-bit integer value

+
    +
  1. get_upper_bound(self, item: str) -> float

  2. +
+

Returns an upper bound on the estimate for the provided string

+
+ +
+
+is_empty
+

Returns True if the sketch has seen no items, otherwise False

+
+ +
+
+merge
+

Merges the provided other sketch into this one

+
+ +
+
+property num_buckets
+

The configured number of buckets for the sketch

+
+ +
+
+property num_hashes
+

The configured number of hashes for the sketch

+
+ +
+
+property seed
+

The base hash seed for the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+property total_weight
+

The total weight currently inserted into the stream

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: int, weight: float = 1.0) -> None

  2. +
+

Updates the sketch with the given 64-bit integer value

+
    +
  1. update(self, item: str, weight: float = 1.0) -> None

  2. +
+

Updates the sketch with the given string

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.0/frequency/frequent_items.html b/docs/5.0.0/frequency/frequent_items.html new file mode 100644 index 00000000..3b70f66c --- /dev/null +++ b/docs/5.0.0/frequency/frequent_items.html @@ -0,0 +1,479 @@ + + + + + + + Frequent Items — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Frequent Items

+

This sketch is useful for tracking approximate frequencies of items (object or string) with optional associated +integer counts that are members of a multiset of such items. +The true frequency of an item is defined to be the sum of associated counts.

+

This implementation provides the following capabilities:

+
    +
  • Estimate the frequency of an item.

  • +
  • Return upper and lower bounds of any item, such that the true frequency is always between the upper and lower bounds.

  • +
  • Return a global maximum error that holds for all items in the stream.

  • +
  • Return an array of frequent items that qualify either a NO_FALSE_POSITIVES or a NO_FALSE_NEGATIVES error type.

  • +
  • Merge itself with another sketch object created from this class.

  • +
  • Serialize/Deserialize to/from a byte array.

  • +
+

Space Usage

+

The sketch is initialized with a maximum map size, maxMapSize, that specifies the maximum physical length of the internal hash map of the form (object item, int count). +The maximum map size is always a power of 2, defined through the variables lg_max_map_size.

+

The hash map starts at a very small size (8 entries) and grows as needed up to the specified maximum map size.

+

Excluding external space required for the item objects, the internal memory space usage of this sketch is 18 * mapSize bytes (assuming 8 bytes for each reference), +plus a small constant number of additional bytes. +The internal memory space usage of this sketch will never exceed 18 * maxMapSize bytes, plus a small constant number of additional bytes.

+

Maximum Capacity of the Sketch

+

The LOAD_FACTOR for the hash map is internally set at \(75\%\), which means at any time the map capacity of (item, count) pairs is mapCap = 0.75 * mapSize. +The maximum capacity of (item, count) pairs of the sketch is maxMapCap = 0.75 * maxMapSize.

+

Updating the sketch with ``(item, count)`` pairs

+

If the item is found in the hash map, the mapped count field (the “counter”) is incremented by the incoming count; otherwise, a new counter (item, count) pair is created. +If the number of tracked counters reaches the maximum capacity of the hash map, the sketch decrements all of the counters (by an approximately computed median) +and removes any non-positive counters.

+

Accuracy

+

If fewer than 0.75 * maxMapSize different items are inserted into the sketch, the estimated frequencies returned by the sketch will be exact.

+

The logic of the frequent items sketch is such that the stored counts and true counts are never too different. +More specifically, for any item, the sketch can return an estimate of the true frequency of item, along with upper and lower bounds on the frequency (that hold deterministically).

+

For this implementation and for a specific active item, it is guaranteed that the true frequency will be between the Upper Bound (UB) and the Lower Bound (LB) computed for that item. +Specifically, (UB- LB) W * epsilon, where \(W\) denotes the sum of all item counts, and \(epsilon = 3.5/M\), where \(epsilon = M\) is the maxMapSize.

+

This is a worst-case guarantee that applies to arbitrary inputs. +For inputs typically seen in practice, (UB-LB) is usually much smaller.

+

Background

+

This code implements a variant of what is commonly known as the “Misra-Gries algorithm”. +Variants of it were discovered and rediscovered and redesigned several times over the years:

+
    +
  • Finding repeated elements, Misra, Gries, 1982

  • +
  • Frequency estimation of Internet packet streams with limited space Demaine, Lopez-Ortiz, Munro, 2002

  • +
  • A simple algorithm for finding frequent elements in streams and bags Karp, Shenker, Papadimitriou, 2003

  • +
  • Efficient Computation of Frequent and Top-k Elements in Data Streams Metwally, Agrawal, Abbadi, 2006

  • +
+

For speed, we do employ some randomization that introduces a small probability that our proof of the worst-case bound might not apply to a given run. +However, we have ensured that this probability is extremely small. +For example, if the stream causes one table purge (rebuild), our proof of the worst-case bound applies with a probability of at least 1 - 1E-14. +If the stream causes 1E9 purges, our proof applies with a probability of at least 1 - 1E-5.

+

There are two flavors of Frequent Items Sketches, one with generic items (objects) and another specific to strings. +The string version is a legacy name from before the library supported generic objects and is retained +only for backwards compatibility.

+
+

Note

+

The frequent_items_sketch uses an input object’s __hash__ and __eq__ methods.

+
+
+

Note

+

Serializing and deserializing the frequent_items_sketch requires the use of a PyObjectSerDe.

+
+
+
+class frequent_items_error_type
+
+
+NO_FALSE_POSITIVES : Returns only true positives but may miss some heavy hitters.
+
+ +
+
+NO_FALSE_NEGATIVES : Does not miss any heavy hitters but may return false positives.
+
+ +
+ +
+
+class frequent_items_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe) _datasketches.frequent_items_sketch
+

Reads a bytes object using the provided serde and returns the corresponding frequent_strings_sketch.

+
+ +
+
+get_epsilon_for_lg_size(lg_max_map_size: int) float
+

Returns the epsilon value used to compute a priori error for a given log2(max_map_size)

+
+ +
+
+get_apriori_error(lg_max_map_size: int, estimated_total_weight: int) float
+

Returns the estimated a priori error given the max_map_size for the sketch and the estimated_total_stream_weight.

+
+ +

Non-static Methods:

+
+
+__init__(self, lg_max_k: int) None
+

Creates an instance of the sketch

+
+
Parameters:
+

lg_max_k (int) – base 2 logarithm of the maximum size of the internal hash map of the sketch. Maximum capacity is 0.75 of this value, which is the maximum number of distinct items the sketch can contain.

+
+
+
+ +
+
+property epsilon
+

The epsilon value used by the sketch to compute error

+
+ +
+
+get_estimate
+

Returns the estimate of the weight (frequency) of the given item. +Note: The true frequency of a item would be the sum of the counts as a result of the two update functions.

+
+ +
+
+get_frequent_items
+
+ +
+
+get_lower_bound
+

Returns the guaranteed lower bound weight (frequency) of the given item.

+
+ +
+
+get_serialized_size_bytes
+

Computes the size needed to serialize the current state of the sketch using the provided serde. This can be expensive since every item needs to be looked at.

+
+ +
+
+get_upper_bound
+

Returns the guaranteed upper bound weight (frequency) of the given item.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+merge
+

Merges the given sketch into this one

+
+ +
+
+property num_active_items
+

The number of active items in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object using the provided serde.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+property total_weight
+

The sum of the weights (frequencies) in the stream seen so far by the sketch

+
+ +
+
+update
+

Updates the sketch with the given string and, optionally, a weight

+
+ +
+ +
+
+class frequent_strings_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.frequent_strings_sketch
+

Reads a bytes object and returns the corresponding frequent_strings_sketch.

+
+ +
+
+get_epsilon_for_lg_size(lg_max_map_size: int) float
+

Returns the epsilon value used to compute a priori error for a given log2(max_map_size)

+
+ +
+
+get_apriori_error(lg_max_map_size: int, estimated_total_weight: int) float
+

Returns the estimated a priori error given the max_map_size for the sketch and the estimated_total_stream_weight.

+
+ +

Non-static Methods:

+
+
+__init__(self, lg_max_k: int) None
+

Creates an instance of the sketch

+
+
Parameters:
+

lg_max_k (int) – base 2 logarithm of the maximum size of the internal hash map of the sketch. Maximum capacity is 0.75 of this value, which is the maximum number of distinct items the sketch can contain.

+
+
+
+ +
+
+property epsilon
+

The epsilon value used by the sketch to compute error

+
+ +
+
+get_estimate
+

Returns the estimate of the weight (frequency) of the given item. +Note: The true frequency of a item would be the sum of the counts as a result of the two update functions.

+
+ +
+
+get_frequent_items
+
+ +
+
+get_lower_bound
+

Returns the guaranteed lower bound weight (frequency) of the given item.

+
+ +
+
+get_serialized_size_bytes
+

Computes the size needed to serialize the current state of the sketch. This can be expensive since every item needs to be looked at.

+
+ +
+
+get_upper_bound
+

Returns the guaranteed upper bound weight (frequency) of the given item.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+merge
+

Merges the given sketch into this one

+
+ +
+
+property num_active_items
+

The number of active items in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+property total_weight
+

The sum of the weights (frequencies) in the stream seen so far by the sketch

+
+ +
+
+update
+

Updates the sketch with the given string and, optionally, a weight

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.0/frequency/index.html b/docs/5.0.0/frequency/index.html new file mode 100644 index 00000000..99bd3d37 --- /dev/null +++ b/docs/5.0.0/frequency/index.html @@ -0,0 +1,145 @@ + + + + + + + Frequency Sketches — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Frequency Sketches

+

Frequency estimation involves determining how often an item has been seen in a stream. The library currently +offers two types of sketches for frequency estimation, one of which has two closely-related variants.

+
+
    +
  • frequent_items_sketch: Identifies the Top K or heavy hitters in a stream, those items whose weight is above a certain percentage of the entire stream. Does not necessarily provide an estimate for most items outside the heavy hitters.

  • +
  • frequent_strings_sketch: Like the items version but containing snly strings (an implementation from before the library handled generic objects).

  • +
  • count_min_sketch: Provides an estimate for any item, regardless of relative weight, but does not maintain a list of the heaviest items.

  • +
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.0/genindex.html b/docs/5.0.0/genindex.html new file mode 100644 index 00000000..6dbd7d3a --- /dev/null +++ b/docs/5.0.0/genindex.html @@ -0,0 +1,1384 @@ + + + + + + Index — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ + +

Index

+ +
+ _ + | A + | C + | D + | E + | F + | G + | H + | I + | J + | K + | L + | M + | N + | P + | Q + | R + | S + | T + | U + | V + +
+

_

+ + +
+ +

A

+ + +
+ +

C

+ + + +
+ +

D

+ + + +
+ +

E

+ + + +
+ +

F

+ + + +
+ +

G

+ + + +
+ +

H

+ + + +
+ +

I

+ + + +
+ +

J

+ + +
+ +

K

+ + + +
+ +

L

+ + + +
+ +

M

+ + + +
+ +

N

+ + + +
+ +

P

+ + + +
+ +

Q

+ + + +
+ +

R

+ + +
+ +

S

+ + + +
+ +

T

+ + + +
+ +

U

+ + + +
+ +

V

+ + + +
+ + + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.0/helper/index.html b/docs/5.0.0/helper/index.html new file mode 100644 index 00000000..d977f1ec --- /dev/null +++ b/docs/5.0.0/helper/index.html @@ -0,0 +1,154 @@ + + + + + + + Helper Classes — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Helper Classes

+

These classes are required for certain sketches or specific +functionality within sketches. +Some of them are abstract base classes, but in those cases there is at +least one reference example of a concrete class.

+
+
    +
  • serde is used when serializing and deserializing sketches.

  • +
  • jaccard is used to compute the Jaccard similarity between pairs of theta or tuple sketches.

  • +
  • tuple_policy is required to use a tuple_sketch by specifying how summaries are combined.

  • +
  • ks_test() performs a Kolmogorov-Smirnov test on absolute-error quantiles family sketches.

  • +
  • kernel_function is required when using a kernel_sketch for Kernel Density Estimation.

  • +
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.0/helper/jaccard.html b/docs/5.0.0/helper/jaccard.html new file mode 100644 index 00000000..b66dbf01 --- /dev/null +++ b/docs/5.0.0/helper/jaccard.html @@ -0,0 +1,212 @@ + + + + + + + Jaccard Similarity — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Jaccard Similarity

+

These objects provide measures related to the Jaccard similarity +of theta_sketch and tuple_sketch objects.

+

Note that there are separate classes to be used for theta and tuple sketches.

+
+
+class theta_jaccard_similarity
+

An object to help compute Jaccard similarity between theta sketches.

+
+
+jaccard(sketch_a: _datasketches.theta_sketch, sketch_b: _datasketches.theta_sketch, seed: int = 9001) list[float]
+

Returns a list with {lower_bound, estimate, upper_bound} of the Jaccard similarity between sketches

+
+ +
+
+exactly_equal(sketch_a: _datasketches.theta_sketch, sketch_b: _datasketches.theta_sketch, seed: int = 9001) bool
+

Returns True if sketch_a and sketch_b are equivalent, otherwise False

+
+ +
+
+similarity_test(actual: _datasketches.theta_sketch, expected: _datasketches.theta_sketch, threshold: float, seed: int = 9001) bool
+

Tests similarity of an actual sketch against an expected sketch. Computers the lower bound of the Jaccard index J_{LB} of the actual and expected sketches. If J_{LB} >= threshold, then the sketches are considered to be similar with a confidence of 97.7% and returns True, otherwise False.

+
+ +
+
+dissimilarity_test(actual: _datasketches.theta_sketch, expected: _datasketches.theta_sketch, threshold: float, seed: int = 9001) bool
+

Tests dissimilarity of an actual sketch against an expected sketch. Computers the lower bound of the Jaccard index J_{UB} of the actual and expected sketches. If J_{UB} <= threshold, then the sketches are considered to be dissimilar with a confidence of 97.7% and returns True, otherwise False.

+
+ +
+ +
+
+class tuple_jaccard_similarity
+

An object to help compute Jaccard similarity between tuple sketches.

+
+
+jaccard(sketch_a: _datasketches.tuple_sketch, sketch_b: _datasketches.tuple_sketch, seed: int = 9001) list[float]
+

Returns a list with {lower_bound, estimate, upper_bound} of the Jaccard similarity between sketches

+
+ +
+
+exactly_equal(sketch_a: _datasketches.tuple_sketch, sketch_b: _datasketches.tuple_sketch, seed: int = 9001) bool
+

Returns True if sketch_a and sketch_b are equivalent, otherwise False

+
+ +
+
+similarity_test(actual: _datasketches.tuple_sketch, expected: _datasketches.tuple_sketch, threshold: float, seed: int = 9001) bool
+

Tests similarity of an actual sketch against an expected sketch. Computes the lower bound of the Jaccard index J_{LB} of the actual and expected sketches. If J_{LB} >= threshold, then the sketches are considered to be similar with a confidence of 97.7% and returns True, otherwise False.

+
+ +
+
+dissimilarity_test(actual: _datasketches.tuple_sketch, expected: _datasketches.tuple_sketch, threshold: float, seed: int = 9001) bool
+

Tests dissimilarity of an actual sketch against an expected sketch. Computes the upper bound of the Jaccard index J_{UB} of the actual and expected sketches. If J_{UB} <= threshold, then the sketches are considered to be dissimilar with a confidence of 97.7% and returns True, otherwise False.

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.0/helper/kernel.html b/docs/5.0.0/helper/kernel.html new file mode 100644 index 00000000..a2a61177 --- /dev/null +++ b/docs/5.0.0/helper/kernel.html @@ -0,0 +1,184 @@ + + + + + + + Kernel Function — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Kernel Function

+

A kernel function is a specific type of +mathematical funciton that is particularly useful in certain machine learning and pattern recognition +contexts. The density_sketch performs approximate +kernel density estimation which, unsurprisingly, +relies on the use of such a kernel function.

+

The library provides an abstract base class KernelFunction and an example implementation of a +Gaussian (also known as a Radial Basis Function) kernel. Custom classes must override the base class +and provide a floating point value as a score indicating the similarity of two input vectors.

+
+
+class KernelFunction(*args, **kwargs)
+

A generic base class from which user-defined kernels must inherit.

+
+
+__call__(self, a: object, b: object) float
+

A method to evaluate a kernel with given inputs a and b.

+
+
Parameters:
+
    +
  • a (numpy array) – An input vector

  • +
  • b (numpy array) – An input vector

  • +
+
+
Returns:
+

A vector similarity score

+
+
Return type:
+

float

+
+
+
+ +
+ +
+
+class GaussianKernel(bandwidth: float = 1.0)
+

Bases: KernelFunction

+

Implements a basic Gaussian kernel

+
+
Parameters:
+

bandwidth (float) – The kernel bandwidth, default 1.0

+
+
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.0/helper/ks_test.html b/docs/5.0.0/helper/ks_test.html new file mode 100644 index 00000000..721be0a5 --- /dev/null +++ b/docs/5.0.0/helper/ks_test.html @@ -0,0 +1,210 @@ + + + + + + + Kolmogorov-Smirnov Test — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Kolmogorov-Smirnov Test

+

A Kolmogorov-Smirnov Test <https://en.wikipedia.org/wiki/Kolmogorov%E2%80%93Smirnov_test>`_ is +a test of equality of two distributions to determine if they are likely to have come from the same +underlying distribution. +The DataSketches library provides a modified form of the test that takes into account the error +in each underlying sketch in the analysis.

+

Currently, the test assumes both input sketches are of the same family and data type.

+
+
+ks_test(sk_1: _datasketches.kll_ints_sketch, sk_2: _datasketches.kll_ints_sketch, p: float) bool
+
+ks_test(sk_1: _datasketches.kll_floats_sketch, sk_2: _datasketches.kll_floats_sketch, p: float) bool
+
+ks_test(sk_1: _datasketches.kll_doubles_sketch, sk_2: _datasketches.kll_doubles_sketch, p: float) bool
+
+ks_test(sk_1: _datasketches.kll_items_sketch, sk_2: _datasketches.kll_items_sketch, p: float) bool
+
+ks_test(sk_1: _datasketches.quantiles_ints_sketch, sk_2: _datasketches.quantiles_ints_sketch, p: float) bool
+
+ks_test(sk_1: _datasketches.quantiles_floats_sketch, sk_2: _datasketches.quantiles_floats_sketch, p: float) bool
+
+ks_test(sk_1: _datasketches.quantiles_doubles_sketch, sk_2: _datasketches.quantiles_doubles_sketch, p: float) bool
+
+ks_test(sk_1: _datasketches.quantiles_items_sketch, sk_2: _datasketches.quantiles_items_sketch, p: float) bool
+

Overloaded function.

+
    +
  1. ks_test(sk_1: _datasketches.kll_ints_sketch, sk_2: _datasketches.kll_ints_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for kll_ints_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
    +
  1. ks_test(sk_1: _datasketches.kll_floats_sketch, sk_2: _datasketches.kll_floats_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for kll_floats_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
    +
  1. ks_test(sk_1: _datasketches.kll_doubles_sketch, sk_2: _datasketches.kll_doubles_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for kll_doubles_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
    +
  1. ks_test(sk_1: _datasketches.kll_items_sketch, sk_2: _datasketches.kll_items_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for kll_items_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
    +
  1. ks_test(sk_1: _datasketches.quantiles_ints_sketch, sk_2: _datasketches.quantiles_ints_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for quantiles_ints_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
    +
  1. ks_test(sk_1: _datasketches.quantiles_floats_sketch, sk_2: _datasketches.quantiles_floats_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for quantiles_floats_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +:Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
    +
  1. ks_test(sk_1: _datasketches.quantiles_doubles_sketch, sk_2: _datasketches.quantiles_doubles_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for quantiles_doubles_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
    +
  1. ks_test(sk_1: _datasketches.quantiles_items_sketch, sk_2: _datasketches.quantiles_items_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for quantiles_items_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.0/helper/serde.html b/docs/5.0.0/helper/serde.html new file mode 100644 index 00000000..a4ed73d0 --- /dev/null +++ b/docs/5.0.0/helper/serde.html @@ -0,0 +1,253 @@ + + + + + + + Serialize/Deserialize (SerDe) — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Serialize/Deserialize (SerDe)

+

A SerDe is a class used to serialize items sketches to a bytes object in binary. +Several example SerDes are provided as references.

+

The use of binary-compatible SerDes in different languages is critical for cross-language compatibility.

+

Each implementation must extend the PyObjectSerDe class and override all three of its methods.

+
+
+class PyObjectSerDe(*args, **kwargs)
+

An abstract base class for serde objects. All custom serdes must extend this class.

+
+
+get_size(self, item: object) int
+

Returns the size in bytes of an item

+
+
Parameters:
+

item (object) – The specified object

+
+
Returns:
+

The size of the item in bytes

+
+
Return type:
+

int

+
+
+
+ +
+
+to_bytes(self, item: object) bytes
+

Retuns a bytes object with a serialized version of an item

+
+
Parameters:
+

item (object) – The specified object

+
+
Returns:
+

A bytes object with the serialized object

+
+
Return type:
+

bytes

+
+
+
+ +
+
+from_bytes(self, data: bytes, offset: int) tuple
+

Reads a bytes object starting from the given offest and returns a tuple of the reconstructed object and the number of additional bytes read

+
+
Parameters:
+
    +
  • data (bytes) – A bytes object from which to deserialize

  • +
  • offset (int) – The offset, in bytes, at which to start reading

  • +
+
+
Returns:
+

A tuple with the reconstructed object and the number of bytes read

+
+
Return type:
+

tuple(object, int)

+
+
+
+ +
+ +

The provided SerDes are:

+
+
+class PyStringsSerDe(*args, **kwargs)
+

Bases: PyObjectSerDe

+

Implements a simple string-encoding scheme where a string is +written as <num_bytes> <string_contents>, with no null termination. +This format allows pre-allocating each string, at the cost of +additional storage. Using this format, the serialized string consumes +4 + len(item) bytes.

+
+ +
+
+class PyIntsSerDe(*args, **kwargs)
+

Bases: PyObjectSerDe

+

Implements an integer encoding scheme where each integer is written +as a 32-bit (4 byte) little-endian value.

+
+ +
+
+class PyLongsSerDe(*args, **kwargs)
+

Bases: PyObjectSerDe

+

Implements an integer encoding scheme where each integer is written +as a 64-bit (8 byte) little-endian value.

+
+ +
+
+class PyFloatsSerDe(*args, **kwargs)
+

Bases: PyObjectSerDe

+

Implements a floating point encoding scheme where each value is written +as a 32-bit floating point value.

+
+ +
+
+class PyDoublesSerDe(*args, **kwargs)
+

Implements a floating point encoding scheme where each value is written +as a 64-bit floating point value.

+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.0/helper/tuple_policy.html b/docs/5.0.0/helper/tuple_policy.html new file mode 100644 index 00000000..7aec98fb --- /dev/null +++ b/docs/5.0.0/helper/tuple_policy.html @@ -0,0 +1,230 @@ + + + + + + + Tuple Policy — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Tuple Policy

+

A Tuple Policy is needed when using a tuple_sketch in order to specify how the +summary values should be created, updated, combined, or intersected. A summary can consist of +any python object.

+

Each implementation must extend the abstract base class TuplePolicy.

+
+
+class TuplePolicy(*args, **kwargs)
+

An abstract base class for Tuple Policy objects. All custom policies must extend this class.

+
+
+create_summary(self) object
+

Creates a new Summary object

+
+
Returns:
+

a Summary object

+
+
Return type:
+

object

+
+
+
+ +
+
+update_summary(self, summary: object, update: object) object
+

Applies the relevant policy to update the provided summary with the data in update.

+
+
Parameters:
+
    +
  • summary (object) – An existing Summary

  • +
  • update (object) – An update to apply to the Summary

  • +
+
+
Returns:
+

The updated Summary

+
+
Return type:
+

object

+
+
+
+ +
+
+__call__(self, summary: object, update: object) object
+

Similar to update_summary but allows a different implementation for set operations (union and intersection)

+
+
Parameters:
+
    +
  • summary (object) – An existing Summary

  • +
  • update (object) – An update to apply to the Summary

  • +
+
+
Returns:
+

The updated Summary

+
+
Return type:
+

object

+
+
+
+ +
+ +
+
+class AccumulatorPolicy
+

Bases: TuplePolicy

+

Implements an accumulatory summary policy, where new values +are added to the existing value.

+
+ +
+
+class MinIntPolicy
+

Bases: TuplePolicy

+

Implements a MIN rule, where the smallest integer value is always kept.

+
+ +
+
+class MaxIntPolicy
+

Bases: TuplePolicy

+

Implements a MAX rule, where the largest integer value is always kept.

+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.0/index.html b/docs/5.0.0/index.html new file mode 100644 index 00000000..e2ba4b9d --- /dev/null +++ b/docs/5.0.0/index.html @@ -0,0 +1,215 @@ + + + + + + + Apache DataSketches — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Apache DataSketches

+

DataSketches are highly-efficient algorithms to analyze big data quickly.

+
+

Counting Distincts

+ +
+
+

Quantile Estimation

+ +
+
+

Frequency Sketches

+

This problem may also be known as heavy hitters or TopK

+ +
+
+

Vector Sketches

+ +
+
+

Random Sampling

+ +
+
+

Helper Classes

+ +
+

Note

+

This project is under active development.

+
+
+
+
+

Indices and tables

+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.0/objects.inv b/docs/5.0.0/objects.inv new file mode 100644 index 00000000..bd0053f4 Binary files /dev/null and b/docs/5.0.0/objects.inv differ diff --git a/docs/5.0.0/quantiles/index.html b/docs/5.0.0/quantiles/index.html new file mode 100644 index 00000000..184ed4dc --- /dev/null +++ b/docs/5.0.0/quantiles/index.html @@ -0,0 +1,154 @@ + + + + + + + Quantiles Sketches — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Quantiles Sketches

+

Quantile estimation is useful for understanding the distribution of data values in a stream. The sketches currently +in the library are designed to answer queries about the rank of an item in the stream of items. That is, when +applying a global ordering on all the items, what is the portion of items seen so far that are less than (alternatively, +less-than-or-equal-to) the given item. Using straightforward logic, they can also estimate the item at a given rank +in the stream.

+

These sketches may be used to compute approximate histograms, Probability Mass Functions (PMFs), or +Cumulative Distribution Functions (CDFs).

+

The library provides three types of quantiles sketches, each of which has generic items as well as versions +specific to a given numeric type (e.g. integer or floating point values). All three types provide error +bounds on rank estimation with proven probabilistic error distributions.

+
+
    +
  • KLL: Provides uniform rank estimation error over the entire range

  • +
  • REQ: Provides relative rank error estimates, which decreases approaching either the high or low end values.

  • +
  • Classic quantiles: Largely deprecated in favor of KLL, also provides uniform rank estimation error. Included largely for backwards compatibility with historic data.

  • +
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.0/quantiles/kll.html b/docs/5.0.0/quantiles/kll.html new file mode 100644 index 00000000..0dc2a14b --- /dev/null +++ b/docs/5.0.0/quantiles/kll.html @@ -0,0 +1,964 @@ + + + + + + + KLL Sketch — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

KLL Sketch

+

Implementation of a very compact quantiles sketch with lazy compaction scheme +and nearly optimal accuracy per retained item. +See Optimal Quantile Approximation in Streams.

+

This is a stochastic streaming sketch that enables near real-time analysis of the +approximate distribution of items from a very large stream in a single pass, requiring only +that the items are comparable. +The analysis is obtained using get_quantile() function or the +inverse functions get_rank(), get_pmf() (Probability Mass Function), and get_cdf() +(Cumulative Distribution Function).

+

As of May 2020, this implementation produces serialized sketches which are binary-compatible +with the equivalent Java implementation only when template parameter T = float +(32-bit single precision values).

+

Given an input stream of N items, the natural rank of any specific +item is defined as its index (1 to N) in inclusive mode +or (0 to N-1) in exclusive mode +in the hypothetical sorted stream of all N input items.

+

The normalized rank (rank) of any specific item is defined as its +natural rank divided by N. +Thus, the normalized rank is between zero and one. +In the documentation for this sketch natural rank is never used so any +reference to just rank should be interpreted to mean normalized rank.

+

This sketch is configured with a parameter k, which affects the size of the sketch +and its estimation error.

+

The estimation error is commonly called epsilon (or eps) and is a fraction +between zero and one. Larger values of k result in smaller values of epsilon. +Epsilon is always with respect to the rank and cannot be applied to the +corresponding items.

+

The relationship between the normalized rank and the corresponding items can be viewed +as a two-dimensional monotonic plot with the normalized rank on one axis and the +corresponding items on the other axis. If the y-axis is specified as the item-axis and +the x-axis as the normalized rank, then y = get_quantile(x) is a monotonically +increasing function.

+

The function get_quantile(rank) translates ranks into +corresponding quantiles. The functions get_rank(item), +get_cdf(…) (Cumulative Distribution Function), and get_pmf(…) +(Probability Mass Function) perform the opposite operation and translate items into ranks.

+

The get_pmf(…) function has about 13 to 47% worse rank error (depending +on k) than the other queries because the mass of each “bin” of the PMF has +“double-sided” error from the upper and lower edges of the bin as a result of a subtraction, +as the errors from the two edges can sometimes add.

+

The default k of 200 yields a “single-sided” epsilon of about 1.33% and a +“double-sided” (PMF) epsilon of about 1.65%.

+

A get_quantile(rank) query has the following guarantees: +- Let q = get_quantile(r) where r is the rank between zero and one. +- The quantile q will be an item from the input stream. +- Let true_rank be the true rank of q derived from the hypothetical sorted +stream of all N items. +- Let eps = get_normalized_rank_error(false). +- Then r - eps ≤ true_rank ≤ r + eps with a confidence of 99%. Note that the +error is on the rank, not the quantile.

+

A get_rank(item) query has the following guarantees: +- Let r = get_rank(i) where i is an item between the min and max items of +the input stream. +- Let true_rank be the true rank of i derived from the hypothetical sorted +stream of all N items. +- Let eps = get_normalized_rank_error(false). +- Then r - eps ≤ true_rank ≤ r + eps with a confidence of 99%.

+

A get_pmf() query has the following guarantees: +- Let {r1, r2, …, r(m+1)} = get_pmf(s1, s2, …, sm) where s1, s2 are +split points (items from the input domain) between the min and max items of +the input stream. +- Let mass_i = estimated mass between s_i and s_i+1. +- Let true_mass be the true mass between the items of s_i, +s_i+1 derived from the hypothetical sorted stream of all N items. +- Let eps = get_normalized_rank_error(true). +- then mass - eps ≤ true_mass ≤ mass + eps with a confidence of 99%. +- r(m+1) includes the mass of all points larger than s_m.

+

A get_cdf(…) query has the following guarantees; +- Let {r1, r2, …, r(m+1)} = get_cdf(s1, s2, …, sm) where s1, s2, … are +split points (items from the input domain) between the min and max items of +the input stream. +- Let mass_i = r_(i+1) - r_i. +- Let true_mass be the true mass between the true ranks of s_i, +s_i+1 derived from the hypothetical sorted stream of all N items. +- Let eps = get_normalized_rank_error(true). +- then mass - eps ≤ true_mass ≤ mass + eps with a confidence of 99%. +- 1 - r(m+1) includes the mass of all points larger than s_m.

+

From the above, it might seem like we could make some estimates to bound the +item returned from a call to get_quantile(). The sketch, however, does not +let us derive error bounds or confidences around items. Because errors are independent, we +can approximately bracket a value as shown below, but there are no error estimates available. +Additionally, the interval may be quite large for certain distributions. +- Let q = get_quantile(r), the estimated quantile of rank r. +- Let eps = get_normalized_rank_error(false). +- Let q_lo = estimated quantile of rank (r - eps). +- Let q_hi = estimated quantile of rank (r + eps). +- Then q_lo ≤ q ≤ q_hi, with 99% confidence.

+
+

Note

+

For the kll_items_sketch, objects must be comparable with __lt__.

+
+
+

Note

+

Serializing and deserializing a kll_items_sketch requires the use of a PyObjectSerDe.

+
+
+
+class kll_ints_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.kll_ints_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 200) None
+

Creates a KLL sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 200.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given normalized rank in a hypothetical sorted version of the input stream so far. +For kll_floats_sketch: if the sketch is empty this returns nan. For kll_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: int) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=int32]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class kll_floats_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.kll_floats_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 200) None
+

Creates a KLL sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 200.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given normalized rank in a hypothetical sorted version of the input stream so far. +For kll_floats_sketch: if the sketch is empty this returns nan. For kll_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: float) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=float32]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class kll_doubles_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.kll_doubles_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 200) None
+

Creates a KLL sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 200.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given normalized rank in a hypothetical sorted version of the input stream so far. +For kll_floats_sketch: if the sketch is empty this returns nan. For kll_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: float) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=float64]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class kll_items_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe) _datasketches.kll_items_sketch
+

Deserializes the sketch from a bytes object using the provided serde.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 200) None
+

Creates a KLL sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 200.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given normalized rank in a hypothetical sorted version of the input stream so far. +For kll_floats_sketch: if the sketch is empty this returns nan. For kll_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object using the provided serde.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Updates the sketch with the given value

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.0/quantiles/quantiles_depr.html b/docs/5.0.0/quantiles/quantiles_depr.html new file mode 100644 index 00000000..e63e9176 --- /dev/null +++ b/docs/5.0.0/quantiles/quantiles_depr.html @@ -0,0 +1,903 @@ + + + + + + + Quantiles Sketch (Deprecated) — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Quantiles Sketch (Deprecated)

+

This is a deprecated quantiles sketch that is included for cross-language compatibility. +Most new projects will favor the KLL sketch over this one, or the REQ sketch for higher accuracy +at the very edge of a distribution.

+

This is a stochastic streaming sketch that enables near-real time analysis of the +approximate distribution from a very large stream in a single pass. +The analysis is obtained using get_rank() and get_quantile() functions, +the Probability Mass Function from get_pmf()` and the Cumulative Distribution Function from get_cdf.

+

Consider a large stream of one million values such as packet sizes coming into a network node. +The natural rank of any specific size value is its index in the hypothetical sorted +array of values. +The normalized rank is the natural rank divided by the stream size, +in this case one million. +The value corresponding to the normalized rank of 0.5 represents the 50th percentile or median +value of the distribution, or get_quantile(0.5). +Similarly, the 95th percentile is obtained from get_quantile(0.95).

+

From the min and max values, for example, 1 and 1000 bytes, +you can obtain the PMF from get_pmf(100, 500, 900) that will result in an array of +4 fractional values such as {.4, .3, .2, .1}, which means that +40% of the values were < 100, +30% of the values were ≥ 100 and < 500, +20% of the values were ≥ 500 and < 900, and +10% of the values were ≥ 900. +A frequency histogram can be obtained by multiplying these fractions by get_n(), +which is the total count of values received. +The get_cdf()` works similarly, but produces the cumulative distribution instead.

+

As of November 2021, this implementation produces serialized sketches which are binary-compatible +with the equivalent Java implementation only when template parameter T = double +(64-bit double precision values).

+

The accuracy of this sketch is a function of the configured value k, which also affects +the overall size of the sketch. Accuracy of this quantile sketch is always with respect to +the normalized rank. A k of 128 produces a normalized, rank error of about 1.7%. +For example, the median item returned from get_quantile(0.5) will be between the actual items +from the hypothetically sorted array of input items at normalized ranks of 0.483 and 0.517, with +a confidence of about 99%.

+
+

Note

+

For the quantiles_items_sketch, objects must be comparable with __lt__.

+
+
+

Note

+

Serializing and deserializing a quantiles_items_sketch requires the use of a PyObjectSerDe.

+
+
+
+class quantiles_ints_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.quantiles_ints_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 128) None
+

Creates a classic quantiles sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 128.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given rank in a hypothetical sorted version of the input stream so far. +For quantiles_floats_sketch: if the sketch is empty this returns nan. For quantiles_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: int) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=int32]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class quantiles_floats_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.quantiles_floats_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 128) None
+

Creates a classic quantiles sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 128.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given rank in a hypothetical sorted version of the input stream so far. +For quantiles_floats_sketch: if the sketch is empty this returns nan. For quantiles_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: float) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=float32]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class quantiles_doubles_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.quantiles_doubles_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 128) None
+

Creates a classic quantiles sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 128.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given rank in a hypothetical sorted version of the input stream so far. +For quantiles_floats_sketch: if the sketch is empty this returns nan. For quantiles_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: float) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=float64]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class quantiles_items_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe) _datasketches.quantiles_items_sketch
+

Deserializes the sketch from a bytes object using the provided serde.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 128) None
+

Creates a classic quantiles sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 128.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given rank in a hypothetical sorted version of the input stream so far. +For quantiles_floats_sketch: if the sketch is empty this returns nan. For quantiles_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object using the provided serde.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Updates the sketch with the given value

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.0/quantiles/req.html b/docs/5.0.0/quantiles/req.html new file mode 100644 index 00000000..7ece205d --- /dev/null +++ b/docs/5.0.0/quantiles/req.html @@ -0,0 +1,754 @@ + + + + + + + Relative Error Quantiles (REQ) Sketch — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Relative Error Quantiles (REQ) Sketch

+

This is an implementation based on the paper “Relative Error Streaming Quantiles” by Graham Cormode, Zohar Karnin, Edo Liberty, Justin Thaler, Pavel Veselý, and loosely derived from a Python prototype written by Pavel Veselý.

+

This implementation differs from the algorithm described in the paper in the following:

+

The algorithm requires no upper bound on the stream length. +Instead, each relative-compactor counts the number of compaction operations performed so far (via variable state). +Initially, the relative-compactor starts with INIT_NUMBER_OF_SECTIONS. +Each time the number of compactions (variable state) exceeds 2^{numSections - 1}, we double numSections. +Note that after merging the sketch with another one variable state may not correspond to the number of compactions performed at a particular level, however, +since the state variable never exceeds the number of compactions, the guarantees of the sketch remain valid.

+

The size of each section (variable k and section_size in the code and parameter k in the paper) is +initialized with a number set by the user via variable k. +When the number of sections doubles, we decrease section_size by a factor of sqrt(2). +This is applied at each level separately. +Thus, when we double the number of sections, the nominal compactor size increases by a factor of approx. sqrt(2) (+/- rounding).

+

The merge operation here does not perform “special compactions”, which are used in the paper to allow for a tight mathematical analysis of the sketch. +This implementation provides a number of capabilities not discussed in the paper or provided in the Python prototype.

+

The Python prototype only implemented high accuracy for low ranks. This implementation provides the user with the ability to +choose either high rank accuracy or low rank accuracy at the time of sketch construction. +The Python prototype only implemented a comparison criterion of INCLUSIVE. +This implementation allows the user to use both the INCLUSIVE criterion and the EXCLUSIVE criterion. +This implementation provides extensive debug visibility into the operation of the sketch with two levels of detail output. +This is not only useful for debugging, but is a powerful tool to help users understand how the sketch works.

+
+

Note

+

For the req_items_sketch, objects must be comparable with __lt__.

+
+
+

Note

+

Serializing and deserializing a req_items_sketch requires the use of a PyObjectSerDe.

+
+
+
+class req_ints_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.req_ints_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_RSE(k: int, rank: float, is_hra: bool, n: int) float
+

Returns an a priori estimate of relative standard error (RSE, expressed as a number in [0,1]). Derived from Lemma 12 in http://arxiv.org/abs/2004.01668v2, but the constant factors have been modified based on empirical measurements, for a given value of parameter k. +Normalized rank must be a value between 0.0 and 1.0 (inclusive). If is_hra is True, uses high rank accuracy mode, else low rank accuracy. N is an estimate of the total number of points provided to the sketch.

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 12, is_hra: bool = True) None
+

Creates an REQ sketch instance with the given value of k.

+
+
Parameters:
+
    +
  • k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 12.

  • +
  • is_hra (bool, optional) – Specifies whether the skech has High Rank Accuracy (True) or Low Rank Accuracy. Default True.

  • +
+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, req_floats_sketch returns nan; req_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, req_floats_sketch returns nan; req_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given normalized rank in a hypothetical sorted version of the input stream so far. +For req_floats_sketch: if the sketch is empty this returns nan. For req_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+get_rank_lower_bound
+

Returns an approximate lower bound on the given normalized rank. +Normalized rank must be a value between 0.0 and 1.0 (inclusive); the number of standard deviations must be 1, 2, or 3.

+
+ +
+
+get_rank_upper_bound
+

Returns an approximate upper bound on the given normalized rank. +Normalized rank must be a value between 0.0 and 1.0 (inclusive); the number of standard deviations must be 1, 2, or 3.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+is_hra
+

Returns True if the sketch is in High Rank Accuracy mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: int) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=int32]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class req_floats_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.req_floats_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_RSE(k: int, rank: float, is_hra: bool, n: int) float
+

Returns an a priori estimate of relative standard error (RSE, expressed as a number in [0,1]). Derived from Lemma 12 in http://arxiv.org/abs/2004.01668v2, but the constant factors have been modified based on empirical measurements, for a given value of parameter k. +Normalized rank must be a value between 0.0 and 1.0 (inclusive). If is_hra is True, uses high rank accuracy mode, else low rank accuracy. N is an estimate of the total number of points provided to the sketch.

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 12, is_hra: bool = True) None
+

Creates an REQ sketch instance with the given value of k.

+
+
Parameters:
+
    +
  • k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 12.

  • +
  • is_hra (bool, optional) – Specifies whether the skech has High Rank Accuracy (True) or Low Rank Accuracy. Default True.

  • +
+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, req_floats_sketch returns nan; req_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, req_floats_sketch returns nan; req_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given normalized rank in a hypothetical sorted version of the input stream so far. +For req_floats_sketch: if the sketch is empty this returns nan. For req_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+get_rank_lower_bound
+

Returns an approximate lower bound on the given normalized rank. +Normalized rank must be a value between 0.0 and 1.0 (inclusive); the number of standard deviations must be 1, 2, or 3.

+
+ +
+
+get_rank_upper_bound
+

Returns an approximate upper bound on the given normalized rank. +Normalized rank must be a value between 0.0 and 1.0 (inclusive); the number of standard deviations must be 1, 2, or 3.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+is_hra
+

Returns True if the sketch is in High Rank Accuracy mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: float) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=float32]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class req_items_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe) _datasketches.req_items_sketch
+

Deserializes the sketch from a bytes object using the provided serde.

+
+ +
+
+get_RSE(k: int, rank: float, is_hra: bool, n: int) float
+

Returns an a priori estimate of relative standard error (RSE, expressed as a number in [0,1]). Derived from Lemma 12 in http://arxiv.org/abs/2004.01668v2, but the constant factors have been modified based on empirical measurements, for a given value of parameter k. +Normalized rank must be a value between 0.0 and 1.0 (inclusive). If is_hra is True, uses high rank accuracy mode, else low rank accuracy. N is an estimate of the total number of points provided to the sketch.

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 12, is_hra: bool = True) None
+

Creates an REQ sketch instance with the given value of k.

+
+
Parameters:
+
    +
  • k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 12.

  • +
  • is_hra (bool, optional) – Specifies whether the skech has High Rank Accuracy (True) or Low Rank Accuracy. Default True.

  • +
+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, req_floats_sketch returns nan; req_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, req_floats_sketch returns nan; req_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given normalized rank in a hypothetical sorted version of the input stream so far. +For req_floats_sketch: if the sketch is empty this returns nan. For req_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+get_rank_lower_bound
+

Returns an approximate lower bound on the given normalized rank. +Normalized rank must be a value between 0.0 and 1.0 (inclusive); the number of standard deviations must be 1, 2, or 3.

+
+ +
+
+get_rank_upper_bound
+

Returns an approximate upper bound on the given normalized rank. +Normalized rank must be a value between 0.0 and 1.0 (inclusive); the number of standard deviations must be 1, 2, or 3.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+is_hra
+

Returns True if the sketch is in High Rank Accuracy mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object using the provided serde.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Updates the sketch with the given value

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.0/sampling/ebpps.html b/docs/5.0.0/sampling/ebpps.html new file mode 100644 index 00000000..07b97185 --- /dev/null +++ b/docs/5.0.0/sampling/ebpps.html @@ -0,0 +1,238 @@ + + + + + + + Exact and Bounded, Probabilitiy Proportional to Size (EBPPS) Sampling — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Exact and Bounded, Probabilitiy Proportional to Size (EBPPS) Sampling

+

An EBPPS sketch produces a randome sample of data from a stream of items, ensuring that the probability +of including an item is always exactly equal to the item’s size. The size of an item is defined as its +weight relative to the total weight of all items seen so far by the sketch. In contrast to VarOpt sampling, +this sketch may return fewer than k items in order to keep the probability of including an item strictly +proportional to its size.

+

This sketch is based on: B. Hentschel, P. J. Haas, Y. Tian +“Exact PPS Sampling with Bounded Sample Size”, +Information Processing Letters, 2023.

+

EBPPS sampling is related to reservoir sampling, but handles unequal item weights. +Feeding the sketch items with a uniform weight value will produce a sample equivalent to reservoir sampling.

+
+

Note

+

Serializing and deserializing this sketch requires the use of a PyObjectSerDe.

+
+
+
+class ebpps_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe) _datasketches.ebpps_sketch
+

Reads a bytes object and returns the corresponding ebpps_sketch

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int) None
+

Creates a new EBPPS sketch instance

+
+
Parameters:
+

k (int) – Maximum number of samples in the sketch

+
+
+
+ +
+
+property c
+

The expected number of samples returned upon a call to get_result() or the creation of an iterator. The number is a floating point value, where the fractional portion represents the probability of including a “partial item” from the sample. The value C should be no larger than the sketch’s configured value of k, although numerical precision limitations mean it may exceed k by double precision floating point error margins in certain cases.

+
+ +
+
+get_serialized_size_bytes
+

Computes the size in bytes needed to serialize the current sketch

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+property k
+

The sketch’s maximum configured sample size

+
+ +
+
+merge
+

Merges the sketch with the given sketch

+
+ +
+
+property n
+

The total stream length

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object

+
+ +
+
+to_string
+

Produces a string summary of the sketch and optionally prints the items

+
+ +
+
+update
+

Updates the sketch with the given value and weight

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.0/sampling/index.html b/docs/5.0.0/sampling/index.html new file mode 100644 index 00000000..7cc2cb53 --- /dev/null +++ b/docs/5.0.0/sampling/index.html @@ -0,0 +1,147 @@ + + + + + + + Random Sampling Sketches — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Random Sampling Sketches

+

These sketches are used to randomly sample items. The length of the input +stream does not need to be known in advance.

+

Both VarOpt (Variance Optimal) and EBPPS (Exact and Bounded, +Probability Proportional to Size) sketches will include sample items based on +each item’s weight relative to the weight of the entire stream but +they differ in details:

+
+
    +
  • ebpps_sketch ensures that the probability of including an item is always exactly proportional to the item’s weight.

  • +
  • var_opt_sketch optimizes for applying a predicate to the resulting sample such that the variance of the subset sum after applying the predicate is minimized, even if the inclusion probability differs somewhat from being proportional to the item’s weight.

  • +
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.0/sampling/varopt.html b/docs/5.0.0/sampling/varopt.html new file mode 100644 index 00000000..1b3889f6 --- /dev/null +++ b/docs/5.0.0/sampling/varopt.html @@ -0,0 +1,300 @@ + + + + + + + Variance Optimal Sampling (VarOpt) — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Variance Optimal Sampling (VarOpt)

+

A VarOpt sketch samples data from a stream of items. The sketch is desinged for optimal (minimum) +variance when querying the sketch to estimate subset sums of items matching a provided predicate. +The sketch will produce a sample of size k (or smaller if fewer items have been presented), with +the probability of including an item roughly corresponding it the item’s weight relative to the total +weight of all items presented to the sketch.

+

VarOpt sampling is related to reservoir sampling, with improved error bounds for subset sum estimation. +Feeding the sketch items with a uniform weight value will produce a sample equivalent to reservoir sampling.

+
+

Note

+

Serializing and deserializing this sketch requires the use of a PyObjectSerDe.

+
+
+
+class var_opt_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe) _datasketches.var_opt_sketch
+

Reads a bytes object and returns the corresponding var opt sketch

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int) None
+

Creates a new Var Opt sketch instance

+
+
Parameters:
+

k (int) – Maximum number of samples in the sketch

+
+
+
+ +
+
+estimate_subset_sum
+

Applies a provided predicate to the sketch and returns the estimated total weight matching the predicate, as well as upper and lower bounds on the estimate and the total weight processed by the sketch

+
+ +
+
+get_serialized_size_bytes
+

Computes the size in bytes needed to serialize the current sketch

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+property k
+

Returns the sketch’s maximum configured sample size

+
+ +
+
+property n
+

Returns the total stream length

+
+ +
+
+property num_samples
+

Returns the number of samples currently in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object

+
+ +
+
+to_string
+

Produces a string summary of the sketch and optionally prints the items

+
+ +
+
+update
+

Updates the sketch with the given value and weight

+
+ +
+ +
+
+class var_opt_union(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe) _datasketches.var_opt_union
+

Constructs a var opt union from the given bytes using the provided serde

+
+ +

Non-static Methods:

+
+
+__init__(self, max_k: int) None
+
+ +
+
+get_result
+

Returns a sketch corresponding to the union result

+
+ +
+
+get_serialized_size_bytes
+

Computes the size in bytes needed to serialize the current union

+
+ +
+
+reset
+

Resets the union to the empty state

+
+ +
+
+serialize
+

Serializes the union into a bytes object with the provided serde

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Updates the union with the given sketch

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.0/search.html b/docs/5.0.0/search.html new file mode 100644 index 00000000..21031339 --- /dev/null +++ b/docs/5.0.0/search.html @@ -0,0 +1,136 @@ + + + + + + Search — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ + + + +
+ +
+ +
+
+ +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/docs/5.0.0/searchindex.js b/docs/5.0.0/searchindex.js new file mode 100644 index 00000000..5206d48d --- /dev/null +++ b/docs/5.0.0/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"alltitles": {"Apache DataSketches": [[14, "apache-datasketches"]], "Compressed Probabilistic Counting (CPC)": [[0, "compressed-probabilistic-counting-cpc"]], "CountMin Sketch": [[5, "countmin-sketch"]], "Counting Distincts": [[14, "counting-distincts"]], "Density Sketch": [[22, "density-sketch"]], "Distinct Counting": [[2, "distinct-counting"]], "Exact and Bounded, Probabilitiy Proportional to Size (EBPPS) Sampling": [[19, "exact-and-bounded-probabilitiy-proportional-to-size-ebpps-sampling"]], "Frequency Sketches": [[7, "frequency-sketches"], [14, "frequency-sketches"]], "Frequent Items": [[6, "frequent-items"]], "Helper Classes": [[8, "helper-classes"], [14, "helper-classes"]], "HyperLogLog (HLL)": [[1, "hyperloglog-hll"]], "Indices and tables": [[14, "indices-and-tables"]], "Jaccard Similarity": [[9, "jaccard-similarity"]], "KLL Sketch": [[16, "kll-sketch"]], "Kernel Function": [[10, "kernel-function"]], "Kolmogorov-Smirnov Test": [[11, "kolmogorov-smirnov-test"]], "Quantile Estimation": [[14, "quantile-estimation"]], "Quantiles Sketch (Deprecated)": [[17, "quantiles-sketch-deprecated"]], "Quantiles Sketches": [[15, "quantiles-sketches"]], "Random Sampling": [[14, "random-sampling"]], "Random Sampling Sketches": [[20, "random-sampling-sketches"]], "Relative Error Quantiles (REQ) Sketch": [[18, "relative-error-quantiles-req-sketch"]], "Serialize/Deserialize (SerDe)": [[12, "serialize-deserialize-serde"]], "Theta Sketch": [[3, "theta-sketch"]], "Tuple Policy": [[13, "tuple-policy"]], "Tuple Sketch": [[4, "tuple-sketch"]], "Variance Optimal Sampling (VarOpt)": [[21, "variance-optimal-sampling-varopt"]], "Vector Sketches": [[14, "vector-sketches"], [23, "vector-sketches"]]}, "docnames": ["distinct_counting/cpc", "distinct_counting/hyper_log_log", "distinct_counting/index", "distinct_counting/theta", "distinct_counting/tuple", "frequency/count_min_sketch", "frequency/frequent_items", "frequency/index", "helper/index", "helper/jaccard", "helper/kernel", "helper/ks_test", "helper/serde", "helper/tuple_policy", "index", "quantiles/index", "quantiles/kll", "quantiles/quantiles_depr", "quantiles/req", "sampling/ebpps", "sampling/index", "sampling/varopt", "vector/density_sketch", "vector/index"], "envversion": {"sphinx": 61, "sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2}, "filenames": ["distinct_counting/cpc.rst", "distinct_counting/hyper_log_log.rst", "distinct_counting/index.rst", "distinct_counting/theta.rst", "distinct_counting/tuple.rst", "frequency/count_min_sketch.rst", "frequency/frequent_items.rst", "frequency/index.rst", "helper/index.rst", "helper/jaccard.rst", "helper/kernel.rst", "helper/ks_test.rst", "helper/serde.rst", "helper/tuple_policy.rst", "index.rst", "quantiles/index.rst", "quantiles/kll.rst", "quantiles/quantiles_depr.rst", "quantiles/req.rst", "sampling/ebpps.rst", "sampling/index.rst", "sampling/varopt.rst", "vector/density_sketch.rst", "vector/index.rst"], "indexentries": {"__call__() (kernelfunction method)": [[10, "datasketches.KernelFunction.__call__", false]], "__call__() (tuplepolicy method)": [[13, "datasketches.TuplePolicy.__call__", false]], "__init__() (compact_theta_sketch method)": [[3, "datasketches.compact_theta_sketch.__init__", false]], "__init__() (compact_tuple_sketch method)": [[4, "datasketches.compact_tuple_sketch.__init__", false]], "__init__() (cpc_sketch method)": [[0, "datasketches.cpc_sketch.__init__", false]], "__init__() (cpc_union method)": [[0, "datasketches.cpc_union.__init__", false]], "__init__() (density_sketch method)": [[22, "datasketches.density_sketch.__init__", false]], "__init__() (ebpps_sketch method)": [[19, "datasketches.ebpps_sketch.__init__", false]], "__init__() (frequent_items_sketch method)": [[6, "datasketches.frequent_items_sketch.__init__", false]], "__init__() (frequent_strings_sketch method)": [[6, "datasketches.frequent_strings_sketch.__init__", false]], "__init__() (hll_sketch method)": [[1, "datasketches.hll_sketch.__init__", false]], "__init__() (hll_union method)": [[1, "datasketches.hll_union.__init__", false]], "__init__() (kll_doubles_sketch method)": [[16, "datasketches.kll_doubles_sketch.__init__", false]], "__init__() (kll_floats_sketch method)": [[16, "datasketches.kll_floats_sketch.__init__", false]], "__init__() (kll_ints_sketch method)": [[16, "datasketches.kll_ints_sketch.__init__", false]], "__init__() (kll_items_sketch method)": [[16, "datasketches.kll_items_sketch.__init__", false]], "__init__() (quantiles_doubles_sketch method)": [[17, "datasketches.quantiles_doubles_sketch.__init__", false]], "__init__() (quantiles_floats_sketch method)": [[17, "datasketches.quantiles_floats_sketch.__init__", false]], "__init__() (quantiles_ints_sketch method)": [[17, "datasketches.quantiles_ints_sketch.__init__", false]], "__init__() (quantiles_items_sketch method)": [[17, "datasketches.quantiles_items_sketch.__init__", false]], "__init__() (req_floats_sketch method)": [[18, "datasketches.req_floats_sketch.__init__", false]], "__init__() (req_ints_sketch method)": [[18, "datasketches.req_ints_sketch.__init__", false]], "__init__() (req_items_sketch method)": [[18, "datasketches.req_items_sketch.__init__", false]], "__init__() (theta_a_not_b method)": [[3, "datasketches.theta_a_not_b.__init__", false]], "__init__() (theta_intersection method)": [[3, "datasketches.theta_intersection.__init__", false]], "__init__() (theta_union method)": [[3, "datasketches.theta_union.__init__", false]], "__init__() (tuple_a_not_b method)": [[4, "datasketches.tuple_a_not_b.__init__", false]], "__init__() (tuple_intersection method)": [[4, "datasketches.tuple_intersection.__init__", false]], "__init__() (tuple_union method)": [[4, "datasketches.tuple_union.__init__", false]], "__init__() (update_theta_sketch method)": [[3, "datasketches.update_theta_sketch.__init__", false]], "__init__() (update_tuple_sketch method)": [[4, "datasketches.update_tuple_sketch.__init__", false]], "__init__() (var_opt_sketch method)": [[21, "datasketches.var_opt_sketch.__init__", false]], "__init__() (var_opt_union method)": [[21, "datasketches.var_opt_union.__init__", false]], "accumulatorpolicy (class in datasketches)": [[13, "datasketches.AccumulatorPolicy", false]], "c (ebpps_sketch property)": [[19, "datasketches.ebpps_sketch.c", false]], "compact (update_theta_sketch attribute)": [[3, "datasketches.update_theta_sketch.compact", false]], "compact (update_tuple_sketch attribute)": [[4, "datasketches.update_tuple_sketch.compact", false]], "compact_theta_sketch (class in datasketches)": [[3, "datasketches.compact_theta_sketch", false]], "compact_tuple_sketch (class in datasketches)": [[4, "datasketches.compact_tuple_sketch", false]], "compute (theta_a_not_b attribute)": [[3, "datasketches.theta_a_not_b.compute", false]], "compute (tuple_a_not_b attribute)": [[4, "datasketches.tuple_a_not_b.compute", false]], "count_min_sketch (class in _datasketches)": [[5, "datasketches.count_min_sketch", false]], "cpc_sketch (class in _datasketches)": [[0, "datasketches.cpc_sketch", false]], "cpc_union (class in _datasketches)": [[0, "datasketches.cpc_union", false]], "create_summary() (tuplepolicy method)": [[13, "datasketches.TuplePolicy.create_summary", false]], "default_seed (tuple_sketch attribute)": [[4, "datasketches.tuple_sketch.DEFAULT_SEED", false]], "density_sketch (class in datasketches)": [[22, "datasketches.density_sketch", false]], "deserialize() (compact_theta_sketch method)": [[3, "datasketches.compact_theta_sketch.deserialize", false]], "deserialize() (compact_tuple_sketch method)": [[4, "datasketches.compact_tuple_sketch.deserialize", false]], "deserialize() (count_min_sketch method)": [[5, "datasketches.count_min_sketch.deserialize", false]], "deserialize() (cpc_sketch method)": [[0, "datasketches.cpc_sketch.deserialize", false]], "deserialize() (density_sketch method)": [[22, "datasketches.density_sketch.deserialize", false]], "deserialize() (ebpps_sketch method)": [[19, "datasketches.ebpps_sketch.deserialize", false]], "deserialize() (frequent_items_sketch method)": [[6, "datasketches.frequent_items_sketch.deserialize", false]], "deserialize() (frequent_strings_sketch method)": [[6, "datasketches.frequent_strings_sketch.deserialize", false]], "deserialize() (hll_sketch method)": [[1, "datasketches.hll_sketch.deserialize", false]], "deserialize() (kll_doubles_sketch method)": [[16, "datasketches.kll_doubles_sketch.deserialize", false]], "deserialize() (kll_floats_sketch method)": [[16, "datasketches.kll_floats_sketch.deserialize", false]], "deserialize() (kll_ints_sketch method)": [[16, "datasketches.kll_ints_sketch.deserialize", false]], "deserialize() (kll_items_sketch method)": [[16, "datasketches.kll_items_sketch.deserialize", false]], "deserialize() (quantiles_doubles_sketch method)": [[17, "datasketches.quantiles_doubles_sketch.deserialize", false]], "deserialize() (quantiles_floats_sketch method)": [[17, "datasketches.quantiles_floats_sketch.deserialize", false]], "deserialize() (quantiles_ints_sketch method)": [[17, "datasketches.quantiles_ints_sketch.deserialize", false]], "deserialize() (quantiles_items_sketch method)": [[17, "datasketches.quantiles_items_sketch.deserialize", false]], "deserialize() (req_floats_sketch method)": [[18, "datasketches.req_floats_sketch.deserialize", false]], "deserialize() (req_ints_sketch method)": [[18, "datasketches.req_ints_sketch.deserialize", false]], "deserialize() (req_items_sketch method)": [[18, "datasketches.req_items_sketch.deserialize", false]], "deserialize() (var_opt_sketch method)": [[21, "datasketches.var_opt_sketch.deserialize", false]], "deserialize() (var_opt_union method)": [[21, "datasketches.var_opt_union.deserialize", false]], "dim (density_sketch property)": [[22, "datasketches.density_sketch.dim", false]], "dissimilarity_test() (theta_jaccard_similarity method)": [[9, "datasketches.theta_jaccard_similarity.dissimilarity_test", false]], "dissimilarity_test() (tuple_jaccard_similarity method)": [[9, "datasketches.tuple_jaccard_similarity.dissimilarity_test", false]], "ebpps_sketch (class in datasketches)": [[19, "datasketches.ebpps_sketch", false]], "epsilon (frequent_items_sketch property)": [[6, "datasketches.frequent_items_sketch.epsilon", false]], "epsilon (frequent_strings_sketch property)": [[6, "datasketches.frequent_strings_sketch.epsilon", false]], "estimate_subset_sum (var_opt_sketch attribute)": [[21, "datasketches.var_opt_sketch.estimate_subset_sum", false]], "exactly_equal() (theta_jaccard_similarity method)": [[9, "datasketches.theta_jaccard_similarity.exactly_equal", false]], "exactly_equal() (tuple_jaccard_similarity method)": [[9, "datasketches.tuple_jaccard_similarity.exactly_equal", false]], "frequent_items_error_type (class in datasketches)": [[6, "datasketches.frequent_items_error_type", false]], "frequent_items_sketch (class in datasketches)": [[6, "datasketches.frequent_items_sketch", false]], "frequent_strings_sketch (class in datasketches)": [[6, "datasketches.frequent_strings_sketch", false]], "from_bytes() (pyobjectserde method)": [[12, "datasketches.PyObjectSerDe.from_bytes", false]], "gaussiankernel (class in datasketches)": [[10, "datasketches.GaussianKernel", false]], "get_apriori_error() (frequent_items_sketch method)": [[6, "datasketches.frequent_items_sketch.get_apriori_error", false]], "get_apriori_error() (frequent_strings_sketch method)": [[6, "datasketches.frequent_strings_sketch.get_apriori_error", false]], "get_cdf (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.get_cdf", false]], "get_cdf (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.get_cdf", false]], "get_cdf (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.get_cdf", false]], "get_cdf (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.get_cdf", false]], "get_cdf (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.get_cdf", false]], "get_cdf (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.get_cdf", false]], "get_cdf (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.get_cdf", false]], "get_cdf (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.get_cdf", false]], "get_cdf (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.get_cdf", false]], "get_cdf (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.get_cdf", false]], "get_cdf (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.get_cdf", false]], "get_compact_serialization_bytes (hll_sketch attribute)": [[1, "datasketches.hll_sketch.get_compact_serialization_bytes", false]], "get_epsilon_for_lg_size() (frequent_items_sketch method)": [[6, "datasketches.frequent_items_sketch.get_epsilon_for_lg_size", false]], "get_epsilon_for_lg_size() (frequent_strings_sketch method)": [[6, "datasketches.frequent_strings_sketch.get_epsilon_for_lg_size", false]], "get_estimate (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.get_estimate", false]], "get_estimate (cpc_sketch attribute)": [[0, "datasketches.cpc_sketch.get_estimate", false]], "get_estimate (density_sketch attribute)": [[22, "datasketches.density_sketch.get_estimate", false]], "get_estimate (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.get_estimate", false]], "get_estimate (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.get_estimate", false]], "get_estimate (hll_sketch attribute)": [[1, "datasketches.hll_sketch.get_estimate", false]], "get_estimate (hll_union attribute)": [[1, "datasketches.hll_union.get_estimate", false]], "get_estimate (theta_sketch attribute)": [[3, "datasketches.theta_sketch.get_estimate", false]], "get_estimate (tuple_sketch attribute)": [[4, "datasketches.tuple_sketch.get_estimate", false]], "get_frequent_items (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.get_frequent_items", false]], "get_frequent_items (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.get_frequent_items", false]], "get_lower_bound (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.get_lower_bound", false]], "get_lower_bound (cpc_sketch attribute)": [[0, "datasketches.cpc_sketch.get_lower_bound", false]], "get_lower_bound (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.get_lower_bound", false]], "get_lower_bound (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.get_lower_bound", false]], "get_lower_bound (hll_sketch attribute)": [[1, "datasketches.hll_sketch.get_lower_bound", false]], "get_lower_bound (hll_union attribute)": [[1, "datasketches.hll_union.get_lower_bound", false]], "get_lower_bound (theta_sketch attribute)": [[3, "datasketches.theta_sketch.get_lower_bound", false]], "get_lower_bound (tuple_sketch attribute)": [[4, "datasketches.tuple_sketch.get_lower_bound", false]], "get_max_updatable_serialization_bytes() (hll_sketch method)": [[1, "datasketches.hll_sketch.get_max_updatable_serialization_bytes", false]], "get_max_value (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.get_max_value", false]], "get_max_value (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.get_max_value", false]], "get_max_value (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.get_max_value", false]], "get_max_value (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.get_max_value", false]], "get_max_value (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.get_max_value", false]], "get_max_value (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.get_max_value", false]], "get_max_value (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.get_max_value", false]], "get_max_value (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.get_max_value", false]], "get_max_value (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.get_max_value", false]], "get_max_value (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.get_max_value", false]], "get_max_value (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.get_max_value", false]], "get_min_value (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.get_min_value", false]], "get_min_value (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.get_min_value", false]], "get_min_value (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.get_min_value", false]], "get_min_value (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.get_min_value", false]], "get_min_value (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.get_min_value", false]], "get_min_value (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.get_min_value", false]], "get_min_value (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.get_min_value", false]], "get_min_value (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.get_min_value", false]], "get_min_value (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.get_min_value", false]], "get_min_value (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.get_min_value", false]], "get_min_value (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.get_min_value", false]], "get_normalized_rank_error() (kll_doubles_sketch method)": [[16, "datasketches.kll_doubles_sketch.get_normalized_rank_error", false]], "get_normalized_rank_error() (kll_floats_sketch method)": [[16, "datasketches.kll_floats_sketch.get_normalized_rank_error", false]], "get_normalized_rank_error() (kll_ints_sketch method)": [[16, "datasketches.kll_ints_sketch.get_normalized_rank_error", false]], "get_normalized_rank_error() (kll_items_sketch method)": [[16, "datasketches.kll_items_sketch.get_normalized_rank_error", false]], "get_normalized_rank_error() (quantiles_doubles_sketch method)": [[17, "datasketches.quantiles_doubles_sketch.get_normalized_rank_error", false]], "get_normalized_rank_error() (quantiles_floats_sketch method)": [[17, "datasketches.quantiles_floats_sketch.get_normalized_rank_error", false]], "get_normalized_rank_error() (quantiles_ints_sketch method)": [[17, "datasketches.quantiles_ints_sketch.get_normalized_rank_error", false]], "get_normalized_rank_error() (quantiles_items_sketch method)": [[17, "datasketches.quantiles_items_sketch.get_normalized_rank_error", false]], "get_pmf (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.get_pmf", false]], "get_pmf (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.get_pmf", false]], "get_pmf (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.get_pmf", false]], "get_pmf (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.get_pmf", false]], "get_pmf (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.get_pmf", false]], "get_pmf (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.get_pmf", false]], "get_pmf (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.get_pmf", false]], "get_pmf (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.get_pmf", false]], "get_pmf (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.get_pmf", false]], "get_pmf (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.get_pmf", false]], "get_pmf (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.get_pmf", false]], "get_quantile (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.get_quantile", false]], "get_quantile (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.get_quantile", false]], "get_quantile (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.get_quantile", false]], "get_quantile (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.get_quantile", false]], "get_quantile (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.get_quantile", false]], "get_quantile (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.get_quantile", false]], "get_quantile (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.get_quantile", false]], "get_quantile (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.get_quantile", false]], "get_quantile (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.get_quantile", false]], "get_quantile (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.get_quantile", false]], "get_quantile (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.get_quantile", false]], "get_quantiles (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.get_quantiles", false]], "get_quantiles (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.get_quantiles", false]], "get_quantiles (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.get_quantiles", false]], "get_quantiles (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.get_quantiles", false]], "get_quantiles (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.get_quantiles", false]], "get_quantiles (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.get_quantiles", false]], "get_quantiles (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.get_quantiles", false]], "get_quantiles (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.get_quantiles", false]], "get_quantiles (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.get_quantiles", false]], "get_quantiles (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.get_quantiles", false]], "get_quantiles (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.get_quantiles", false]], "get_rank (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.get_rank", false]], "get_rank (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.get_rank", false]], "get_rank (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.get_rank", false]], "get_rank (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.get_rank", false]], "get_rank (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.get_rank", false]], "get_rank (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.get_rank", false]], "get_rank (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.get_rank", false]], "get_rank (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.get_rank", false]], "get_rank (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.get_rank", false]], "get_rank (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.get_rank", false]], "get_rank (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.get_rank", false]], "get_rank_lower_bound (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.get_rank_lower_bound", false]], "get_rank_lower_bound (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.get_rank_lower_bound", false]], "get_rank_lower_bound (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.get_rank_lower_bound", false]], "get_rank_upper_bound (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.get_rank_upper_bound", false]], "get_rank_upper_bound (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.get_rank_upper_bound", false]], "get_rank_upper_bound (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.get_rank_upper_bound", false]], "get_rel_err() (hll_sketch method)": [[1, "datasketches.hll_sketch.get_rel_err", false]], "get_rel_err() (hll_union method)": [[1, "datasketches.hll_union.get_rel_err", false]], "get_relative_error (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.get_relative_error", false]], "get_result (cpc_union attribute)": [[0, "datasketches.cpc_union.get_result", false]], "get_result (hll_union attribute)": [[1, "datasketches.hll_union.get_result", false]], "get_result (theta_intersection attribute)": [[3, "datasketches.theta_intersection.get_result", false]], "get_result (theta_union attribute)": [[3, "datasketches.theta_union.get_result", false]], "get_result (tuple_intersection attribute)": [[4, "datasketches.tuple_intersection.get_result", false]], "get_result (tuple_union attribute)": [[4, "datasketches.tuple_union.get_result", false]], "get_result (var_opt_union attribute)": [[21, "datasketches.var_opt_union.get_result", false]], "get_rse() (req_floats_sketch method)": [[18, "datasketches.req_floats_sketch.get_RSE", false]], "get_rse() (req_ints_sketch method)": [[18, "datasketches.req_ints_sketch.get_RSE", false]], "get_rse() (req_items_sketch method)": [[18, "datasketches.req_items_sketch.get_RSE", false]], "get_seed_hash (theta_sketch attribute)": [[3, "datasketches.theta_sketch.get_seed_hash", false]], "get_seed_hash (tuple_sketch attribute)": [[4, "datasketches.tuple_sketch.get_seed_hash", false]], "get_serialized_size_bytes (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.get_serialized_size_bytes", false]], "get_serialized_size_bytes (ebpps_sketch attribute)": [[19, "datasketches.ebpps_sketch.get_serialized_size_bytes", false]], "get_serialized_size_bytes (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.get_serialized_size_bytes", false]], "get_serialized_size_bytes (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.get_serialized_size_bytes", false]], "get_serialized_size_bytes (var_opt_sketch attribute)": [[21, "datasketches.var_opt_sketch.get_serialized_size_bytes", false]], "get_serialized_size_bytes (var_opt_union attribute)": [[21, "datasketches.var_opt_union.get_serialized_size_bytes", false]], "get_size() (pyobjectserde method)": [[12, "datasketches.PyObjectSerDe.get_size", false]], "get_updatable_serialization_bytes (hll_sketch attribute)": [[1, "datasketches.hll_sketch.get_updatable_serialization_bytes", false]], "get_upper_bound (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.get_upper_bound", false]], "get_upper_bound (cpc_sketch attribute)": [[0, "datasketches.cpc_sketch.get_upper_bound", false]], "get_upper_bound (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.get_upper_bound", false]], "get_upper_bound (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.get_upper_bound", false]], "get_upper_bound (hll_sketch attribute)": [[1, "datasketches.hll_sketch.get_upper_bound", false]], "get_upper_bound (hll_union attribute)": [[1, "datasketches.hll_union.get_upper_bound", false]], "get_upper_bound (theta_sketch attribute)": [[3, "datasketches.theta_sketch.get_upper_bound", false]], "get_upper_bound (tuple_sketch attribute)": [[4, "datasketches.tuple_sketch.get_upper_bound", false]], "has_result (theta_intersection attribute)": [[3, "datasketches.theta_intersection.has_result", false]], "has_result (tuple_intersection attribute)": [[4, "datasketches.tuple_intersection.has_result", false]], "hll_4 (tgt_hll_type attribute)": [[1, "datasketches.tgt_hll_type.HLL_4", false]], "hll_6 (tgt_hll_type attribute)": [[1, "datasketches.tgt_hll_type.HLL_6", false]], "hll_8 (tgt_hll_type attribute)": [[1, "datasketches.tgt_hll_type.HLL_8", false]], "hll_sketch (class in _datasketches)": [[1, "datasketches.hll_sketch", false]], "hll_union (class in _datasketches)": [[1, "datasketches.hll_union", false]], "is_compact (hll_sketch attribute)": [[1, "datasketches.hll_sketch.is_compact", false]], "is_empty (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.is_empty", false]], "is_empty (cpc_sketch attribute)": [[0, "datasketches.cpc_sketch.is_empty", false]], "is_empty (density_sketch attribute)": [[22, "datasketches.density_sketch.is_empty", false]], "is_empty (ebpps_sketch attribute)": [[19, "datasketches.ebpps_sketch.is_empty", false]], "is_empty (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.is_empty", false]], "is_empty (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.is_empty", false]], "is_empty (hll_sketch attribute)": [[1, "datasketches.hll_sketch.is_empty", false]], "is_empty (hll_union attribute)": [[1, "datasketches.hll_union.is_empty", false]], "is_empty (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.is_empty", false]], "is_empty (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.is_empty", false]], "is_empty (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.is_empty", false]], "is_empty (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.is_empty", false]], "is_empty (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.is_empty", false]], "is_empty (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.is_empty", false]], "is_empty (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.is_empty", false]], "is_empty (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.is_empty", false]], "is_empty (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.is_empty", false]], "is_empty (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.is_empty", false]], "is_empty (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.is_empty", false]], "is_empty (theta_sketch attribute)": [[3, "datasketches.theta_sketch.is_empty", false]], "is_empty (tuple_sketch attribute)": [[4, "datasketches.tuple_sketch.is_empty", false]], "is_empty (var_opt_sketch attribute)": [[21, "datasketches.var_opt_sketch.is_empty", false]], "is_estimation_mode (density_sketch attribute)": [[22, "datasketches.density_sketch.is_estimation_mode", false]], "is_estimation_mode (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.is_estimation_mode", false]], "is_estimation_mode (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.is_estimation_mode", false]], "is_estimation_mode (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.is_estimation_mode", false]], "is_estimation_mode (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.is_estimation_mode", false]], "is_estimation_mode (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.is_estimation_mode", false]], "is_estimation_mode (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.is_estimation_mode", false]], "is_estimation_mode (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.is_estimation_mode", false]], "is_estimation_mode (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.is_estimation_mode", false]], "is_estimation_mode (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.is_estimation_mode", false]], "is_estimation_mode (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.is_estimation_mode", false]], "is_estimation_mode (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.is_estimation_mode", false]], "is_estimation_mode (theta_sketch attribute)": [[3, "datasketches.theta_sketch.is_estimation_mode", false]], "is_estimation_mode (tuple_sketch attribute)": [[4, "datasketches.tuple_sketch.is_estimation_mode", false]], "is_hra (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.is_hra", false]], "is_hra (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.is_hra", false]], "is_hra (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.is_hra", false]], "is_ordered (theta_sketch attribute)": [[3, "datasketches.theta_sketch.is_ordered", false]], "is_ordered (tuple_sketch attribute)": [[4, "datasketches.tuple_sketch.is_ordered", false]], "jaccard() (theta_jaccard_similarity method)": [[9, "datasketches.theta_jaccard_similarity.jaccard", false]], "jaccard() (tuple_jaccard_similarity method)": [[9, "datasketches.tuple_jaccard_similarity.jaccard", false]], "k (density_sketch property)": [[22, "datasketches.density_sketch.k", false]], "k (ebpps_sketch property)": [[19, "datasketches.ebpps_sketch.k", false]], "k (kll_doubles_sketch property)": [[16, "datasketches.kll_doubles_sketch.k", false]], "k (kll_floats_sketch property)": [[16, "datasketches.kll_floats_sketch.k", false]], "k (kll_ints_sketch property)": [[16, "datasketches.kll_ints_sketch.k", false]], "k (kll_items_sketch property)": [[16, "datasketches.kll_items_sketch.k", false]], "k (quantiles_doubles_sketch property)": [[17, "datasketches.quantiles_doubles_sketch.k", false]], "k (quantiles_floats_sketch property)": [[17, "datasketches.quantiles_floats_sketch.k", false]], "k (quantiles_ints_sketch property)": [[17, "datasketches.quantiles_ints_sketch.k", false]], "k (quantiles_items_sketch property)": [[17, "datasketches.quantiles_items_sketch.k", false]], "k (req_floats_sketch property)": [[18, "datasketches.req_floats_sketch.k", false]], "k (req_ints_sketch property)": [[18, "datasketches.req_ints_sketch.k", false]], "k (req_items_sketch property)": [[18, "datasketches.req_items_sketch.k", false]], "k (var_opt_sketch property)": [[21, "datasketches.var_opt_sketch.k", false]], "kernelfunction (class in datasketches)": [[10, "datasketches.KernelFunction", false]], "kll_doubles_sketch (class in datasketches)": [[16, "datasketches.kll_doubles_sketch", false]], "kll_floats_sketch (class in datasketches)": [[16, "datasketches.kll_floats_sketch", false]], "kll_ints_sketch (class in datasketches)": [[16, "datasketches.kll_ints_sketch", false]], "kll_items_sketch (class in datasketches)": [[16, "datasketches.kll_items_sketch", false]], "ks_test() (in module datasketches)": [[11, "datasketches.ks_test", false]], "lg_config_k (hll_sketch property)": [[1, "datasketches.hll_sketch.lg_config_k", false]], "lg_config_k (hll_union property)": [[1, "datasketches.hll_union.lg_config_k", false]], "lg_k (cpc_sketch property)": [[0, "datasketches.cpc_sketch.lg_k", false]], "maxintpolicy (class in datasketches)": [[13, "datasketches.MaxIntPolicy", false]], "merge (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.merge", false]], "merge (density_sketch attribute)": [[22, "datasketches.density_sketch.merge", false]], "merge (ebpps_sketch attribute)": [[19, "datasketches.ebpps_sketch.merge", false]], "merge (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.merge", false]], "merge (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.merge", false]], "merge (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.merge", false]], "merge (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.merge", false]], "merge (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.merge", false]], "merge (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.merge", false]], "merge (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.merge", false]], "merge (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.merge", false]], "merge (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.merge", false]], "merge (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.merge", false]], "merge (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.merge", false]], "merge (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.merge", false]], "merge (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.merge", false]], "minintpolicy (class in datasketches)": [[13, "datasketches.MinIntPolicy", false]], "n (density_sketch property)": [[22, "datasketches.density_sketch.n", false]], "n (ebpps_sketch property)": [[19, "datasketches.ebpps_sketch.n", false]], "n (kll_doubles_sketch property)": [[16, "datasketches.kll_doubles_sketch.n", false]], "n (kll_floats_sketch property)": [[16, "datasketches.kll_floats_sketch.n", false]], "n (kll_ints_sketch property)": [[16, "datasketches.kll_ints_sketch.n", false]], "n (kll_items_sketch property)": [[16, "datasketches.kll_items_sketch.n", false]], "n (quantiles_doubles_sketch property)": [[17, "datasketches.quantiles_doubles_sketch.n", false]], "n (quantiles_floats_sketch property)": [[17, "datasketches.quantiles_floats_sketch.n", false]], "n (quantiles_ints_sketch property)": [[17, "datasketches.quantiles_ints_sketch.n", false]], "n (quantiles_items_sketch property)": [[17, "datasketches.quantiles_items_sketch.n", false]], "n (req_floats_sketch property)": [[18, "datasketches.req_floats_sketch.n", false]], "n (req_ints_sketch property)": [[18, "datasketches.req_ints_sketch.n", false]], "n (req_items_sketch property)": [[18, "datasketches.req_items_sketch.n", false]], "n (var_opt_sketch property)": [[21, "datasketches.var_opt_sketch.n", false]], "no_false_negatives (frequent_items_error_type attribute)": [[6, "datasketches.frequent_items_error_type.NO_FALSE_NEGATIVES", false]], "no_false_positives (frequent_items_error_type attribute)": [[6, "datasketches.frequent_items_error_type.NO_FALSE_POSITIVES", false]], "normalized_rank_error (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.normalized_rank_error", false]], "normalized_rank_error (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.normalized_rank_error", false]], "normalized_rank_error (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.normalized_rank_error", false]], "normalized_rank_error (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.normalized_rank_error", false]], "normalized_rank_error (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.normalized_rank_error", false]], "normalized_rank_error (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.normalized_rank_error", false]], "normalized_rank_error (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.normalized_rank_error", false]], "normalized_rank_error (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.normalized_rank_error", false]], "num_active_items (frequent_items_sketch property)": [[6, "datasketches.frequent_items_sketch.num_active_items", false]], "num_active_items (frequent_strings_sketch property)": [[6, "datasketches.frequent_strings_sketch.num_active_items", false]], "num_buckets (count_min_sketch property)": [[5, "datasketches.count_min_sketch.num_buckets", false]], "num_hashes (count_min_sketch property)": [[5, "datasketches.count_min_sketch.num_hashes", false]], "num_retained (density_sketch property)": [[22, "datasketches.density_sketch.num_retained", false]], "num_retained (kll_doubles_sketch property)": [[16, "datasketches.kll_doubles_sketch.num_retained", false]], "num_retained (kll_floats_sketch property)": [[16, "datasketches.kll_floats_sketch.num_retained", false]], "num_retained (kll_ints_sketch property)": [[16, "datasketches.kll_ints_sketch.num_retained", false]], "num_retained (kll_items_sketch property)": [[16, "datasketches.kll_items_sketch.num_retained", false]], "num_retained (quantiles_doubles_sketch property)": [[17, "datasketches.quantiles_doubles_sketch.num_retained", false]], "num_retained (quantiles_floats_sketch property)": [[17, "datasketches.quantiles_floats_sketch.num_retained", false]], "num_retained (quantiles_ints_sketch property)": [[17, "datasketches.quantiles_ints_sketch.num_retained", false]], "num_retained (quantiles_items_sketch property)": [[17, "datasketches.quantiles_items_sketch.num_retained", false]], "num_retained (req_floats_sketch property)": [[18, "datasketches.req_floats_sketch.num_retained", false]], "num_retained (req_ints_sketch property)": [[18, "datasketches.req_ints_sketch.num_retained", false]], "num_retained (req_items_sketch property)": [[18, "datasketches.req_items_sketch.num_retained", false]], "num_retained (theta_sketch property)": [[3, "datasketches.theta_sketch.num_retained", false]], "num_retained (tuple_sketch property)": [[4, "datasketches.tuple_sketch.num_retained", false]], "num_samples (var_opt_sketch property)": [[21, "datasketches.var_opt_sketch.num_samples", false]], "pydoublesserde (class in datasketches)": [[12, "datasketches.PyDoublesSerDe", false]], "pyfloatsserde (class in datasketches)": [[12, "datasketches.PyFloatsSerDe", false]], "pyintsserde (class in datasketches)": [[12, "datasketches.PyIntsSerDe", false]], "pylongsserde (class in datasketches)": [[12, "datasketches.PyLongsSerDe", false]], "pyobjectserde (class in datasketches)": [[12, "datasketches.PyObjectSerDe", false]], "pystringsserde (class in datasketches)": [[12, "datasketches.PyStringsSerDe", false]], "quantiles_doubles_sketch (class in datasketches)": [[17, "datasketches.quantiles_doubles_sketch", false]], "quantiles_floats_sketch (class in datasketches)": [[17, "datasketches.quantiles_floats_sketch", false]], "quantiles_ints_sketch (class in datasketches)": [[17, "datasketches.quantiles_ints_sketch", false]], "quantiles_items_sketch (class in datasketches)": [[17, "datasketches.quantiles_items_sketch", false]], "req_floats_sketch (class in datasketches)": [[18, "datasketches.req_floats_sketch", false]], "req_ints_sketch (class in datasketches)": [[18, "datasketches.req_ints_sketch", false]], "req_items_sketch (class in datasketches)": [[18, "datasketches.req_items_sketch", false]], "reset (hll_sketch attribute)": [[1, "datasketches.hll_sketch.reset", false]], "reset (hll_union attribute)": [[1, "datasketches.hll_union.reset", false]], "reset (tuple_union attribute)": [[4, "datasketches.tuple_union.reset", false]], "reset (update_theta_sketch attribute)": [[3, "datasketches.update_theta_sketch.reset", false]], "reset (update_tuple_sketch attribute)": [[4, "datasketches.update_tuple_sketch.reset", false]], "reset (var_opt_union attribute)": [[21, "datasketches.var_opt_union.reset", false]], "seed (count_min_sketch property)": [[5, "datasketches.count_min_sketch.seed", false]], "serialize (compact_theta_sketch attribute)": [[3, "datasketches.compact_theta_sketch.serialize", false]], "serialize (compact_tuple_sketch attribute)": [[4, "datasketches.compact_tuple_sketch.serialize", false]], "serialize (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.serialize", false]], "serialize (cpc_sketch attribute)": [[0, "datasketches.cpc_sketch.serialize", false]], "serialize (density_sketch attribute)": [[22, "datasketches.density_sketch.serialize", false]], "serialize (ebpps_sketch attribute)": [[19, "datasketches.ebpps_sketch.serialize", false]], "serialize (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.serialize", false]], "serialize (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.serialize", false]], "serialize (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.serialize", false]], "serialize (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.serialize", false]], "serialize (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.serialize", false]], "serialize (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.serialize", false]], "serialize (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.serialize", false]], "serialize (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.serialize", false]], "serialize (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.serialize", false]], "serialize (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.serialize", false]], "serialize (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.serialize", false]], "serialize (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.serialize", false]], "serialize (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.serialize", false]], "serialize (var_opt_sketch attribute)": [[21, "datasketches.var_opt_sketch.serialize", false]], "serialize (var_opt_union attribute)": [[21, "datasketches.var_opt_union.serialize", false]], "serialize_compact (hll_sketch attribute)": [[1, "datasketches.hll_sketch.serialize_compact", false]], "serialize_updatable (hll_sketch attribute)": [[1, "datasketches.hll_sketch.serialize_updatable", false]], "similarity_test() (theta_jaccard_similarity method)": [[9, "datasketches.theta_jaccard_similarity.similarity_test", false]], "similarity_test() (tuple_jaccard_similarity method)": [[9, "datasketches.tuple_jaccard_similarity.similarity_test", false]], "suggest_num_buckets() (count_min_sketch method)": [[5, "datasketches.count_min_sketch.suggest_num_buckets", false]], "suggest_num_hashes() (count_min_sketch method)": [[5, "datasketches.count_min_sketch.suggest_num_hashes", false]], "tgt_hll_type (class in _datasketches)": [[1, "datasketches.tgt_hll_type", false]], "tgt_type (hll_sketch property)": [[1, "datasketches.hll_sketch.tgt_type", false]], "theta (theta_sketch property)": [[3, "datasketches.theta_sketch.theta", false]], "theta (tuple_sketch property)": [[4, "datasketches.tuple_sketch.theta", false]], "theta64 (theta_sketch property)": [[3, "datasketches.theta_sketch.theta64", false]], "theta64 (tuple_sketch property)": [[4, "datasketches.tuple_sketch.theta64", false]], "theta_a_not_b (class in datasketches)": [[3, "datasketches.theta_a_not_b", false]], "theta_intersection (class in datasketches)": [[3, "datasketches.theta_intersection", false]], "theta_jaccard_similarity (class in datasketches)": [[9, "datasketches.theta_jaccard_similarity", false]], "theta_sketch (class in datasketches)": [[3, "datasketches.theta_sketch", false]], "theta_union (class in datasketches)": [[3, "datasketches.theta_union", false]], "to_bytes() (pyobjectserde method)": [[12, "datasketches.PyObjectSerDe.to_bytes", false]], "to_string (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.to_string", false]], "to_string (cpc_sketch attribute)": [[0, "datasketches.cpc_sketch.to_string", false]], "to_string (density_sketch attribute)": [[22, "datasketches.density_sketch.to_string", false]], "to_string (ebpps_sketch attribute)": [[19, "datasketches.ebpps_sketch.to_string", false]], "to_string (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.to_string", false]], "to_string (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.to_string", false]], "to_string (hll_sketch attribute)": [[1, "datasketches.hll_sketch.to_string", false]], "to_string (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.to_string", false]], "to_string (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.to_string", false]], "to_string (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.to_string", false]], "to_string (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.to_string", false]], "to_string (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.to_string", false]], "to_string (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.to_string", false]], "to_string (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.to_string", false]], "to_string (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.to_string", false]], "to_string (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.to_string", false]], "to_string (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.to_string", false]], "to_string (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.to_string", false]], "to_string (theta_sketch attribute)": [[3, "datasketches.theta_sketch.to_string", false]], "to_string (tuple_sketch attribute)": [[4, "datasketches.tuple_sketch.to_string", false]], "to_string (var_opt_sketch attribute)": [[21, "datasketches.var_opt_sketch.to_string", false]], "to_string (var_opt_union attribute)": [[21, "datasketches.var_opt_union.to_string", false]], "total_weight (count_min_sketch property)": [[5, "datasketches.count_min_sketch.total_weight", false]], "total_weight (frequent_items_sketch property)": [[6, "datasketches.frequent_items_sketch.total_weight", false]], "total_weight (frequent_strings_sketch property)": [[6, "datasketches.frequent_strings_sketch.total_weight", false]], "trim (update_theta_sketch attribute)": [[3, "datasketches.update_theta_sketch.trim", false]], "trim (update_tuple_sketch attribute)": [[4, "datasketches.update_tuple_sketch.trim", false]], "tuple_a_not_b (class in datasketches)": [[4, "datasketches.tuple_a_not_b", false]], "tuple_intersection (class in datasketches)": [[4, "datasketches.tuple_intersection", false]], "tuple_jaccard_similarity (class in datasketches)": [[9, "datasketches.tuple_jaccard_similarity", false]], "tuple_sketch (class in datasketches)": [[4, "datasketches.tuple_sketch", false]], "tuple_union (class in datasketches)": [[4, "datasketches.tuple_union", false]], "tuplepolicy (class in datasketches)": [[13, "datasketches.TuplePolicy", false]], "update (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.update", false]], "update (cpc_sketch attribute)": [[0, "datasketches.cpc_sketch.update", false]], "update (cpc_union attribute)": [[0, "datasketches.cpc_union.update", false]], "update (density_sketch attribute)": [[22, "datasketches.density_sketch.update", false]], "update (ebpps_sketch attribute)": [[19, "datasketches.ebpps_sketch.update", false]], "update (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.update", false]], "update (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.update", false]], "update (hll_sketch attribute)": [[1, "datasketches.hll_sketch.update", false]], "update (hll_union attribute)": [[1, "datasketches.hll_union.update", false]], "update (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.update", false]], "update (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.update", false]], "update (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.update", false]], "update (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.update", false]], "update (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.update", false]], "update (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.update", false]], "update (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.update", false]], "update (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.update", false]], "update (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.update", false]], "update (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.update", false]], "update (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.update", false]], "update (theta_intersection attribute)": [[3, "datasketches.theta_intersection.update", false]], "update (theta_union attribute)": [[3, "datasketches.theta_union.update", false]], "update (tuple_intersection attribute)": [[4, "datasketches.tuple_intersection.update", false]], "update (tuple_union attribute)": [[4, "datasketches.tuple_union.update", false]], "update (update_theta_sketch attribute)": [[3, "datasketches.update_theta_sketch.update", false]], "update (update_tuple_sketch attribute)": [[4, "datasketches.update_tuple_sketch.update", false]], "update (var_opt_sketch attribute)": [[21, "datasketches.var_opt_sketch.update", false]], "update (var_opt_union attribute)": [[21, "datasketches.var_opt_union.update", false]], "update_summary() (tuplepolicy method)": [[13, "datasketches.TuplePolicy.update_summary", false]], "update_theta_sketch (class in datasketches)": [[3, "datasketches.update_theta_sketch", false]], "update_tuple_sketch (class in datasketches)": [[4, "datasketches.update_tuple_sketch", false]], "var_opt_sketch (class in datasketches)": [[21, "datasketches.var_opt_sketch", false]], "var_opt_union (class in datasketches)": [[21, "datasketches.var_opt_union", false]]}, "objects": {"_datasketches": [[5, 0, 1, "datasketches.count_min_sketch", "count_min_sketch"], [0, 0, 1, "datasketches.cpc_sketch", "cpc_sketch"], [0, 0, 1, "datasketches.cpc_union", "cpc_union"], [1, 0, 1, "datasketches.hll_sketch", "hll_sketch"], [1, 0, 1, "datasketches.hll_union", "hll_union"], [1, 0, 1, "datasketches.tgt_hll_type", "tgt_hll_type"]], "_datasketches.count_min_sketch": [[5, 1, 1, "datasketches.count_min_sketch.deserialize", "deserialize"], [5, 2, 1, "datasketches.count_min_sketch.get_estimate", "get_estimate"], [5, 2, 1, "datasketches.count_min_sketch.get_lower_bound", "get_lower_bound"], [5, 2, 1, "datasketches.count_min_sketch.get_relative_error", "get_relative_error"], [5, 2, 1, "datasketches.count_min_sketch.get_serialized_size_bytes", "get_serialized_size_bytes"], [5, 2, 1, "datasketches.count_min_sketch.get_upper_bound", "get_upper_bound"], [5, 2, 1, "datasketches.count_min_sketch.is_empty", "is_empty"], [5, 2, 1, "datasketches.count_min_sketch.merge", "merge"], [5, 3, 1, "datasketches.count_min_sketch.num_buckets", "num_buckets"], [5, 3, 1, "datasketches.count_min_sketch.num_hashes", "num_hashes"], [5, 3, 1, "datasketches.count_min_sketch.seed", "seed"], [5, 2, 1, "datasketches.count_min_sketch.serialize", "serialize"], [5, 1, 1, "datasketches.count_min_sketch.suggest_num_buckets", "suggest_num_buckets"], [5, 1, 1, "datasketches.count_min_sketch.suggest_num_hashes", "suggest_num_hashes"], [5, 2, 1, "datasketches.count_min_sketch.to_string", "to_string"], [5, 3, 1, "datasketches.count_min_sketch.total_weight", "total_weight"], [5, 2, 1, "datasketches.count_min_sketch.update", "update"]], "_datasketches.cpc_sketch": [[0, 1, 1, "datasketches.cpc_sketch.__init__", "__init__"], [0, 1, 1, "datasketches.cpc_sketch.deserialize", "deserialize"], [0, 2, 1, "datasketches.cpc_sketch.get_estimate", "get_estimate"], [0, 2, 1, "datasketches.cpc_sketch.get_lower_bound", "get_lower_bound"], [0, 2, 1, "datasketches.cpc_sketch.get_upper_bound", "get_upper_bound"], [0, 2, 1, "datasketches.cpc_sketch.is_empty", "is_empty"], [0, 3, 1, "datasketches.cpc_sketch.lg_k", "lg_k"], [0, 2, 1, "datasketches.cpc_sketch.serialize", "serialize"], [0, 2, 1, "datasketches.cpc_sketch.to_string", "to_string"], [0, 2, 1, "datasketches.cpc_sketch.update", "update"]], "_datasketches.cpc_union": [[0, 1, 1, "datasketches.cpc_union.__init__", "__init__"], [0, 2, 1, "datasketches.cpc_union.get_result", "get_result"], [0, 2, 1, "datasketches.cpc_union.update", "update"]], "_datasketches.hll_sketch": [[1, 1, 1, "datasketches.hll_sketch.__init__", "__init__"], [1, 1, 1, "datasketches.hll_sketch.deserialize", "deserialize"], [1, 2, 1, "datasketches.hll_sketch.get_compact_serialization_bytes", "get_compact_serialization_bytes"], [1, 2, 1, "datasketches.hll_sketch.get_estimate", "get_estimate"], [1, 2, 1, "datasketches.hll_sketch.get_lower_bound", "get_lower_bound"], [1, 1, 1, "datasketches.hll_sketch.get_max_updatable_serialization_bytes", "get_max_updatable_serialization_bytes"], [1, 1, 1, "datasketches.hll_sketch.get_rel_err", "get_rel_err"], [1, 2, 1, "datasketches.hll_sketch.get_updatable_serialization_bytes", "get_updatable_serialization_bytes"], [1, 2, 1, "datasketches.hll_sketch.get_upper_bound", "get_upper_bound"], [1, 2, 1, "datasketches.hll_sketch.is_compact", "is_compact"], [1, 2, 1, "datasketches.hll_sketch.is_empty", "is_empty"], [1, 3, 1, "datasketches.hll_sketch.lg_config_k", "lg_config_k"], [1, 2, 1, "datasketches.hll_sketch.reset", "reset"], [1, 2, 1, "datasketches.hll_sketch.serialize_compact", "serialize_compact"], [1, 2, 1, "datasketches.hll_sketch.serialize_updatable", "serialize_updatable"], [1, 3, 1, "datasketches.hll_sketch.tgt_type", "tgt_type"], [1, 2, 1, "datasketches.hll_sketch.to_string", "to_string"], [1, 2, 1, "datasketches.hll_sketch.update", "update"]], "_datasketches.hll_union": [[1, 1, 1, "datasketches.hll_union.__init__", "__init__"], [1, 2, 1, "datasketches.hll_union.get_estimate", "get_estimate"], [1, 2, 1, "datasketches.hll_union.get_lower_bound", "get_lower_bound"], [1, 1, 1, "datasketches.hll_union.get_rel_err", "get_rel_err"], [1, 2, 1, "datasketches.hll_union.get_result", "get_result"], [1, 2, 1, "datasketches.hll_union.get_upper_bound", "get_upper_bound"], [1, 2, 1, "datasketches.hll_union.is_empty", "is_empty"], [1, 3, 1, "datasketches.hll_union.lg_config_k", "lg_config_k"], [1, 2, 1, "datasketches.hll_union.reset", "reset"], [1, 2, 1, "datasketches.hll_union.update", "update"]], "_datasketches.tgt_hll_type": [[1, 2, 1, "datasketches.tgt_hll_type.HLL_4", "HLL_4"], [1, 2, 1, "datasketches.tgt_hll_type.HLL_6", "HLL_6"], [1, 2, 1, "datasketches.tgt_hll_type.HLL_8", "HLL_8"]], "datasketches": [[13, 0, 1, "", "AccumulatorPolicy"], [10, 0, 1, "", "GaussianKernel"], [10, 0, 1, "", "KernelFunction"], [13, 0, 1, "", "MaxIntPolicy"], [13, 0, 1, "", "MinIntPolicy"], [12, 0, 1, "", "PyDoublesSerDe"], [12, 0, 1, "", "PyFloatsSerDe"], [12, 0, 1, "", "PyIntsSerDe"], [12, 0, 1, "", "PyLongsSerDe"], [12, 0, 1, "", "PyObjectSerDe"], [12, 0, 1, "", "PyStringsSerDe"], [13, 0, 1, "", "TuplePolicy"], [3, 0, 1, "", "compact_theta_sketch"], [4, 0, 1, "", "compact_tuple_sketch"], [22, 0, 1, "", "density_sketch"], [19, 0, 1, "", "ebpps_sketch"], [6, 0, 1, "", "frequent_items_error_type"], [6, 0, 1, "", "frequent_items_sketch"], [6, 0, 1, "", "frequent_strings_sketch"], [16, 0, 1, "", "kll_doubles_sketch"], [16, 0, 1, "", "kll_floats_sketch"], [16, 0, 1, "", "kll_ints_sketch"], [16, 0, 1, "", "kll_items_sketch"], [11, 4, 1, "", "ks_test"], [17, 0, 1, "", "quantiles_doubles_sketch"], [17, 0, 1, "", "quantiles_floats_sketch"], [17, 0, 1, "", "quantiles_ints_sketch"], [17, 0, 1, "", "quantiles_items_sketch"], [18, 0, 1, "", "req_floats_sketch"], [18, 0, 1, "", "req_ints_sketch"], [18, 0, 1, "", "req_items_sketch"], [3, 0, 1, "", "theta_a_not_b"], [3, 0, 1, "", "theta_intersection"], [9, 0, 1, "", "theta_jaccard_similarity"], [3, 0, 1, "", "theta_sketch"], [3, 0, 1, "", "theta_union"], [4, 0, 1, "", "tuple_a_not_b"], [4, 0, 1, "", "tuple_intersection"], [9, 0, 1, "", "tuple_jaccard_similarity"], [4, 0, 1, "", "tuple_sketch"], [4, 0, 1, "", "tuple_union"], [3, 0, 1, "", "update_theta_sketch"], [4, 0, 1, "", "update_tuple_sketch"], [21, 0, 1, "", "var_opt_sketch"], [21, 0, 1, "", "var_opt_union"]], "datasketches.KernelFunction": [[10, 1, 1, "", "__call__"]], "datasketches.PyObjectSerDe": [[12, 1, 1, "", "from_bytes"], [12, 1, 1, "", "get_size"], [12, 1, 1, "", "to_bytes"]], "datasketches.TuplePolicy": [[13, 1, 1, "", "__call__"], [13, 1, 1, "", "create_summary"], [13, 1, 1, "", "update_summary"]], "datasketches.compact_theta_sketch": [[3, 1, 1, "", "__init__"], [3, 1, 1, "", "deserialize"], [3, 2, 1, "", "serialize"]], "datasketches.compact_tuple_sketch": [[4, 1, 1, "", "__init__"], [4, 1, 1, "", "deserialize"], [4, 2, 1, "", "serialize"]], "datasketches.density_sketch": [[22, 1, 1, "", "__init__"], [22, 1, 1, "", "deserialize"], [22, 3, 1, "", "dim"], [22, 2, 1, "", "get_estimate"], [22, 2, 1, "", "is_empty"], [22, 2, 1, "", "is_estimation_mode"], [22, 3, 1, "", "k"], [22, 2, 1, "", "merge"], [22, 3, 1, "", "n"], [22, 3, 1, "", "num_retained"], [22, 2, 1, "", "serialize"], [22, 2, 1, "", "to_string"], [22, 2, 1, "", "update"]], "datasketches.ebpps_sketch": [[19, 1, 1, "", "__init__"], [19, 3, 1, "", "c"], [19, 1, 1, "", "deserialize"], [19, 2, 1, "", "get_serialized_size_bytes"], [19, 2, 1, "", "is_empty"], [19, 3, 1, "", "k"], [19, 2, 1, "", "merge"], [19, 3, 1, "", "n"], [19, 2, 1, "", "serialize"], [19, 2, 1, "", "to_string"], [19, 2, 1, "", "update"]], "datasketches.frequent_items_error_type": [[6, 2, 1, "", "NO_FALSE_NEGATIVES"], [6, 2, 1, "", "NO_FALSE_POSITIVES"]], "datasketches.frequent_items_sketch": [[6, 1, 1, "", "__init__"], [6, 1, 1, "", "deserialize"], [6, 3, 1, "", "epsilon"], [6, 1, 1, "", "get_apriori_error"], [6, 1, 1, "", "get_epsilon_for_lg_size"], [6, 2, 1, "", "get_estimate"], [6, 2, 1, "", "get_frequent_items"], [6, 2, 1, "", "get_lower_bound"], [6, 2, 1, "", "get_serialized_size_bytes"], [6, 2, 1, "", "get_upper_bound"], [6, 2, 1, "", "is_empty"], [6, 2, 1, "", "merge"], [6, 3, 1, "", "num_active_items"], [6, 2, 1, "", "serialize"], [6, 2, 1, "", "to_string"], [6, 3, 1, "", "total_weight"], [6, 2, 1, "", "update"]], "datasketches.frequent_strings_sketch": [[6, 1, 1, "", "__init__"], [6, 1, 1, "", "deserialize"], [6, 3, 1, "", "epsilon"], [6, 1, 1, "", "get_apriori_error"], [6, 1, 1, "", "get_epsilon_for_lg_size"], [6, 2, 1, "", "get_estimate"], [6, 2, 1, "", "get_frequent_items"], [6, 2, 1, "", "get_lower_bound"], [6, 2, 1, "", "get_serialized_size_bytes"], [6, 2, 1, "", "get_upper_bound"], [6, 2, 1, "", "is_empty"], [6, 2, 1, "", "merge"], [6, 3, 1, "", "num_active_items"], [6, 2, 1, "", "serialize"], [6, 2, 1, "", "to_string"], [6, 3, 1, "", "total_weight"], [6, 2, 1, "", "update"]], "datasketches.kll_doubles_sketch": [[16, 1, 1, "", "__init__"], [16, 1, 1, "", "deserialize"], [16, 2, 1, "", "get_cdf"], [16, 2, 1, "", "get_max_value"], [16, 2, 1, "", "get_min_value"], [16, 1, 1, "", "get_normalized_rank_error"], [16, 2, 1, "", "get_pmf"], [16, 2, 1, "", "get_quantile"], [16, 2, 1, "", "get_quantiles"], [16, 2, 1, "", "get_rank"], [16, 2, 1, "", "is_empty"], [16, 2, 1, "", "is_estimation_mode"], [16, 3, 1, "", "k"], [16, 2, 1, "", "merge"], [16, 3, 1, "", "n"], [16, 2, 1, "", "normalized_rank_error"], [16, 3, 1, "", "num_retained"], [16, 2, 1, "", "serialize"], [16, 2, 1, "", "to_string"], [16, 2, 1, "", "update"]], "datasketches.kll_floats_sketch": [[16, 1, 1, "", "__init__"], [16, 1, 1, "", "deserialize"], [16, 2, 1, "", "get_cdf"], [16, 2, 1, "", "get_max_value"], [16, 2, 1, "", "get_min_value"], [16, 1, 1, "", "get_normalized_rank_error"], [16, 2, 1, "", "get_pmf"], [16, 2, 1, "", "get_quantile"], [16, 2, 1, "", "get_quantiles"], [16, 2, 1, "", "get_rank"], [16, 2, 1, "", "is_empty"], [16, 2, 1, "", "is_estimation_mode"], [16, 3, 1, "", "k"], [16, 2, 1, "", "merge"], [16, 3, 1, "", "n"], [16, 2, 1, "", "normalized_rank_error"], [16, 3, 1, "", "num_retained"], [16, 2, 1, "", "serialize"], [16, 2, 1, "", "to_string"], [16, 2, 1, "", "update"]], "datasketches.kll_ints_sketch": [[16, 1, 1, "", "__init__"], [16, 1, 1, "", "deserialize"], [16, 2, 1, "", "get_cdf"], [16, 2, 1, "", "get_max_value"], [16, 2, 1, "", "get_min_value"], [16, 1, 1, "", "get_normalized_rank_error"], [16, 2, 1, "", "get_pmf"], [16, 2, 1, "", "get_quantile"], [16, 2, 1, "", "get_quantiles"], [16, 2, 1, "", "get_rank"], [16, 2, 1, "", "is_empty"], [16, 2, 1, "", "is_estimation_mode"], [16, 3, 1, "", "k"], [16, 2, 1, "", "merge"], [16, 3, 1, "", "n"], [16, 2, 1, "", "normalized_rank_error"], [16, 3, 1, "", "num_retained"], [16, 2, 1, "", "serialize"], [16, 2, 1, "", "to_string"], [16, 2, 1, "", "update"]], "datasketches.kll_items_sketch": [[16, 1, 1, "", "__init__"], [16, 1, 1, "", "deserialize"], [16, 2, 1, "", "get_cdf"], [16, 2, 1, "", "get_max_value"], [16, 2, 1, "", "get_min_value"], [16, 1, 1, "", "get_normalized_rank_error"], [16, 2, 1, "", "get_pmf"], [16, 2, 1, "", "get_quantile"], [16, 2, 1, "", "get_quantiles"], [16, 2, 1, "", "get_rank"], [16, 2, 1, "", "is_empty"], [16, 2, 1, "", "is_estimation_mode"], [16, 3, 1, "", "k"], [16, 2, 1, "", "merge"], [16, 3, 1, "", "n"], [16, 2, 1, "", "normalized_rank_error"], [16, 3, 1, "", "num_retained"], [16, 2, 1, "", "serialize"], [16, 2, 1, "", "to_string"], [16, 2, 1, "", "update"]], "datasketches.quantiles_doubles_sketch": [[17, 1, 1, "", "__init__"], [17, 1, 1, "", "deserialize"], [17, 2, 1, "", "get_cdf"], [17, 2, 1, "", "get_max_value"], [17, 2, 1, "", "get_min_value"], [17, 1, 1, "", "get_normalized_rank_error"], [17, 2, 1, "", "get_pmf"], [17, 2, 1, "", "get_quantile"], [17, 2, 1, "", "get_quantiles"], [17, 2, 1, "", "get_rank"], [17, 2, 1, "", "is_empty"], [17, 2, 1, "", "is_estimation_mode"], [17, 3, 1, "", "k"], [17, 2, 1, "", "merge"], [17, 3, 1, "", "n"], [17, 2, 1, "", "normalized_rank_error"], [17, 3, 1, "", "num_retained"], [17, 2, 1, "", "serialize"], [17, 2, 1, "", "to_string"], [17, 2, 1, "", "update"]], "datasketches.quantiles_floats_sketch": [[17, 1, 1, "", "__init__"], [17, 1, 1, "", "deserialize"], [17, 2, 1, "", "get_cdf"], [17, 2, 1, "", "get_max_value"], [17, 2, 1, "", "get_min_value"], [17, 1, 1, "", "get_normalized_rank_error"], [17, 2, 1, "", "get_pmf"], [17, 2, 1, "", "get_quantile"], [17, 2, 1, "", "get_quantiles"], [17, 2, 1, "", "get_rank"], [17, 2, 1, "", "is_empty"], [17, 2, 1, "", "is_estimation_mode"], [17, 3, 1, "", "k"], [17, 2, 1, "", "merge"], [17, 3, 1, "", "n"], [17, 2, 1, "", "normalized_rank_error"], [17, 3, 1, "", "num_retained"], [17, 2, 1, "", "serialize"], [17, 2, 1, "", "to_string"], [17, 2, 1, "", "update"]], "datasketches.quantiles_ints_sketch": [[17, 1, 1, "", "__init__"], [17, 1, 1, "", "deserialize"], [17, 2, 1, "", "get_cdf"], [17, 2, 1, "", "get_max_value"], [17, 2, 1, "", "get_min_value"], [17, 1, 1, "", "get_normalized_rank_error"], [17, 2, 1, "", "get_pmf"], [17, 2, 1, "", "get_quantile"], [17, 2, 1, "", "get_quantiles"], [17, 2, 1, "", "get_rank"], [17, 2, 1, "", "is_empty"], [17, 2, 1, "", "is_estimation_mode"], [17, 3, 1, "", "k"], [17, 2, 1, "", "merge"], [17, 3, 1, "", "n"], [17, 2, 1, "", "normalized_rank_error"], [17, 3, 1, "", "num_retained"], [17, 2, 1, "", "serialize"], [17, 2, 1, "", "to_string"], [17, 2, 1, "", "update"]], "datasketches.quantiles_items_sketch": [[17, 1, 1, "", "__init__"], [17, 1, 1, "", "deserialize"], [17, 2, 1, "", "get_cdf"], [17, 2, 1, "", "get_max_value"], [17, 2, 1, "", "get_min_value"], [17, 1, 1, "", "get_normalized_rank_error"], [17, 2, 1, "", "get_pmf"], [17, 2, 1, "", "get_quantile"], [17, 2, 1, "", "get_quantiles"], [17, 2, 1, "", "get_rank"], [17, 2, 1, "", "is_empty"], [17, 2, 1, "", "is_estimation_mode"], [17, 3, 1, "", "k"], [17, 2, 1, "", "merge"], [17, 3, 1, "", "n"], [17, 2, 1, "", "normalized_rank_error"], [17, 3, 1, "", "num_retained"], [17, 2, 1, "", "serialize"], [17, 2, 1, "", "to_string"], [17, 2, 1, "", "update"]], "datasketches.req_floats_sketch": [[18, 1, 1, "", "__init__"], [18, 1, 1, "", "deserialize"], [18, 1, 1, "", "get_RSE"], [18, 2, 1, "", "get_cdf"], [18, 2, 1, "", "get_max_value"], [18, 2, 1, "", "get_min_value"], [18, 2, 1, "", "get_pmf"], [18, 2, 1, "", "get_quantile"], [18, 2, 1, "", "get_quantiles"], [18, 2, 1, "", "get_rank"], [18, 2, 1, "", "get_rank_lower_bound"], [18, 2, 1, "", "get_rank_upper_bound"], [18, 2, 1, "", "is_empty"], [18, 2, 1, "", "is_estimation_mode"], [18, 2, 1, "", "is_hra"], [18, 3, 1, "", "k"], [18, 2, 1, "", "merge"], [18, 3, 1, "", "n"], [18, 3, 1, "", "num_retained"], [18, 2, 1, "", "serialize"], [18, 2, 1, "", "to_string"], [18, 2, 1, "", "update"]], "datasketches.req_ints_sketch": [[18, 1, 1, "", "__init__"], [18, 1, 1, "", "deserialize"], [18, 1, 1, "", "get_RSE"], [18, 2, 1, "", "get_cdf"], [18, 2, 1, "", "get_max_value"], [18, 2, 1, "", "get_min_value"], [18, 2, 1, "", "get_pmf"], [18, 2, 1, "", "get_quantile"], [18, 2, 1, "", "get_quantiles"], [18, 2, 1, "", "get_rank"], [18, 2, 1, "", "get_rank_lower_bound"], [18, 2, 1, "", "get_rank_upper_bound"], [18, 2, 1, "", "is_empty"], [18, 2, 1, "", "is_estimation_mode"], [18, 2, 1, "", "is_hra"], [18, 3, 1, "", "k"], [18, 2, 1, "", "merge"], [18, 3, 1, "", "n"], [18, 3, 1, "", "num_retained"], [18, 2, 1, "", "serialize"], [18, 2, 1, "", "to_string"], [18, 2, 1, "", "update"]], "datasketches.req_items_sketch": [[18, 1, 1, "", "__init__"], [18, 1, 1, "", "deserialize"], [18, 1, 1, "", "get_RSE"], [18, 2, 1, "", "get_cdf"], [18, 2, 1, "", "get_max_value"], [18, 2, 1, "", "get_min_value"], [18, 2, 1, "", "get_pmf"], [18, 2, 1, "", "get_quantile"], [18, 2, 1, "", "get_quantiles"], [18, 2, 1, "", "get_rank"], [18, 2, 1, "", "get_rank_lower_bound"], [18, 2, 1, "", "get_rank_upper_bound"], [18, 2, 1, "", "is_empty"], [18, 2, 1, "", "is_estimation_mode"], [18, 2, 1, "", "is_hra"], [18, 3, 1, "", "k"], [18, 2, 1, "", "merge"], [18, 3, 1, "", "n"], [18, 3, 1, "", "num_retained"], [18, 2, 1, "", "serialize"], [18, 2, 1, "", "to_string"], [18, 2, 1, "", "update"]], "datasketches.theta_a_not_b": [[3, 1, 1, "", "__init__"], [3, 2, 1, "", "compute"]], "datasketches.theta_intersection": [[3, 1, 1, "", "__init__"], [3, 2, 1, "", "get_result"], [3, 2, 1, "", "has_result"], [3, 2, 1, "", "update"]], "datasketches.theta_jaccard_similarity": [[9, 1, 1, "", "dissimilarity_test"], [9, 1, 1, "", "exactly_equal"], [9, 1, 1, "", "jaccard"], [9, 1, 1, "", "similarity_test"]], "datasketches.theta_sketch": [[3, 2, 1, "", "get_estimate"], [3, 2, 1, "", "get_lower_bound"], [3, 2, 1, "", "get_seed_hash"], [3, 2, 1, "", "get_upper_bound"], [3, 2, 1, "", "is_empty"], [3, 2, 1, "", "is_estimation_mode"], [3, 2, 1, "", "is_ordered"], [3, 3, 1, "", "num_retained"], [3, 3, 1, "", "theta"], [3, 3, 1, "", "theta64"], [3, 2, 1, "", "to_string"]], "datasketches.theta_union": [[3, 1, 1, "", "__init__"], [3, 2, 1, "", "get_result"], [3, 2, 1, "", "update"]], "datasketches.tuple_a_not_b": [[4, 1, 1, "", "__init__"], [4, 2, 1, "", "compute"]], "datasketches.tuple_intersection": [[4, 1, 1, "", "__init__"], [4, 2, 1, "", "get_result"], [4, 2, 1, "", "has_result"], [4, 2, 1, "", "update"]], "datasketches.tuple_jaccard_similarity": [[9, 1, 1, "", "dissimilarity_test"], [9, 1, 1, "", "exactly_equal"], [9, 1, 1, "", "jaccard"], [9, 1, 1, "", "similarity_test"]], "datasketches.tuple_sketch": [[4, 2, 1, "", "DEFAULT_SEED"], [4, 2, 1, "", "get_estimate"], [4, 2, 1, "", "get_lower_bound"], [4, 2, 1, "", "get_seed_hash"], [4, 2, 1, "", "get_upper_bound"], [4, 2, 1, "", "is_empty"], [4, 2, 1, "", "is_estimation_mode"], [4, 2, 1, "", "is_ordered"], [4, 3, 1, "", "num_retained"], [4, 3, 1, "", "theta"], [4, 3, 1, "", "theta64"], [4, 2, 1, "", "to_string"]], "datasketches.tuple_union": [[4, 1, 1, "", "__init__"], [4, 2, 1, "", "get_result"], [4, 2, 1, "", "reset"], [4, 2, 1, "", "update"]], "datasketches.update_theta_sketch": [[3, 1, 1, "", "__init__"], [3, 2, 1, "", "compact"], [3, 2, 1, "", "reset"], [3, 2, 1, "", "trim"], [3, 2, 1, "", "update"]], "datasketches.update_tuple_sketch": [[4, 1, 1, "", "__init__"], [4, 2, 1, "", "compact"], [4, 2, 1, "", "reset"], [4, 2, 1, "", "trim"], [4, 2, 1, "", "update"]], "datasketches.var_opt_sketch": [[21, 1, 1, "", "__init__"], [21, 1, 1, "", "deserialize"], [21, 2, 1, "", "estimate_subset_sum"], [21, 2, 1, "", "get_serialized_size_bytes"], [21, 2, 1, "", "is_empty"], [21, 3, 1, "", "k"], [21, 3, 1, "", "n"], [21, 3, 1, "", "num_samples"], [21, 2, 1, "", "serialize"], [21, 2, 1, "", "to_string"], [21, 2, 1, "", "update"]], "datasketches.var_opt_union": [[21, 1, 1, "", "__init__"], [21, 1, 1, "", "deserialize"], [21, 2, 1, "", "get_result"], [21, 2, 1, "", "get_serialized_size_bytes"], [21, 2, 1, "", "reset"], [21, 2, 1, "", "serialize"], [21, 2, 1, "", "to_string"], [21, 2, 1, "", "update"]]}, "objnames": {"0": ["py", "class", "Python class"], "1": ["py", "method", "Python method"], "2": ["py", "attribute", "Python attribute"], "3": ["py", "property", "Python property"], "4": ["py", "function", "Python function"]}, "objtypes": {"0": "py:class", "1": "py:method", "2": "py:attribute", "3": "py:property", "4": "py:function"}, "terms": {"": [1, 6, 19, 20, 21], "0": [3, 4, 5, 6, 10, 16, 17, 18], "01668v2": 18, "05": 5, "1": [0, 1, 3, 4, 5, 6, 10, 16, 17, 18], "10": [1, 17], "100": 17, "1000": 17, "11": 0, "12": [3, 4, 18], "128": 17, "13": 16, "14": 6, "16": 1, "18": 6, "1982": 6, "1985": 2, "1e": 6, "1e9": 6, "2": [0, 1, 3, 4, 6, 17, 18], "20": 17, "200": 16, "2002": 6, "2003": 6, "2004": 18, "2006": 6, "2020": 16, "2021": 17, "2023": 19, "21": 1, "3": [0, 1, 3, 4, 6, 17, 18], "30": 17, "32": [12, 16], "33": 16, "4": [1, 12, 17], "40": 17, "47": 16, "483": 17, "5": [5, 6, 17], "500": 17, "50th": 17, "517": 17, "6": 1, "64": [0, 3, 4, 5, 12, 17], "65": 16, "7": [1, 9, 17], "75": 6, "8": [1, 6, 12], "80": 11, "900": 17, "9001": [0, 3, 4, 9], "93smirnov_test": 11, "95": [5, 17], "95th": 17, "97": 9, "99": [16, 17], "A": [1, 3, 4, 6, 10, 11, 12, 13, 16, 17, 21], "As": [0, 16, 17], "For": [0, 1, 5, 6, 16, 17, 18, 23], "If": [1, 6, 9, 16, 17, 18], "In": [0, 1, 16, 19], "It": [3, 16, 17, 18], "One": 2, "That": 15, "The": [0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 22], "Then": 16, "There": [3, 6], "These": [1, 8, 9, 15, 20, 23], "With": [16, 17, 18], "_": 11, "__call__": [10, 13], "__eq__": 6, "__hash__": 6, "__init__": [0, 1, 3, 4, 6, 16, 17, 18, 19, 21, 22], "__lt__": [16, 17, 18], "_datasketch": [0, 1, 3, 4, 5, 6, 9, 11, 16, 17, 18, 19, 21, 22], "ab": 18, "abbadi": 6, "abil": 18, "about": [1, 15, 16, 17], "abov": [7, 16], "absolut": 8, "abstract": [3, 4, 8, 10, 12, 13], "accept": 23, "account": 11, "accumulatori": 13, "accumulatorpolici": 13, "accuraci": [0, 1, 2, 3, 5, 6, 16, 17, 18], "achiev": 5, "activ": [6, 14], "actual": [9, 17], "ad": 13, "add": 16, "addit": [0, 2, 6, 12], "addition": 16, "advanc": 20, "affect": [16, 17], "after": [18, 20], "against": [0, 9], "agraw": 6, "algorithm": [0, 1, 2, 3, 6, 14, 18], "all": [1, 3, 6, 12, 13, 15, 16, 17, 19, 21], "alloc": 12, "allow": [0, 4, 12, 13, 18], "along": 6, "also": [0, 3, 10, 14, 15, 17], "altern": 15, "although": [1, 19], "alwai": [6, 13, 16, 17, 19, 20], "an": [0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 12, 13, 15, 16, 17, 18, 19, 20, 21, 22], "analog": [16, 17, 18], "analysi": [4, 11, 16, 17, 18], "analyz": 14, "ani": [3, 4, 5, 6, 7, 13, 16, 17], "anoth": [0, 6, 18], "answer": 15, "appl": 0, "appli": [2, 3, 4, 6, 13, 15, 16, 18, 20, 21], "applic": 2, "approach": 15, "approx": [5, 18], "approxim": [0, 1, 3, 4, 5, 6, 10, 15, 16, 17, 18, 22], "ar": [0, 1, 3, 4, 5, 6, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 20, 23], "arbitrari": [4, 6], "arg": [0, 1, 3, 4, 5, 6, 10, 12, 13, 16, 17, 18, 19, 21, 22], "arg0": 3, "arg1": 3, "around": 16, "arrai": [6, 10, 16, 17, 18], "art": 2, "arxiv": 18, "as_pmf": [16, 17], "associ": [4, 6, 16, 17, 18], "assum": [6, 11], "avail": 16, "avoid": 3, "axi": 16, "b": [3, 4, 10, 19], "back": 0, "background": 6, "backward": [6, 15], "bag": 6, "bandwidth": 10, "base": [0, 1, 2, 3, 4, 5, 6, 8, 10, 12, 13, 18, 19, 20, 22], "basi": 10, "basic": [3, 4, 10], "becaus": 16, "been": [7, 16, 17, 18, 21], "befor": [6, 7], "behavior": 1, "being": 20, "below": 16, "best": [16, 17], "better": [1, 2, 3], "between": [1, 3, 4, 6, 8, 9, 16, 17, 18, 22], "beyond": 3, "big": 14, "bin": [0, 16], "binari": [12, 16, 17], "bit": [0, 1, 3, 4, 5, 12, 16, 17], "blob": 22, "bool": [1, 3, 4, 9, 11, 16, 17, 18], "both": [11, 18, 20], "bound": [0, 1, 3, 4, 5, 6, 9, 14, 15, 16, 18, 20, 21], "bracket": 16, "bucket": [1, 5], "build": 22, "byte": [0, 1, 3, 4, 5, 6, 12, 16, 17, 18, 19, 21, 22], "c": [0, 19], "call": [16, 19], "came": 2, "can": [0, 1, 3, 4, 6, 11, 13, 15, 16, 17, 18], "cannot": 16, "capabl": [0, 6, 18], "capac": 6, "cardin": [0, 3], "case": [1, 6, 8, 17, 19], "caus": 6, "cdf": [15, 16, 17, 18], "certain": [7, 8, 10, 16, 19], "choic": 1, "choos": 18, "class": [0, 1, 3, 4, 5, 6, 9, 10, 12, 13, 16, 17, 18, 19, 21, 22], "classic": [15, 17], "close": 7, "cm": 5, "code": [6, 18], "collect": 1, "com": 22, "combin": [8, 13], "come": [11, 17], "commonli": [6, 16], "compact": [1, 3, 4, 16, 18], "compact_theta_sketch": 3, "compact_tuple_sketch": 4, "compactor": 18, "compar": [0, 16, 17, 18], "comparison": [0, 18], "compat": [6, 12, 15, 16, 17], "complic": 4, "compress": [1, 2, 14], "comput": [3, 4, 6, 8, 9, 15, 19, 21, 22], "concept": 2, "concret": 8, "confid": [5, 9, 16, 17], "configur": [0, 1, 5, 16, 17, 18, 19, 21, 22], "consecut": [16, 17, 18], "consid": [9, 17], "consist": 13, "constant": [1, 6, 16, 17, 18], "construct": [1, 18, 21], "consum": [1, 12], "contain": [3, 6, 7], "context": 10, "contrast": [5, 19], "control": [16, 17, 18, 22], "coreset": 22, "cormod": [5, 18], "correspond": [0, 1, 3, 4, 5, 6, 16, 17, 18, 19, 21, 22], "cost": [1, 12], "could": [16, 17, 18], "count": [1, 3, 4, 6, 17, 18], "count_min_sketch": [5, 7], "counter": 6, "countmin": [7, 14], "coupon": 1, "cpc": [1, 2, 14], "cpc_sketch": [0, 2], "cpc_union": 0, "creat": [0, 3, 4, 6, 13, 16, 17, 18, 19, 21, 22], "create_summari": 13, "creation": 19, "criterion": 18, "critic": 12, "cross": [12, 17], "cumul": [15, 16, 17, 18], "current": [1, 3, 4, 5, 6, 7, 11, 15, 19, 21], "custom": [4, 10, 12, 13], "data": [2, 6, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 22], "datasketch": [2, 11], "datum": [0, 1, 3, 4], "debug": 18, "decreas": [15, 18], "decrement": 6, "dedic": [3, 4], "default": [1, 3, 4, 10, 16, 17, 18], "default_se": 4, "defin": [3, 4, 6, 10, 16, 19], "definit": [16, 17, 18], "delta": 5, "demain": 6, "denot": [5, 6], "densiti": [8, 10, 14, 23], "density_sketch": [10, 22, 23], "depend": [5, 16], "deprec": [14, 15], "deriv": [3, 16, 17, 18], "describ": [0, 5, 18], "deseri": [0, 1, 3, 4, 5, 6, 8, 14, 16, 17, 18, 19, 21, 22], "design": [15, 23], "desing": 21, "detail": [18, 20], "determin": [7, 11], "determinist": 6, "develop": [0, 14], "deviat": [0, 1, 3, 4, 18], "differ": [0, 1, 2, 3, 6, 12, 13, 18, 20], "dim": 22, "dimac": 5, "dimens": [0, 22], "dimension": 16, "discov": 6, "discrep": 22, "discuss": 18, "disjoint": [16, 17, 18], "dissimilar": 9, "dissimilarity_test": 9, "distanc": 22, "distinct": [0, 1, 3, 4, 6], "distribut": [1, 11, 15, 16, 17, 18], "divid": [16, 17, 18], "do": 6, "document": 16, "doe": [0, 5, 6, 7, 16, 18, 20], "domain": 16, "doubl": [16, 17, 18, 19], "dtype": [16, 17, 18], "dure": 1, "e": 15, "e2": 11, "each": [1, 2, 4, 6, 11, 12, 13, 15, 16, 17, 18, 20], "earliest": 2, "easili": [3, 4], "ebpp": [14, 20], "ebpps_sketch": [19, 20], "edg": [16, 17], "edo": [18, 22], "edoliberti": 22, "edu": 5, "effect": [3, 4], "effici": [0, 3, 6, 14], "either": [6, 15, 16, 17, 18], "element": [2, 6], "els": 18, "empir": [0, 16, 17, 18], "emploi": 6, "empti": [0, 1, 3, 4, 6, 16, 17, 18, 19, 21, 22], "en": 11, "enabl": [16, 17], "encod": 12, "end": 15, "endian": 12, "enough": 1, "ensur": [6, 19, 20], "entir": [7, 15, 20], "entri": [1, 3, 4, 6], "entropi": 0, "ep": 16, "epsilon": [6, 16], "equal": [11, 15, 16, 17, 18, 19], "equival": [9, 16, 17, 19, 21], "error": [1, 3, 5, 6, 8, 11, 14, 15, 16, 17, 19, 21, 22], "estim": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 16, 17, 18, 21, 22, 23], "estimate_subset_sum": 21, "estimated_total_stream_weight": 6, "estimated_total_weight": 6, "evalu": 10, "even": [0, 20], "everi": [3, 4, 5, 6], "exact": [6, 14, 20], "exactli": [19, 20], "exactly_equ": 9, "exampl": [4, 5, 6, 8, 10, 12, 17], "exce": [6, 18, 19], "except": [1, 16, 17, 18], "excess": [3, 4], "exclud": 6, "exclus": [16, 17, 18], "exist": [3, 4, 13], "expect": [9, 19], "expens": 6, "express": 18, "extend": [12, 13], "extens": [4, 18], "extern": 6, "extrem": [0, 6], "f688c8161a25582457b0a09deb4630a81406293b": 22, "f_x": 5, "factor": 18, "failur": 5, "fals": [0, 1, 3, 4, 5, 6, 9, 11, 16, 17, 18, 19, 21, 22], "famili": [1, 8, 11], "far": [6, 15, 16, 17, 18, 19], "fast": 0, "favor": [15, 17], "fed": 1, "feed": [19, 21], "few": 4, "fewer": [6, 19, 21], "field": 6, "find": 6, "fit": [16, 17], "fix": 4, "flag": [16, 17], "flajolet": [1, 2], "flavor": [1, 6], "float": [0, 1, 3, 4, 5, 6, 9, 10, 11, 12, 15, 16, 17, 18, 19], "float32": [16, 17, 18], "float64": [16, 17], "fm85": 0, "follow": [6, 16, 18, 22], "footprint": 2, "form": [3, 4, 6, 11], "format": 12, "found": 6, "fraction": [3, 4, 16, 17, 19], "framework": 3, "frequenc": [5, 6, 17], "frequent": [5, 7, 14], "frequent_items_error_typ": 6, "frequent_items_sketch": [6, 7], "frequent_strings_sketch": [6, 7], "from": [2, 3, 4, 6, 7, 10, 11, 12, 16, 17, 18, 19, 20, 21, 22], "from_byt": 12, "full": [1, 5], "funciton": 10, "function": [0, 1, 3, 4, 5, 6, 8, 11, 14, 15, 16, 17, 18], "futur": 0, "g": 15, "gaussian": 10, "gaussiankernel": 10, "gde": 22, "gener": [6, 7, 10, 15, 16, 17, 18], "get": [16, 17], "get_apriori_error": 6, "get_cdf": [16, 17, 18], "get_compact_serialization_byt": 1, "get_epsilon_for_lg_s": 6, "get_estim": [0, 1, 3, 4, 5, 6, 22], "get_frequent_item": 6, "get_lower_bound": [0, 1, 3, 4, 5, 6], "get_max_updatable_serialization_byt": 1, "get_max_valu": [16, 17, 18], "get_min_valu": [16, 17, 18], "get_n": 17, "get_normalized_rank_error": [16, 17, 18], "get_pmf": [16, 17, 18], "get_quantil": [16, 17, 18], "get_rank": [16, 17, 18], "get_rank_lower_bound": 18, "get_rank_upper_bound": 18, "get_rel_err": 1, "get_relative_error": 5, "get_result": [0, 1, 3, 4, 19, 21], "get_rs": 18, "get_seed_hash": [3, 4], "get_serialized_size_byt": [5, 6, 19, 21], "get_siz": 12, "get_updatable_serialization_byt": 1, "get_upper_bound": [0, 1, 3, 4, 5, 6], "github": 22, "given": [0, 1, 3, 4, 5, 6, 10, 11, 12, 15, 16, 17, 18, 19, 21, 22], "global": [6, 15], "good": [2, 3], "graham": [5, 18], "gri": 6, "grow": 6, "guarante": [5, 6, 16, 17, 18], "ha": [1, 3, 4, 5, 7, 15, 16, 17, 18], "haa": 19, "handl": [3, 7, 19], "has_result": [3, 4], "hash": [0, 3, 4, 5, 6], "hat": 5, "have": [1, 6, 11, 16, 17, 18, 21], "heavi": [5, 6, 7, 14], "heaviest": 7, "help": [9, 18], "hentschel": 19, "here": 18, "hi": 0, "high": [0, 1, 15, 18], "higher": [1, 17], "highest": 1, "highli": 14, "hip": 0, "histogram": [15, 17], "histor": [0, 15], "hitter": [5, 6, 7, 14], "hll": [0, 2, 14], "hll_4": 1, "hll_6": 1, "hll_8": 1, "hll_sketch": [1, 2], "hll_union": 1, "hold": [1, 6], "how": [4, 7, 8, 13, 18], "howev": [6, 16, 18], "http": [5, 11, 18, 22], "hyper": 2, "hyperloglog": [0, 2, 3, 14], "hypothesi": 11, "hypothet": [16, 17, 18], "i": [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22], "icon": 0, "identifi": 7, "imag": 5, "implement": [0, 1, 4, 6, 7, 10, 12, 13, 16, 17, 18, 22], "improv": [1, 21], "includ": [15, 16, 17, 18, 19, 20, 21], "inclus": [1, 16, 17, 18, 20], "incom": [3, 4, 6], "increas": [16, 17, 18], "increment": 6, "independ": 16, "index": [9, 14, 16, 17], "indic": [1, 10], "inform": 19, "inherit": 10, "init_number_of_sect": 18, "initi": [1, 3, 4, 6, 18], "input": [0, 1, 3, 4, 6, 10, 11, 16, 17, 18, 20, 22, 23], "insert": [3, 5, 6], "inspir": 22, "instanc": [6, 16, 17, 18, 19, 21, 22], "instead": [17, 18], "insuffici": 11, "int": [0, 1, 3, 4, 5, 6, 9, 12, 16, 17, 18, 19, 21, 22], "int32": [16, 17, 18], "integ": [0, 5, 6, 12, 13, 15], "integr": [1, 3, 4], "intern": 6, "internet": 6, "interpret": 16, "intersect": [2, 3, 4, 13], "interv": [16, 17, 18], "introduc": 6, "invers": [0, 16], "involv": 7, "is_compact": 1, "is_empti": [0, 1, 3, 4, 5, 6, 16, 17, 18, 19, 21, 22], "is_estimation_mod": [3, 4, 16, 17, 18, 22], "is_hra": 18, "is_ord": [3, 4], "item": [1, 3, 4, 5, 7, 12, 14, 15, 16, 17, 18, 19, 20, 21, 22], "iter": 19, "its": [0, 12, 16, 17, 19], "itself": 6, "j": 19, "j_": 9, "jaccard": [3, 4, 8, 14], "java": [16, 17], "just": 16, "justin": 18, "k": [0, 1, 2, 3, 4, 6, 7, 16, 17, 18, 19, 21, 22], "kappa": 0, "karnin": [18, 22], "karnin19a": 22, "karp": 6, "keep": [1, 4, 19], "kei": [2, 4], "kept": 13, "kernel": [8, 14, 22, 23], "kernel_funct": 8, "kernel_sketch": 8, "kernelfunct": [10, 22], "kevin": 0, "kll": [14, 15, 17], "kll_doubles_sketch": [11, 16], "kll_floats_sketch": [11, 16], "kll_ints_sketch": [11, 16], "kll_items_sketch": [11, 16], "known": [0, 2, 6, 10, 14, 20], "kolmogorov": [8, 14], "ks_test": [8, 11], "kwarg": [0, 1, 3, 4, 5, 6, 10, 12, 13, 16, 17, 18, 19, 21, 22], "lang": 0, "languag": [12, 17], "larg": [1, 15, 16, 17], "larger": [2, 16, 19], "largest": 13, "last": [16, 17, 18], "lazi": 16, "lb": [6, 9], "le": 5, "learn": [10, 22], "least": [6, 8], "left": [16, 17, 18], "legaci": 6, "lemma": 18, "len": 12, "length": [6, 16, 17, 18, 19, 20, 21, 22], "less": [15, 16, 17, 18], "let": 16, "letter": 19, "level": [5, 18], "leverag": 1, "lg_config_k": 1, "lg_k": [0, 1, 3, 4], "lg_max_k": [1, 6], "lg_max_map_s": 6, "liberti": [18, 22], "librari": [2, 4, 6, 7, 10, 11, 15, 23], "like": [1, 7, 11, 16], "limit": [6, 19], "line": [16, 17, 18], "list": [5, 7, 9], "littl": 12, "load_factor": 6, "log": [1, 2], "log2": [1, 6], "logarithm": [0, 3, 4, 6], "logic": [6, 15], "longer": 2, "look": 6, "loos": 18, "lopez": 6, "low": [15, 18], "lower": [0, 1, 3, 4, 5, 6, 9, 16, 18, 21], "lower_bound": 9, "m": [6, 16, 17, 18], "machin": [10, 22], "mai": [5, 6, 14, 15, 16, 18, 19], "maintain": [3, 7], "make": 16, "mani": 3, "map": 6, "mapcap": 6, "mapsiz": 6, "margin": 19, "martin": 2, "mass": [15, 16, 17, 18], "mass_i": 16, "match": [0, 3, 4, 21], "mathemat": [10, 18], "max": [13, 16, 17, 18], "max_k": 21, "max_map_s": 6, "maximum": [1, 3, 4, 5, 6, 16, 17, 18, 19, 21], "maxintpolici": 13, "maxmapcap": 6, "maxmaps": 6, "mean": [4, 6, 16, 17, 19], "measur": [3, 4, 9, 16, 17, 18], "median": [6, 17], "member": [3, 6], "memori": [1, 2, 6], "merg": [0, 1, 4, 5, 6, 16, 17, 18, 19, 22], "method": [0, 1, 3, 4, 5, 6, 10, 12, 16, 17, 18, 19, 21, 22], "metwal": 6, "might": [6, 16], "million": 17, "min": [13, 16, 17, 18], "minim": 20, "minimum": [2, 3, 16, 17, 18, 21], "minintpolici": 13, "misra": 6, "miss": 6, "mlr": 22, "mode": [1, 3, 4, 16, 17, 18, 22], "modifi": [11, 18], "modul": 14, "monoton": [16, 17, 18], "more": [0, 6], "most": [7, 17], "much": [1, 6], "multipli": 17, "multiset": 6, "munro": 6, "must": [1, 3, 4, 10, 12, 13, 16, 17, 18], "muthukrishnan": 5, "n": [1, 16, 17, 18, 19, 21, 22], "name": 6, "nan": [16, 17, 18], "natur": [16, 17], "ndarrai": [16, 17, 18], "nearli": [0, 16], "necessari": [16, 17, 18], "necessarili": 7, "need": [3, 5, 6, 13, 19, 20, 21], "network": 17, "never": [5, 6, 16, 18], "new": [0, 1, 6, 13, 17, 19, 21, 22], "newli": 0, "no_false_neg": 6, "no_false_posit": 6, "node": 17, "nomin": [3, 4, 18], "non": [0, 1, 3, 4, 5, 6, 16, 17, 18, 19, 21, 22], "none": [0, 1, 3, 4, 5, 6, 16, 17, 18, 19, 21, 22], "normal": [16, 17, 18], "normalized_rank_error": [16, 17], "note": [6, 9, 11, 16, 18], "novemb": 17, "now": 23, "null": [11, 12], "num_active_item": 6, "num_bucket": 5, "num_byt": 12, "num_hash": 5, "num_retain": [3, 4, 16, 17, 18, 22], "num_sampl": 21, "num_std_dev": 1, "number": [0, 1, 2, 3, 4, 5, 6, 12, 16, 17, 18, 19, 21, 22], "numer": [15, 19], "numpi": 10, "numsect": 18, "object": [0, 1, 3, 4, 5, 6, 7, 9, 10, 12, 13, 16, 17, 18, 19, 21, 22], "obtain": [5, 16, 17, 18], "occurr": 5, "off": [1, 2, 16, 17, 18], "offer": [1, 2, 7], "offest": 12, "offset": 12, "often": 7, "one": [2, 5, 6, 7, 8, 16, 17, 18, 22], "onli": [1, 6, 16, 17, 18, 23], "oper": [0, 2, 3, 4, 13, 16, 18], "opposit": 16, "opt": 21, "optim": [0, 14, 16, 20], "option": [0, 3, 4, 6, 16, 17, 18, 19, 21], "order": [3, 4, 5, 13, 15, 19], "org": [11, 18], "ortiz": 6, "other": [3, 4, 5, 16, 17], "otherwis": [0, 1, 3, 4, 5, 6, 9, 11, 16, 17, 18, 19, 21, 22], "our": 6, "output": 18, "outsid": 7, "over": [6, 15, 17], "overal": 17, "overestim": 5, "overload": [0, 1, 3, 4, 5, 11, 16, 17, 18], "overrid": [10, 12], "p": [3, 4, 11, 19], "packag": 3, "packet": [6, 17], "page": 14, "pair": [6, 8, 11], "papadimitri": 6, "paper": [0, 3, 5, 18, 22], "paramet": [0, 1, 3, 4, 5, 6, 10, 12, 13, 16, 17, 18, 19, 21, 22], "partial": 19, "particular": 18, "particularli": 10, "pass": [16, 17], "pattern": 10, "pavel": 18, "pdf": [5, 22], "per": [1, 16], "percentag": 7, "percentil": [16, 17], "perform": [0, 1, 2, 3, 4, 8, 10, 11, 16, 18], "permiss": 5, "phillip": 1, "physic": 6, "plot": 16, "plu": 6, "pmf": [15, 16, 17, 18], "point": [0, 1, 3, 4, 10, 12, 15, 16, 17, 18, 19, 22], "polici": [4, 8, 14], "portion": [15, 19], "posit": 6, "possibl": 0, "power": [6, 18], "pp": 19, "practic": [3, 6], "pre": 12, "precis": [16, 17, 19], "predic": [20, 21], "present": 21, "press": 22, "print": [19, 21], "priori": [1, 6, 18], "probabilist": [1, 2, 5, 14, 15, 16, 17, 18], "probabilitii": [14, 20], "probabl": [0, 5, 6, 15, 16, 17, 18, 19, 20, 21], "problem": 14, "proceed": 22, "process": [19, 21], "produc": [0, 1, 3, 4, 5, 6, 16, 17, 18, 19, 21, 22], "project": [14, 17], "proof": 6, "properti": [0, 1, 2, 3, 4, 5, 6, 16, 17, 18, 19, 21, 22], "proport": [14, 20], "prototyp": 18, "proven": 15, "provid": [0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 15, 16, 17, 18, 21, 22, 23], "pub": 5, "purg": 6, "py": 22, "pydoublesserd": 12, "pyfloatsserd": 12, "pyintsserd": 12, "pylongsserd": 12, "pyobjectserd": [4, 6, 12, 16, 17, 18, 19, 21], "pystringsserd": 12, "python": [13, 18], "q": 16, "q_hi": 16, "q_lo": 16, "qualifi": 6, "quantil": [8, 16, 22], "quantiles_doubles_sketch": [11, 17], "quantiles_floats_sketch": [11, 17], "quantiles_ints_sketch": [11, 17], "quantiles_items_sketch": [11, 17], "queri": [5, 15, 16, 17, 21], "quickli": 14, "quit": [0, 4, 16], "r": 16, "r1": 16, "r2": 16, "r_": 16, "r_i": 16, "radial": 10, "random": [6, 19], "randomli": 20, "rang": 15, "rank": [15, 16, 17, 18], "rate": [3, 4], "reach": [1, 6], "read": [0, 1, 3, 4, 5, 6, 12, 19, 21, 22], "real": [16, 17, 18], "reason": 1, "rebuild": 6, "receiv": [1, 17], "recognit": 10, "recommend": 1, "reconstruct": 12, "redesign": 6, "rediscov": 6, "refer": [6, 8, 12, 16], "reflect": 11, "regardless": 7, "reject": 11, "rel": [1, 5, 7, 14, 15, 19, 20, 21], "relat": [7, 9, 19, 21], "relationship": 16, "relative_error": 5, "relev": 13, "reli": 10, "remain": 18, "remov": [3, 4, 6], "repeat": 6, "repres": [1, 17, 19], "req": [14, 15, 17], "req_floats_sketch": 18, "req_ints_sketch": 18, "req_items_sketch": 18, "requir": [4, 5, 6, 8, 16, 17, 18, 19, 21, 22], "reservoir": [19, 21], "reset": [1, 3, 4, 21], "respect": [16, 17], "result": [0, 3, 4, 6, 16, 17, 18, 20, 21], "retain": [3, 4, 6, 16, 17, 18, 22], "retun": 12, "return": [0, 1, 3, 4, 5, 6, 9, 10, 11, 12, 13, 16, 17, 18, 19, 21, 22], "right": [4, 16, 17, 18], "roughli": [0, 21], "round": 18, "row": 1, "rse": 18, "rule": 13, "run": 6, "runtimeerror": [16, 17, 18], "rutger": 5, "s1": 16, "s2": 16, "s_i": 16, "s_m": 16, "same": [1, 3, 11], "sampl": [3, 4, 16, 17, 18, 22], "satisfi": 5, "scheme": [12, 16], "score": 10, "search": 14, "section": 18, "section_s": 18, "secur": 0, "see": 16, "seed": [0, 3, 4, 5, 9], "seem": 16, "seen": [5, 6, 7, 15, 19], "self": [0, 1, 3, 4, 5, 6, 10, 12, 13, 16, 17, 18, 19, 21, 22], "semin": 2, "separ": [3, 9, 16, 17, 18], "serd": [4, 6, 8, 14, 16, 17, 18, 19, 21], "serial": [0, 1, 3, 4, 5, 6, 8, 14, 16, 17, 18, 19, 21, 22], "serialize_compact": 1, "serialize_updat": 1, "set": [2, 3, 4, 6, 13, 16, 17, 18, 22], "sever": [2, 3, 4, 6, 12], "shenker": 6, "should": [13, 16, 19], "shown": 16, "side": [16, 17], "significantli": 1, "similar": [2, 3, 4, 8, 10, 13, 14], "similarity_test": 9, "similarli": 17, "simpl": [2, 3, 6, 12], "simultan": 0, "sinc": [6, 18], "singl": [16, 17], "size": [1, 3, 4, 5, 6, 11, 12, 14, 16, 17, 18, 20, 21, 22], "sk_1": 11, "sk_2": 11, "skech": 18, "sketch": [0, 1, 2, 6, 8, 9, 11, 12, 19, 21], "sketch_a": 9, "sketch_b": 9, "slot": 1, "sm": 16, "small": [1, 6, 11], "smaller": [0, 1, 6, 16, 21], "smallest": 13, "smirnov": [8, 14], "snly": 7, "so": [0, 6, 15, 16, 17, 18, 19], "solut": 2, "some": [6, 8, 16], "sometim": 16, "somewhat": [2, 20], "sort": [3, 4, 16, 17, 18], "sourc": [3, 4], "sourch": 4, "space": [0, 1, 2, 3, 6], "special": 18, "specif": [6, 8, 10, 15, 16, 17], "specifi": [0, 1, 5, 6, 8, 12, 13, 16, 18], "speed": [0, 6], "split": [16, 17, 18], "split_point": [16, 17, 18], "sqrt": 18, "standard": [0, 1, 3, 4, 18], "start": [1, 6, 12, 18], "start_full_s": 1, "start_max_s": 1, "state": [1, 2, 3, 4, 6, 18, 21], "static": [0, 1, 3, 4, 5, 6, 16, 17, 18, 19, 21, 22], "stochast": [16, 17], "storag": [1, 12], "store": [2, 3, 6], "str": [0, 1, 3, 4, 5], "straightforward": 15, "stream": [0, 1, 3, 4, 5, 6, 7, 15, 16, 17, 18, 19, 20, 21, 22], "strictli": 19, "string": [0, 1, 3, 4, 5, 6, 7, 12, 16, 17, 18, 19, 21, 22], "string_cont": 12, "subset": [20, 21], "subtract": 16, "suggest": 5, "suggest_num_bucket": 5, "suggest_num_hash": 5, "sum": [6, 16, 17, 18, 20, 21], "summari": [0, 1, 3, 4, 5, 6, 8, 13, 16, 17, 18, 19, 21, 22], "support": [2, 6], "surviv": 0, "t": [16, 17], "tabl": [1, 6], "take": 11, "target": 1, "target_hll_typ": 1, "task": 2, "templat": [16, 17], "term": 1, "termin": 12, "test": [8, 9, 14], "tgt_hll_type": 1, "tgt_type": 1, "thaler": 18, "than": [0, 1, 2, 3, 6, 15, 16, 17, 18, 19], "thei": [4, 11, 15, 20], "them": 8, "theta": [1, 2, 4, 8, 9, 14], "theta64": [3, 4], "theta_a_not_b": 3, "theta_intersect": 3, "theta_jaccard_similar": [3, 9], "theta_sketch": [2, 3, 4, 9], "theta_union": 3, "thi": [0, 1, 4, 5, 6, 11, 12, 13, 14, 16, 17, 18, 19, 21, 22], "those": [7, 8], "thousand": [16, 17], "three": [1, 12, 15], "threshold": 9, "through": [3, 4, 6], "throw": [16, 17, 18], "thu": [16, 18], "tian": 19, "tight": 18, "time": [1, 6, 16, 17, 18], "to_byt": 12, "to_str": [0, 1, 3, 4, 5, 6, 16, 17, 18, 19, 21, 22], "too": [6, 11], "tool": 18, "top": [6, 7], "topk": 14, "total": [5, 17, 18, 19, 21], "total_weight": [5, 6], "track": 6, "trade": [1, 2, 16, 17, 18], "tradeoff": 0, "translat": 16, "trial": [16, 17], "trim": [3, 4], "true": [0, 1, 3, 4, 5, 6, 9, 11, 16, 17, 18, 19, 21, 22], "true_mass": 16, "true_rank": 16, "tupl": [2, 3, 8, 9, 12, 14], "tuple_a_not_b": [3, 4], "tuple_intersect": 4, "tuple_jaccard_similar": [4, 9], "tuple_polici": 8, "tuple_sketch": [2, 4, 8, 9, 13], "tuple_union": 4, "tuplepolici": [4, 13], "two": [0, 6, 7, 10, 11, 16, 18, 22], "type": [1, 2, 6, 7, 10, 11, 12, 13, 15], "typic": 6, "u": 16, "ub": [6, 9], "under": 14, "underestim": 5, "underli": 11, "understand": [15, 18], "unequ": 19, "uniform": [15, 19, 21], "union": [0, 1, 3, 4, 13, 21], "uniqu": [0, 1, 2, 16, 17, 18], "unsurprisingli": 10, "up": [1, 6], "updat": [0, 1, 3, 4, 5, 6, 13, 16, 17, 18, 19, 21, 22], "update_summari": 13, "update_theta_sketch": 3, "update_tuple_sketch": 4, "upon": 19, "upper": [0, 1, 3, 4, 5, 6, 9, 16, 18, 21], "upper_bound": [1, 9], "us": [1, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 22], "usag": 6, "user": [0, 10, 18], "usual": 6, "v99": 22, "valid": [3, 4, 18], "valu": [0, 1, 2, 3, 4, 5, 6, 10, 11, 12, 13, 15, 16, 17, 18, 19, 21], "var": 21, "var_opt_sketch": [20, 21], "var_opt_union": 21, "variabl": [6, 18], "varianc": [14, 20], "variant": [3, 6, 7], "varopt": [14, 19, 20], "vector": [10, 16, 17, 18, 22], "veri": [4, 6, 16, 17], "version": [1, 6, 7, 12, 15, 16, 17, 18], "vesel\u00fd": 18, "via": 18, "view": 16, "visibl": 18, "w": 6, "warmup": 1, "we": [6, 11, 16, 18], "weight": [5, 6, 7, 16, 17, 18, 19, 20, 21], "well": [0, 2, 15, 21], "were": [2, 6, 16, 17], "what": [6, 15], "when": [0, 1, 3, 4, 5, 8, 13, 15, 16, 17, 18, 21], "where": [1, 6, 12, 13, 16, 19], "whether": [1, 3, 4, 18], "which": [2, 3, 4, 5, 6, 7, 10, 12, 15, 16, 17, 18], "while": [2, 3], "whose": 7, "wiki": 11, "wikipedia": 11, "win": 0, "within": [5, 8], "work": [2, 17, 18], "wors": 16, "worst": 6, "would": 6, "written": [12, 18], "x": [5, 16], "y": [16, 19], "year": 6, "yield": 16, "you": 17, "zero": 16, "zohar": [18, 22]}, "titles": ["Compressed Probabilistic Counting (CPC)", "HyperLogLog (HLL)", "Distinct Counting", "Theta Sketch", "Tuple Sketch", "CountMin Sketch", "Frequent Items", "Frequency Sketches", "Helper Classes", "Jaccard Similarity", "Kernel Function", "Kolmogorov-Smirnov Test", "Serialize/Deserialize (SerDe)", "Tuple Policy", "Apache DataSketches", "Quantiles Sketches", "KLL Sketch", "Quantiles Sketch (Deprecated)", "Relative Error Quantiles (REQ) Sketch", "Exact and Bounded, Probabilitiy Proportional to Size (EBPPS) Sampling", "Random Sampling Sketches", "Variance Optimal Sampling (VarOpt)", "Density Sketch", "Vector Sketches"], "titleterms": {"apach": 14, "bound": 19, "class": [8, 14], "compress": 0, "count": [0, 2, 14], "countmin": 5, "cpc": 0, "datasketch": 14, "densiti": 22, "deprec": 17, "deseri": 12, "distinct": [2, 14], "ebpp": 19, "error": 18, "estim": 14, "exact": 19, "frequenc": [7, 14], "frequent": 6, "function": 10, "helper": [8, 14], "hll": 1, "hyperloglog": 1, "indic": 14, "item": 6, "jaccard": 9, "kernel": 10, "kll": 16, "kolmogorov": 11, "optim": 21, "polici": 13, "probabilist": 0, "probabilitii": 19, "proport": 19, "quantil": [14, 15, 17, 18], "random": [14, 20], "rel": 18, "req": 18, "sampl": [14, 19, 20, 21], "serd": 12, "serial": 12, "similar": 9, "size": 19, "sketch": [3, 4, 5, 7, 14, 15, 16, 17, 18, 20, 22, 23], "smirnov": 11, "tabl": 14, "test": 11, "theta": 3, "tupl": [4, 13], "varianc": 21, "varopt": 21, "vector": [14, 23]}}) \ No newline at end of file diff --git a/docs/5.0.0/vector/density_sketch.html b/docs/5.0.0/vector/density_sketch.html new file mode 100644 index 00000000..51b650b1 --- /dev/null +++ b/docs/5.0.0/vector/density_sketch.html @@ -0,0 +1,248 @@ + + + + + + + Density Sketch — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Density Sketch

+

Builds a coreset from the given set of input points. +Provides density estimate at a given point.

+

Based on the following paper: Zohar Karnin, Edo Liberty +“Discrepancy, Coresets, and Sketches in Machine Learning” +https://proceedings.mlr.press/v99/karnin19a/karnin19a.pdf

+

Inspired by the following implementation: https://github.com/edoliberty/streaming-quantiles/blob/f688c8161a25582457b0a09deb4630a81406293b/gde.py

+

Requires the use of a KernelFunction to compute the distance between two vectors.

+
+
+class density_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, kernel: _datasketches.KernelFunction) _datasketches.density_sketch
+

Reads a bytes object and returns the corresponding density_sketch

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int, dim: int, kernel: _datasketches.KernelFunction) None
+

Creates a new density sketch

+
+
Parameters:
+
    +
  • k (int) – controls the size and error of the sketch

  • +
  • dim (int) – dimension of the input data

  • +
  • kernel (KernelFunction) – instance of a kernel

  • +
+
+
+
+ +
+
+property dim
+

The configured parameter dim

+
+ +
+
+get_estimate
+

Returns an approximate density at the given point

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Updates the sketch with the given vector

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.0/vector/index.html b/docs/5.0.0/vector/index.html new file mode 100644 index 00000000..808fefda --- /dev/null +++ b/docs/5.0.0/vector/index.html @@ -0,0 +1,135 @@ + + + + + + + Vector Sketches — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Vector Sketches

+

These sketches are designed to accept vector inputs. For now, the library provides only the +density_sketch for Kernel Density Estimation.

+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.1/.buildinfo b/docs/5.0.1/.buildinfo new file mode 100644 index 00000000..6a08c6b8 --- /dev/null +++ b/docs/5.0.1/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. +config: c2b4fc476624577343da93a20886cb56 +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/docs/5.0.1/_sources/distinct_counting/cpc.rst.txt b/docs/5.0.1/_sources/distinct_counting/cpc.rst.txt new file mode 100644 index 00000000..6a28d387 --- /dev/null +++ b/docs/5.0.1/_sources/distinct_counting/cpc.rst.txt @@ -0,0 +1,32 @@ +Compressed Probabilistic Counting (CPC) +--------------------------------------- +High performance C++ implementation of Compressed Probabilistic Counting (CPC) Sketch. +This is a unique-counting sketch that implements the Compressed Probabilistic Counting (CPC, a.k.a FM85) algorithms developed by Kevin Lang in his paper +`Back to the Future: an Even More Nearly Optimal Cardinality Estimation Algorithm `_. +This sketch is extremely space-efficient when serialized. +In an apples-to-apples empirical comparison against compressed HyperLogLog sketches, this new algorithm simultaneously wins on the two dimensions of the space/accuracy tradeoff and produces sketches that are smaller than the entropy of HLL, so no possible implementation of compressed HLL can match its space efficiency for a given accuracy. As described in the paper this sketch implements a newly developed ICON estimator algorithm that survives unioning operations, another well-known estimator, the Historical Inverse Probability (HIP) estimator does not. +The update speed performance of this sketch is quite fast and is comparable to the speed of HLL. +The unioning (merging) capability of this sketch also allows for merging of sketches with different configurations of K. +For additional security this sketch can be configured with a user-specified hash seed. + + +.. autoclass:: _datasketches.cpc_sketch + :members: + :undoc-members: + :exclude-members: deserialize + + .. rubric:: Static Methods: + + .. automethod:: deserialize + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + + +.. autoclass:: _datasketches.cpc_union + :members: + :undoc-members: + :exclude-members: deserialize + + .. automethod:: __init__ diff --git a/docs/5.0.1/_sources/distinct_counting/hyper_log_log.rst.txt b/docs/5.0.1/_sources/distinct_counting/hyper_log_log.rst.txt new file mode 100644 index 00000000..287209b0 --- /dev/null +++ b/docs/5.0.1/_sources/distinct_counting/hyper_log_log.rst.txt @@ -0,0 +1,55 @@ +HyperLogLog (HLL) +----------------- +This is a high performance implementation of Phillipe Flajolet's HLL sketch but with significantly improved error behavior. + +If the ONLY use case for sketching is counting uniques and merging, the HLL sketch is a reasonable choice, although the highest performing in terms of accuracy for storage space consumed is CPC (Compressed Probabilistic Counting). For large enough counts, this HLL version (with HLL_4) can be 2 to 16 times smaller than the Theta sketch family for the same accuracy. + +This implementation offers three different types of HLL sketch, each with different trade-offs with accuracy, space and performance. +These types are specified with the target_hll_type parameter. + +In terms of accuracy, all three types, for the same lg_config_k, have the same error distribution as a function of ``n``, the number of unique values fed to the sketch. +The configuration parameter ``lg_config_k`` is the log-base-2 of ``k``, where ``k`` is the number of buckets or slots for the sketch. + +During warmup, when the sketch has only received a small number of unique items (up to about 10% of ``k``), this implementation leverages a new class of estimator algorithms with significantly better accuracy. + + +.. autoclass:: _datasketches.tgt_hll_type + + .. autoattribute:: HLL_4 + :annotation: : 4 bits per entry + + .. autoattribute:: HLL_6 + :annotation: : 6 bits per entry + + .. autoattribute:: HLL_8 + :annotation: : 8 bits per entry + + +.. autoclass:: _datasketches.hll_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_max_updatable_serialization_bytes, get_rel_err + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_max_updatable_serialization_bytes + .. automethod:: get_rel_err + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: _datasketches.hll_union + :members: + :undoc-members: + :exclude-members: get_rel_err + + .. rubric:: Static Methods: + + .. automethod:: get_rel_err + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + \ No newline at end of file diff --git a/docs/5.0.1/_sources/distinct_counting/index.rst.txt b/docs/5.0.1/_sources/distinct_counting/index.rst.txt new file mode 100644 index 00000000..f4038815 --- /dev/null +++ b/docs/5.0.1/_sources/distinct_counting/index.rst.txt @@ -0,0 +1,24 @@ +Distinct Counting +================= + +.. currentmodule:: datasketches + +Distinct counting is one of the earliest tasks to which sketches were applied. The concept is simple: +Provide an estimate of the number of unique elements in a set of data. One of the earliest solutions came +from Flajolet and Martin in 1985 with their seminal work +`Probabilistic counting Algorithms for Data Base Applications `_. + +The DataSketches library offers several types of distinct counting sketches, each with different properties. + + * :class:`hll_sketch`: Hyper Log Log, a well-known sketch for distinct counting but no longer state-of-the-art. + * :class:`cpc_sketch`: Provides a better accuracy-space trade-off than HLL, but with a somewhat larger footprint while in-memory. + * :class:`theta_sketch`: Theta sketch, a type of k-minimum value sketch, which provide good performance with intersection and set difference operations. + * :class:`tuple_sketch`: Tuple sketch, which is similar to a theta sketch but supports additional data stored with each key. + +.. toctree:: + :maxdepth: 1 + + hyper_log_log + cpc + theta + tuple \ No newline at end of file diff --git a/docs/5.0.1/_sources/distinct_counting/theta.rst.txt b/docs/5.0.1/_sources/distinct_counting/theta.rst.txt new file mode 100644 index 00000000..94951f96 --- /dev/null +++ b/docs/5.0.1/_sources/distinct_counting/theta.rst.txt @@ -0,0 +1,65 @@ +Theta Sketch +------------ + +.. currentmodule:: datasketches + +Theta sketches are used for distinct counting. + +The theta package contains the basic sketch classes that are members of the `Theta Sketch Framework `_. +There is a separate Tuple package for many of the sketches that are derived from the same algorithms defined in the Theta Sketch Framework paper. + +The *Theta Sketch* sketch is a space-efficient method for estimating cardinalities of sets. +It can also easily handle set operations (such as union, intersection, difference) while maintaining good accuracy. +Theta sketch is a practical variant of the K-Minimum Values sketch which avoids the need to sort the stored +hash values on every insertion to the sketch. +It has better error properties than the HyperLogLog sketch for set operations beyond the simple union. + +Set operations (union, intersection, A-not-B) are performed through the use of dedicated objects. + +Several `Jaccard similarity `_ +measures can be computed between theta sketches with the :class:`theta_jaccard_similarity` class. + +.. autoclass:: theta_sketch + :members: + :undoc-members: + +.. autoclass:: update_theta_sketch + :members: + :undoc-members: + + .. automethod:: __init__ + + +.. autoclass:: compact_theta_sketch + :members: + :undoc-members: + :exclude-members: deserialize + + .. rubric:: Static Methods: + + .. automethod:: deserialize + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + + +.. autoclass:: theta_union + :members: + :undoc-members: + + .. automethod:: __init__ + + +.. autoclass:: theta_intersection + :members: + :undoc-members: + + .. automethod:: __init__ + + +.. autoclass:: theta_a_not_b + :members: + :undoc-members: + + .. automethod:: __init__ diff --git a/docs/5.0.1/_sources/distinct_counting/tuple.rst.txt b/docs/5.0.1/_sources/distinct_counting/tuple.rst.txt new file mode 100644 index 00000000..e4a369f2 --- /dev/null +++ b/docs/5.0.1/_sources/distinct_counting/tuple.rst.txt @@ -0,0 +1,64 @@ +Tuple Sketch +------------ + +.. currentmodule:: datasketches + +Tuple sketches are an extension of Theta sketches, meaning they provide estimate of distinct counts, that +allow the keeping of arbitrary summaries associated with each retained key +(for example, a count for every key). The use of a :class:`tuple_sketch` requires a :class:`TuplePolicy` which +defines how summaries are created, updated, merged, or intersected. The library provides a few basic +examples of :class:`TuplePolicy` implementations, but the right custom summary and policy can allow very +complicated analysis to be performed quite easily. + +Set operations (union, intersection, A-not-B) are performed through the use of dedicated objects. + +Several `Jaccard similarity `_ +measures can be computed between theta sketches with the :class:`tuple_jaccard_similarity` class. + +.. note:: + Serializing and deserializing this sketch requires the use of a :class:`PyObjectSerDe`. + +.. autoclass:: tuple_sketch + :members: + :undoc-members: + +.. autoclass:: update_tuple_sketch + :members: + :undoc-members: + + .. automethod:: __init__ + + +.. autoclass:: compact_tuple_sketch + :members: + :undoc-members: + :exclude-members: deserialize + + .. rubric:: Static Methods: + + .. automethod:: deserialize + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + + +.. autoclass:: tuple_union + :members: + :undoc-members: + + .. automethod:: __init__ + + +.. autoclass:: tuple_intersection + :members: + :undoc-members: + + .. automethod:: __init__ + + +.. autoclass:: tuple_a_not_b + :members: + :undoc-members: + + .. automethod:: __init__ diff --git a/docs/5.0.1/_sources/frequency/count_min_sketch.rst.txt b/docs/5.0.1/_sources/frequency/count_min_sketch.rst.txt new file mode 100644 index 00000000..b53b02e4 --- /dev/null +++ b/docs/5.0.1/_sources/frequency/count_min_sketch.rst.txt @@ -0,0 +1,27 @@ +CountMin Sketch +--------------- + +The CountMin sketch, as described in Cormode and Muthukrishnan in +http://dimacs.rutgers.edu/~graham/pubs/papers/cm-full.pdf, +is used for approximate Frequency Estimation. +For an item :math:`x` with frequency :math:`f_x`, the sketch provides an estimate, :math:`\hat{f_x}`, +such that :math:`f_x \approx \hat{f_x}.` +The sketch guarantees that :math:`f_x \le \hat{f_x}` and provides a probabilistic upper bound which is dependent on the size parameters. +The sketch provides an estimate of the occurrence frequency for any queried item but, in contrast +to the Frequent Items Sketch, this sketch does not provide a list of +heavy hitters. + +.. currentmodule:: _datasketches + +.. autoclass:: count_min_sketch + :members: + :undoc-members: + :exclude-members: deserialize, suggest_num_buckets, suggest_num_hashes + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: suggest_num_buckets + .. automethod:: suggest_num_hashes + + .. rubric:: Non-static Methods: diff --git a/docs/5.0.1/_sources/frequency/frequent_items.rst.txt b/docs/5.0.1/_sources/frequency/frequent_items.rst.txt new file mode 100644 index 00000000..76d81f58 --- /dev/null +++ b/docs/5.0.1/_sources/frequency/frequent_items.rst.txt @@ -0,0 +1,120 @@ +Frequent Items +-------------- + +.. currentmodule:: datasketches + +This sketch is useful for tracking approximate frequencies of items (``object`` or ``string``) with optional associated +integer counts that are members of a multiset of such items. +The true frequency of an item is defined to be the sum of associated counts. + +This implementation provides the following capabilities: + +* Estimate the *frequency* of an item. +* Return *upper* and *lower bounds* of any item, such that the true frequency is always between the upper and lower bounds. +* Return a global *maximum error* that holds for all items in the stream. +* Return an array of frequent items that qualify either a *NO_FALSE_POSITIVES* or a *NO_FALSE_NEGATIVES* error type. +* *Merge* itself with another sketch object created from this class. +* *Serialize/Deserialize* to/from a byte array. + +**Space Usage** + +The sketch is initialized with a maximum map size, ``maxMapSize``, that specifies the maximum physical length of the internal hash map of the form ``(object item, int count)``. +The maximum map size is always a power of 2, defined through the variables ``lg_max_map_size``. + +The hash map starts at a very small size (8 entries) and grows as needed up to the specified maximum map size. + +Excluding external space required for the item objects, the internal memory space usage of this sketch is ``18 * mapSize`` bytes (assuming 8 bytes for each reference), +plus a small constant number of additional bytes. +The internal memory space usage of this sketch will never exceed ``18 * maxMapSize`` bytes, plus a small constant number of additional bytes. + +**Maximum Capacity of the Sketch** + +The ``LOAD_FACTOR`` for the hash map is internally set at :math:`75\%`, which means at any time the map capacity of ``(item, count)`` pairs is ``mapCap = 0.75 * mapSize``. +The maximum capacity of ``(item, count)`` pairs of the sketch is ``maxMapCap = 0.75 * maxMapSize``. + +**Updating the sketch with ``(item, count)`` pairs** + +If the item is found in the hash map, the mapped count field (the "counter") is incremented by the incoming count; otherwise, a new counter ``(item, count)`` pair is created. +If the number of tracked counters reaches the maximum capacity of the hash map, the sketch decrements all of the counters (by an approximately computed median) +and removes any non-positive counters. + +**Accuracy** + +If fewer than ``0.75 * maxMapSize`` different items are inserted into the sketch, the estimated frequencies returned by the sketch will be exact. + +The logic of the frequent items sketch is such that the stored counts and true counts are never too different. +More specifically, for any item, the sketch can return an estimate of the true frequency of item, along with upper and lower bounds on the frequency (that hold deterministically). + +For this implementation and for a specific active item, it is guaranteed that the true frequency will be between the Upper Bound (UB) and the Lower Bound (LB) computed for that item. +Specifically, ``(UB- LB) ≤ W * epsilon``, where :math:`W` denotes the sum of all item counts, and :math:`epsilon = 3.5/M`, where :math:`epsilon = M` is the maxMapSize. + +This is a worst-case guarantee that applies to arbitrary inputs. +For inputs typically seen in practice, ``(UB-LB)`` is usually much smaller. + +**Background** + +This code implements a variant of what is commonly known as the "Misra-Gries algorithm". +Variants of it were discovered and rediscovered and redesigned several times over the years: + +* *Finding repeated elements*, Misra, Gries, 1982 +* *Frequency estimation of Internet packet streams with limited space* Demaine, Lopez-Ortiz, Munro, 2002 +* *A simple algorithm for finding frequent elements in streams and bags* Karp, Shenker, Papadimitriou, 2003 +* *Efficient Computation of Frequent and Top-k Elements in Data Streams* Metwally, Agrawal, Abbadi, 2006 + + +For speed, we do employ some randomization that introduces a small probability that our proof of the worst-case bound might not apply to a given run. +However, we have ensured that this probability is extremely small. +For example, if the stream causes one table purge (rebuild), our proof of the worst-case bound applies with a probability of at least `1 - 1E-14`. +If the stream causes ``1E9`` purges, our proof applies with a probability of at least ``1 - 1E-5``. + +There are two flavors of Frequent Items Sketches, one with generic items (objects) and another specific to strings. +The string version is a legacy name from before the library supported generic objects and is retained +only for backwards compatibility. + +.. note:: + The :class:`frequent_items_sketch` uses an input object's ``__hash__`` and ``__eq__`` methods. + +.. note:: + Serializing and deserializing the :class:`frequent_items_sketch` requires the use of a :class:`PyObjectSerDe`. + +.. autoclass:: frequent_items_error_type + + .. autoattribute:: NO_FALSE_POSITIVES + :annotation: : Returns only true positives but may miss some heavy hitters. + + .. autoattribute:: NO_FALSE_NEGATIVES + :annotation: : Does not miss any heavy hitters but may return false positives. + + +.. autoclass:: frequent_items_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_epsilon_for_lg_size, get_apriori_error + :member-order: groupwise + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_epsilon_for_lg_size + .. automethod:: get_apriori_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + + +.. autoclass:: frequent_strings_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_epsilon_for_lg_size, get_apriori_error + :member-order: groupwise + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_epsilon_for_lg_size + .. automethod:: get_apriori_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ diff --git a/docs/5.0.1/_sources/frequency/index.rst.txt b/docs/5.0.1/_sources/frequency/index.rst.txt new file mode 100644 index 00000000..3cd3dfa5 --- /dev/null +++ b/docs/5.0.1/_sources/frequency/index.rst.txt @@ -0,0 +1,15 @@ +Frequency Sketches +================== + +Frequency estimation involves determining how often an item has been seen in a stream. The library currently +offers two types of sketches for frequency estimation, one of which has two closely-related variants. + + * :class:`frequent_items_sketch`: Identifies the *Top K* or *heavy hitters* in a stream, those items whose weight is above a certain percentage of the entire stream. Does not necessarily provide an estimate for most items outside the heavy hitters. + * :class:`frequent_strings_sketch`: Like the items version but containing snly strings (an implementation from before the library handled generic objects). + * :class:`count_min_sketch`: Provides an estimate for any item, regardless of relative weight, but does not maintain a list of the heaviest items. + +.. toctree:: + :maxdepth: 1 + + frequent_items + count_min_sketch \ No newline at end of file diff --git a/docs/5.0.1/_sources/helper/index.rst.txt b/docs/5.0.1/_sources/helper/index.rst.txt new file mode 100644 index 00000000..182b8e85 --- /dev/null +++ b/docs/5.0.1/_sources/helper/index.rst.txt @@ -0,0 +1,24 @@ +Helper Classes +============== + +.. currentmodule:: dataksetches + +These classes are required for certain sketches or specific +functionality within sketches. +Some of them are abstract base classes, but in those cases there is at +least one reference example of a concrete class. + + * :class:`serde` is used when serializing and deserializing sketches. + * :class:`jaccard` is used to compute the Jaccard similarity between pairs of theta or tuple sketches. + * :class:`tuple_policy` is required to use a :class:`tuple_sketch` by specifying how summaries are combined. + * :func:`ks_test` performs a Kolmogorov-Smirnov test on absolute-error quantiles family sketches. + * :class:`kernel_function` is required when using a :class:`kernel_sketch` for Kernel Density Estimation. + +.. toctree:: + :maxdepth: 1 + + serde + jaccard + tuple_policy + ks_test + kernel diff --git a/docs/5.0.1/_sources/helper/jaccard.rst.txt b/docs/5.0.1/_sources/helper/jaccard.rst.txt new file mode 100644 index 00000000..d3b9bfa3 --- /dev/null +++ b/docs/5.0.1/_sources/helper/jaccard.rst.txt @@ -0,0 +1,23 @@ +Jaccard Similarity +################## + +.. currentmodule:: datasketches + +These objects provide measures related to the `Jaccard similarity `_ +of :class:`theta_sketch` and :class:`tuple_sketch` objects. + +Note that there are separate classes to be used for theta and tuple sketches. + +.. autoclass:: theta_jaccard_similarity + + .. automethod:: jaccard + .. automethod:: exactly_equal + .. automethod:: similarity_test + .. automethod:: dissimilarity_test + +.. autoclass:: tuple_jaccard_similarity + + .. automethod:: jaccard + .. automethod:: exactly_equal + .. automethod:: similarity_test + .. automethod:: dissimilarity_test diff --git a/docs/5.0.1/_sources/helper/kernel.rst.txt b/docs/5.0.1/_sources/helper/kernel.rst.txt new file mode 100644 index 00000000..bdc2c729 --- /dev/null +++ b/docs/5.0.1/_sources/helper/kernel.rst.txt @@ -0,0 +1,21 @@ +Kernel Function +############### + +.. currentmodule:: datasketches + +A `kernel function `_ is a specific type of +mathematical funciton that is particularly useful in certain machine learning and pattern recognition +contexts. The :class:`density_sketch` performs approximate +`kernel density estimation `_ which, unsurprisingly, +relies on the use of such a kernel function. + +The library provides an abstract base class :class:`KernelFunction` and an example implementation of a +Gaussian (also known as a Radial Basis Function) kernel. Custom classes must override the base class +and provide a floating point value as a score indicating the similarity of two input vectors. + +.. autoclass:: KernelFunction + + .. automethod:: __call__ + +.. autoclass:: GaussianKernel + :show-inheritance: \ No newline at end of file diff --git a/docs/5.0.1/_sources/helper/ks_test.rst.txt b/docs/5.0.1/_sources/helper/ks_test.rst.txt new file mode 100644 index 00000000..c9bc19b0 --- /dev/null +++ b/docs/5.0.1/_sources/helper/ks_test.rst.txt @@ -0,0 +1,14 @@ +Kolmogorov-Smirnov Test +####################### + +.. currentmodule:: datasketches + +A `Kolmogorov-Smirnov Test `_` is +a test of equality of two distributions to determine if they are likely to have come from the same +underlying distribution. +The DataSketches library provides a modified form of the test that takes into account the error +in each underlying sketch in the analysis. + +Currently, the test assumes both input sketches are of the same family and data type. + +.. autofunction:: ks_test diff --git a/docs/5.0.1/_sources/helper/serde.rst.txt b/docs/5.0.1/_sources/helper/serde.rst.txt new file mode 100644 index 00000000..ccac1d84 --- /dev/null +++ b/docs/5.0.1/_sources/helper/serde.rst.txt @@ -0,0 +1,34 @@ +Serialize/Deserialize (SerDe) +############################# + +.. currentmodule:: datasketches + +A SerDe is a class used to serialize items sketches to a :class:`bytes` object in binary. +Several example SerDes are provided as references. + +The use of binary-compatible SerDes in different languages is critical for cross-language compatibility. + +Each implementation must extend the :class:`PyObjectSerDe` class and override all three of its methods. + +.. autoclass:: PyObjectSerDe + + .. automethod:: get_size + .. automethod:: to_bytes + .. automethod:: from_bytes + + +The provided SerDes are: + +.. autoclass:: PyStringsSerDe + :show-inheritance: + +.. autoclass:: PyIntsSerDe + :show-inheritance: + +.. autoclass:: PyLongsSerDe + :show-inheritance: + +.. autoclass:: PyFloatsSerDe + :show-inheritance: + +.. autoclass:: PyDoublesSerDe diff --git a/docs/5.0.1/_sources/helper/tuple_policy.rst.txt b/docs/5.0.1/_sources/helper/tuple_policy.rst.txt new file mode 100644 index 00000000..3f5781f2 --- /dev/null +++ b/docs/5.0.1/_sources/helper/tuple_policy.rst.txt @@ -0,0 +1,25 @@ +Tuple Policy +############ + +.. currentmodule:: datasketches + +A Tuple Policy is needed when using a :class:`tuple_sketch` in order to specify how the +summary values should be created, updated, combined, or intersected. A summary can consist of +any python object. + +Each implementation must extend the abstract base class :class:`TuplePolicy`. + +.. autoclass:: TuplePolicy + + .. automethod:: create_summary + .. automethod:: update_summary + .. automethod:: __call__ + +.. autoclass:: AccumulatorPolicy + :show-inheritance: + +.. autoclass:: MinIntPolicy + :show-inheritance: + +.. autoclass:: MaxIntPolicy + :show-inheritance: diff --git a/docs/5.0.1/_sources/index.rst.txt b/docs/5.0.1/_sources/index.rst.txt new file mode 100644 index 00000000..b683e1fd --- /dev/null +++ b/docs/5.0.1/_sources/index.rst.txt @@ -0,0 +1,73 @@ +.. datasketches documentation master file, created by + sphinx-quickstart on Tue Jul 25 11:04:59 2023. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Apache DataSketches +================================================= + +**DataSketches** are highly-efficient algorithms to analyze big data quickly. + + +Counting Distincts +################## +.. + maxdepth: 1 means only the heading is printed in the contents +.. toctree:: + :maxdepth: 2 + + distinct_counting/index + +Quantile Estimation +################### + +.. toctree:: + :maxdepth: 2 + + quantiles/index + +Frequency Sketches +################## +This problem may also be known as **heavy hitters** or **TopK** + +.. toctree:: + :maxdepth: 2 + + frequency/index + +Vector Sketches +############### + +.. toctree:: + :maxdepth: 2 + + vector/index + + +Random Sampling +############### + +.. toctree:: + :maxdepth: 2 + + sampling/index + +Helper Classes +############## + +.. toctree:: + :maxdepth: 2 + + helper/index + + +.. note:: + + This project is under active development. + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/docs/5.0.1/_sources/quantiles/index.rst.txt b/docs/5.0.1/_sources/quantiles/index.rst.txt new file mode 100644 index 00000000..b1928f67 --- /dev/null +++ b/docs/5.0.1/_sources/quantiles/index.rst.txt @@ -0,0 +1,26 @@ +Quantiles Sketches +================== + +Quantile estimation is useful for understanding the distribution of data values in a stream. The sketches currently +in the library are designed to answer queries about the `rank` of an item in the stream of items. That is, when +applying a global ordering on all the items, what is the portion of items seen so far that are less than (alternatively, +less-than-or-equal-to) the given item. Using straightforward logic, they can also estimate the item at a given rank +in the stream. + +These sketches may be used to compute approximate histograms, Probability Mass Functions (PMFs), or +Cumulative Distribution Functions (CDFs). + +The library provides three types of quantiles sketches, each of which has generic items as well as versions +specific to a given numeric type (e.g. integer or floating point values). All three types provide error +bounds on rank estimation with proven probabilistic error distributions. + + * KLL: Provides uniform rank estimation error over the entire range + * REQ: Provides relative rank error estimates, which decreases approaching either the high or low end values. + * Classic quantiles: Largely deprecated in favor of KLL, also provides uniform rank estimation error. Included largely for backwards compatibility with historic data. + +.. toctree:: + :maxdepth: 1 + + kll + req + quantiles_depr \ No newline at end of file diff --git a/docs/5.0.1/_sources/quantiles/kll.rst.txt b/docs/5.0.1/_sources/quantiles/kll.rst.txt new file mode 100644 index 00000000..0e54b443 --- /dev/null +++ b/docs/5.0.1/_sources/quantiles/kll.rst.txt @@ -0,0 +1,171 @@ +KLL Sketch +---------- + +.. currentmodule:: datasketches + +Implementation of a very compact quantiles sketch with lazy compaction scheme +and nearly optimal accuracy per retained item. +See `Optimal Quantile Approximation in Streams`. + +This is a stochastic streaming sketch that enables near real-time analysis of the +approximate distribution of items from a very large stream in a single pass, requiring only +that the items are comparable. +The analysis is obtained using `get_quantile()` function or the +inverse functions `get_rank()`, `get_pmf()` (Probability Mass Function), and `get_cdf()` +(Cumulative Distribution Function). + +As of May 2020, this implementation produces serialized sketches which are binary-compatible +with the equivalent Java implementation only when template parameter `T = float` +(32-bit single precision values). + +Given an input stream of `N` items, the `natural rank` of any specific +item is defined as its index `(1 to N)` in inclusive mode +or `(0 to N-1)` in exclusive mode +in the hypothetical sorted stream of all `N` input items. + +The `normalized rank` (`rank`) of any specific item is defined as its +`natural rank` divided by `N`. +Thus, the `normalized rank` is between zero and one. +In the documentation for this sketch `natural rank` is never used so any +reference to just `rank` should be interpreted to mean `normalized rank`. + +This sketch is configured with a parameter `k`, which affects the size of the sketch +and its estimation error. + +The estimation error is commonly called `epsilon` (or `eps`) and is a fraction +between zero and one. Larger values of `k` result in smaller values of `epsilon`. +Epsilon is always with respect to the rank and cannot be applied to the +corresponding items. + +The relationship between the `normalized rank` and the corresponding items can be viewed +as a two-dimensional monotonic plot with the `normalized rank` on one axis and the +corresponding items on the other axis. If the y-axis is specified as the item-axis and +the x-axis as the `normalized rank`, then `y = get_quantile(x)` is a monotonically +increasing function. + +The function `get_quantile(rank)` translates ranks into +corresponding quantiles. The functions `get_rank(item)`, +`get_cdf(...)` (Cumulative Distribution Function), and `get_pmf(...)` +(Probability Mass Function) perform the opposite operation and translate items into ranks. + +The `get_pmf(...)` function has about 13 to 47% worse rank error (depending +on `k`) than the other queries because the mass of each "bin" of the PMF has +"double-sided" error from the upper and lower edges of the bin as a result of a subtraction, +as the errors from the two edges can sometimes add. + +The default `k` of 200 yields a "single-sided" `epsilon` of about 1.33% and a +"double-sided" (PMF) `epsilon` of about 1.65%. + +A `get_quantile(rank)` query has the following guarantees: +- Let `q = get_quantile(r)` where `r` is the rank between zero and one. +- The quantile `q` will be an item from the input stream. +- Let `true_rank` be the true rank of `q` derived from the hypothetical sorted +stream of all `N` items. +- Let `eps = get_normalized_rank_error(false)`. +- Then `r - eps ≤ true_rank ≤ r + eps` with a confidence of 99%. Note that the +error is on the rank, not the quantile. + +A `get_rank(item)` query has the following guarantees: +- Let `r = get_rank(i)` where `i` is an item between the min and max items of +the input stream. +- Let `true_rank` be the true rank of `i` derived from the hypothetical sorted +stream of all `N` items. +- Let `eps = get_normalized_rank_error(false)`. +- Then `r - eps ≤ true_rank ≤ r + eps` with a confidence of 99%. + +A `get_pmf()` query has the following guarantees: +- Let `{r1, r2, ..., r(m+1)} = get_pmf(s1, s2, ..., sm)` where `s1, s2` are +split points (items from the input domain) between the min and max items of +the input stream. +- Let `mass_i = estimated mass between s_i and s_i+1`. +- Let `true_mass` be the true mass between the items of `s_i`, +`s_i+1` derived from the hypothetical sorted stream of all `N` items. +- Let `eps = get_normalized_rank_error(true)`. +- then `mass - eps ≤ true_mass ≤ mass + eps` with a confidence of 99%. +- `r(m+1)` includes the mass of all points larger than `s_m`. + +A `get_cdf(...)` query has the following guarantees; +- Let `{r1, r2, ..., r(m+1)} = get_cdf(s1, s2, ..., sm)` where `s1, s2, ...` are +split points (items from the input domain) between the min and max items of +the input stream. +- Let `mass_i = r_(i+1) - r_i`. +- Let `true_mass` be the true mass between the true ranks of `s_i`, +`s_i+1` derived from the hypothetical sorted stream of all `N` items. +- Let `eps = get_normalized_rank_error(true)`. +- then `mass - eps ≤ true_mass ≤ mass + eps` with a confidence of 99%. +- `1 - r(m+1)` includes the mass of all points larger than `s_m`. + +From the above, it might seem like we could make some estimates to bound the +`item` returned from a call to `get_quantile()`. The sketch, however, does not +let us derive error bounds or confidences around items. Because errors are independent, we +can approximately bracket a value as shown below, but there are no error estimates available. +Additionally, the interval may be quite large for certain distributions. +- Let `q = get_quantile(r)`, the estimated quantile of rank `r`. +- Let `eps = get_normalized_rank_error(false)`. +- Let `q_lo = estimated quantile of rank (r - eps)`. +- Let `q_hi = estimated quantile of rank (r + eps)`. +- Then `q_lo ≤ q ≤ q_hi`, with 99% confidence. + +.. note:: + For the :class:`kll_items_sketch`, objects must be comparable with ``__lt__``. + +.. note:: + Serializing and deserializing a :class:`kll_items_sketch` requires the use of a :class:`PyObjectSerDe`. + + +.. autoclass:: kll_ints_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_normalized_rank_error + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_normalized_rank_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: kll_floats_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_normalized_rank_error + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_normalized_rank_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: kll_doubles_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_normalized_rank_error + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_normalized_rank_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: kll_items_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_normalized_rank_error + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_normalized_rank_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + diff --git a/docs/5.0.1/_sources/quantiles/quantiles_depr.rst.txt b/docs/5.0.1/_sources/quantiles/quantiles_depr.rst.txt new file mode 100644 index 00000000..18dd5df6 --- /dev/null +++ b/docs/5.0.1/_sources/quantiles/quantiles_depr.rst.txt @@ -0,0 +1,106 @@ +Quantiles Sketch (Deprecated) +----------------------------- + +.. currentmodule:: datasketches + +This is a deprecated quantiles sketch that is included for cross-language compatibility. +Most new projects will favor the KLL sketch over this one, or the REQ sketch for higher accuracy +at the very edge of a distribution. + +This is a stochastic streaming sketch that enables near-real time analysis of the +approximate distribution from a very large stream in a single pass. +The analysis is obtained using `get_rank()` and `get_quantile()` functions, +the Probability Mass Function from `get_pmf()`` and the Cumulative Distribution Function from `get_cdf`. + +Consider a large stream of one million values such as packet sizes coming into a network node. +The natural rank of any specific size value is its index in the hypothetical sorted +array of values. +The normalized rank is the natural rank divided by the stream size, +in this case one million. +The value corresponding to the normalized rank of `0.5` represents the 50th percentile or median +value of the distribution, or `get_quantile(0.5)`. +Similarly, the 95th percentile is obtained from `get_quantile(0.95)`. + +From the min and max values, for example, 1 and 1000 bytes, +you can obtain the PMF from `get_pmf(100, 500, 900)` that will result in an array of +4 fractional values such as {.4, .3, .2, .1}, which means that +40% of the values were < 100, +30% of the values were ≥ 100 and < 500, +20% of the values were ≥ 500 and < 900, and +10% of the values were ≥ 900. +A frequency histogram can be obtained by multiplying these fractions by `get_n()`, +which is the total count of values received. +The `get_cdf()`` works similarly, but produces the cumulative distribution instead. + +As of November 2021, this implementation produces serialized sketches which are binary-compatible +with the equivalent Java implementation only when template parameter T = double +(64-bit double precision values). + +The accuracy of this sketch is a function of the configured value `k`, which also affects +the overall size of the sketch. Accuracy of this quantile sketch is always with respect to +the normalized rank. A `k` of 128 produces a normalized, rank error of about 1.7%. +For example, the median item returned from `get_quantile(0.5)` will be between the actual items +from the hypothetically sorted array of input items at normalized ranks of 0.483 and 0.517, with +a confidence of about 99%. + +.. note:: + For the :class:`quantiles_items_sketch`, objects must be comparable with ``__lt__``. + +.. note:: + Serializing and deserializing a :class:`quantiles_items_sketch` requires the use of a :class:`PyObjectSerDe`. + +.. autoclass:: quantiles_ints_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_normalized_rank_error + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_normalized_rank_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: quantiles_floats_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_normalized_rank_error + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_normalized_rank_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: quantiles_doubles_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_normalized_rank_error + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_normalized_rank_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: quantiles_items_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_normalized_rank_error + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_normalized_rank_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ diff --git a/docs/5.0.1/_sources/quantiles/req.rst.txt b/docs/5.0.1/_sources/quantiles/req.rst.txt new file mode 100644 index 00000000..3f63e01e --- /dev/null +++ b/docs/5.0.1/_sources/quantiles/req.rst.txt @@ -0,0 +1,79 @@ +Relative Error Quantiles (REQ) Sketch +------------------------------------- + +.. currentmodule:: datasketches + +This is an implementation based on the `paper `_ "Relative Error Streaming Quantiles" by Graham Cormode, Zohar Karnin, Edo Liberty, Justin Thaler, Pavel Veselý, and loosely derived from a Python prototype written by Pavel Veselý. + +This implementation differs from the algorithm described in the paper in the following: + +The algorithm requires no upper bound on the stream length. +Instead, each relative-compactor counts the number of compaction operations performed so far (via variable state). +Initially, the relative-compactor starts with `INIT_NUMBER_OF_SECTIONS`. +Each time the number of compactions `(variable state) exceeds 2^{numSections - 1}`, we double `numSections`. +Note that after merging the sketch with another one variable state may not correspond to the number of compactions performed at a particular level, however, +since the state variable never exceeds the number of compactions, the guarantees of the sketch remain valid. + +The size of each section (variable `k` and `section_size` in the code and parameter `k` in the paper) is +initialized with a number set by the user via variable `k`. +When the number of sections doubles, we decrease section_size by a factor of `sqrt(2)`. +This is applied at each level separately. +Thus, when we double the number of sections, the nominal compactor size increases by a factor of approx. `sqrt(2) (+/- rounding)`. + +The merge operation here does not perform "special compactions", which are used in the paper to allow for a tight mathematical analysis of the sketch. +This implementation provides a number of capabilities not discussed in the paper or provided in the Python prototype. + +The Python prototype only implemented high accuracy for low ranks. This implementation provides the user with the ability to +choose either high rank accuracy or low rank accuracy at the time of sketch construction. +The Python prototype only implemented a comparison criterion of `INCLUSIVE`. +This implementation allows the user to use both the `INCLUSIVE` criterion and the `EXCLUSIVE` criterion. +This implementation provides extensive debug visibility into the operation of the sketch with two levels of detail output. +This is not only useful for debugging, but is a powerful tool to help users understand how the sketch works. + +.. note:: + For the :class:`req_items_sketch`, objects must be comparable with ``__lt__``. + +.. note:: + Serializing and deserializing a :class:`req_items_sketch` requires the use of a :class:`PyObjectSerDe`. + +.. autoclass:: req_ints_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_RSE + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_RSE + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: req_floats_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_RSE + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_RSE + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: req_items_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_RSE + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_RSE + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ diff --git a/docs/5.0.1/_sources/sampling/ebpps.rst.txt b/docs/5.0.1/_sources/sampling/ebpps.rst.txt new file mode 100644 index 00000000..b2253209 --- /dev/null +++ b/docs/5.0.1/_sources/sampling/ebpps.rst.txt @@ -0,0 +1,33 @@ +Exact and Bounded, Probabilitiy Proportional to Size (EBPPS) Sampling +--------------------------------------------------------------------- + +.. currentmodule:: datasketches + +An EBPPS sketch produces a randome sample of data from a stream of items, ensuring that the probability +of including an item is always exactly equal to the item's size. The size of an item is defined as its +weight relative to the total weight of all items seen so far by the sketch. In contrast to VarOpt sampling, +this sketch may return fewer than `k` items in order to keep the probability of including an item strictly +proportional to its size. + +This sketch is based on: B. Hentschel, P. J. Haas, Y. Tian +"Exact PPS Sampling with Bounded Sample Size", +Information Processing Letters, 2023. + +EBPPS sampling is related to reservoir sampling, but handles unequal item weights. +Feeding the sketch items with a uniform weight value will produce a sample equivalent to reservoir sampling. + +.. note:: + Serializing and deserializing this sketch requires the use of a :class:`PyObjectSerDe`. + +.. autoclass:: ebpps_sketch + :members: + :undoc-members: + :exclude-members: deserialize + + .. rubric:: Static Methods: + + .. automethod:: deserialize + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ diff --git a/docs/5.0.1/_sources/sampling/index.rst.txt b/docs/5.0.1/_sources/sampling/index.rst.txt new file mode 100644 index 00000000..fca6c3ce --- /dev/null +++ b/docs/5.0.1/_sources/sampling/index.rst.txt @@ -0,0 +1,21 @@ +Random Sampling Sketches +======================== + +.. currentmodule:: datasketches + +These sketches are used to randomly sample items. The length of the input +stream does not need to be known in advance. + +Both VarOpt (Variance Optimal) and EBPPS (Exact and Bounded, +Probability Proportional to Size) sketches will include sample items based on +each item's weight relative to the weight of the entire stream but +they differ in details: + + * :class:`ebpps_sketch` ensures that the probability of including an item is always exactly proportional to the item's weight. + * :class:`var_opt_sketch` optimizes for applying a predicate to the resulting sample such that the variance of the subset sum after applying the predicate is minimized, even if the inclusion probability differs somewhat from being proportional to the item's weight. + +.. toctree:: + :maxdepth: 1 + + varopt + ebpps diff --git a/docs/5.0.1/_sources/sampling/varopt.rst.txt b/docs/5.0.1/_sources/sampling/varopt.rst.txt new file mode 100644 index 00000000..d837835e --- /dev/null +++ b/docs/5.0.1/_sources/sampling/varopt.rst.txt @@ -0,0 +1,42 @@ +Variance Optimal Sampling (VarOpt) +---------------------------------- + +.. currentmodule:: datasketches + +A VarOpt sketch samples data from a stream of items. The sketch is desinged for optimal (minimum) +variance when querying the sketch to estimate subset sums of items matching a provided predicate. +The sketch will produce a sample of size `k` (or smaller if fewer items have been presented), with +the probability of including an item roughly corresponding it the item's weight relative to the total +weight of all items presented to the sketch. + +VarOpt sampling is related to reservoir sampling, with improved error bounds for subset sum estimation. +Feeding the sketch items with a uniform weight value will produce a sample equivalent to reservoir sampling. + +.. note:: + Serializing and deserializing this sketch requires the use of a :class:`PyObjectSerDe`. + +.. autoclass:: var_opt_sketch + :members: + :undoc-members: + :exclude-members: deserialize + + .. rubric:: Static Methods: + + .. automethod:: deserialize + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: var_opt_union + :members: + :undoc-members: + :exclude-members: deserialize + + .. rubric:: Static Methods: + + .. automethod:: deserialize + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ diff --git a/docs/5.0.1/_sources/vector/density_sketch.rst.txt b/docs/5.0.1/_sources/vector/density_sketch.rst.txt new file mode 100644 index 00000000..07d83181 --- /dev/null +++ b/docs/5.0.1/_sources/vector/density_sketch.rst.txt @@ -0,0 +1,28 @@ +Density Sketch +-------------- + +.. currentmodule:: datasketches + +Builds a coreset from the given set of input points. +Provides density estimate at a given point. + +Based on the following paper: Zohar Karnin, Edo Liberty +"Discrepancy, Coresets, and Sketches in Machine Learning" +https://proceedings.mlr.press/v99/karnin19a/karnin19a.pdf + +Inspired by the following implementation: https://github.com/edoliberty/streaming-quantiles/blob/f688c8161a25582457b0a09deb4630a81406293b/gde.py + +Requires the use of a :class:`KernelFunction` to compute the distance between two vectors. + +.. autoclass:: density_sketch + :members: + :undoc-members: + :exclude-members: deserialize + + .. rubric:: Static Methods: + + .. automethod:: deserialize + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ diff --git a/docs/5.0.1/_sources/vector/index.rst.txt b/docs/5.0.1/_sources/vector/index.rst.txt new file mode 100644 index 00000000..1b83a43c --- /dev/null +++ b/docs/5.0.1/_sources/vector/index.rst.txt @@ -0,0 +1,12 @@ +Vector Sketches +================== + +.. currentmodule:: dataksetches + +These sketches are designed to accept vector inputs. For now, the library provides only the +:class:`density_sketch` for Kernel Density Estimation. + +.. toctree:: + :maxdepth: 1 + + density_sketch \ No newline at end of file diff --git a/docs/5.0.1/_static/_sphinx_javascript_frameworks_compat.js b/docs/5.0.1/_static/_sphinx_javascript_frameworks_compat.js new file mode 100644 index 00000000..81415803 --- /dev/null +++ b/docs/5.0.1/_static/_sphinx_javascript_frameworks_compat.js @@ -0,0 +1,123 @@ +/* Compatability shim for jQuery and underscores.js. + * + * Copyright Sphinx contributors + * Released under the two clause BSD licence + */ + +/** + * small helper function to urldecode strings + * + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL + */ +jQuery.urldecode = function(x) { + if (!x) { + return x + } + return decodeURIComponent(x.replace(/\+/g, ' ')); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s === 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node, addItems) { + if (node.nodeType === 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && + !jQuery(node.parentNode).hasClass(className) && + !jQuery(node.parentNode).hasClass("nohighlight")) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.className = className; + } + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + if (isInSVG) { + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + var bbox = node.parentElement.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": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} diff --git a/docs/5.0.1/_static/basic.css b/docs/5.0.1/_static/basic.css new file mode 100644 index 00000000..f316efcb --- /dev/null +++ b/docs/5.0.1/_static/basic.css @@ -0,0 +1,925 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- 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: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +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/docs/5.0.1/_static/css/badge_only.css b/docs/5.0.1/_static/css/badge_only.css new file mode 100644 index 00000000..c718cee4 --- /dev/null +++ b/docs/5.0.1/_static/css/badge_only.css @@ -0,0 +1 @@ +.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}} \ No newline at end of file diff --git a/docs/5.0.1/_static/css/fonts/Roboto-Slab-Bold.woff b/docs/5.0.1/_static/css/fonts/Roboto-Slab-Bold.woff new file mode 100644 index 00000000..6cb60000 Binary files /dev/null and b/docs/5.0.1/_static/css/fonts/Roboto-Slab-Bold.woff differ diff --git a/docs/5.0.1/_static/css/fonts/Roboto-Slab-Bold.woff2 b/docs/5.0.1/_static/css/fonts/Roboto-Slab-Bold.woff2 new file mode 100644 index 00000000..7059e231 Binary files /dev/null and b/docs/5.0.1/_static/css/fonts/Roboto-Slab-Bold.woff2 differ diff --git a/docs/5.0.1/_static/css/fonts/Roboto-Slab-Regular.woff b/docs/5.0.1/_static/css/fonts/Roboto-Slab-Regular.woff new file mode 100644 index 00000000..f815f63f Binary files /dev/null and b/docs/5.0.1/_static/css/fonts/Roboto-Slab-Regular.woff differ diff --git a/docs/5.0.1/_static/css/fonts/Roboto-Slab-Regular.woff2 b/docs/5.0.1/_static/css/fonts/Roboto-Slab-Regular.woff2 new file mode 100644 index 00000000..f2c76e5b Binary files /dev/null and b/docs/5.0.1/_static/css/fonts/Roboto-Slab-Regular.woff2 differ diff --git a/docs/5.0.1/_static/css/fonts/fontawesome-webfont.eot b/docs/5.0.1/_static/css/fonts/fontawesome-webfont.eot new file mode 100644 index 00000000..e9f60ca9 Binary files /dev/null and b/docs/5.0.1/_static/css/fonts/fontawesome-webfont.eot differ diff --git a/docs/5.0.1/_static/css/fonts/fontawesome-webfont.svg b/docs/5.0.1/_static/css/fonts/fontawesome-webfont.svg new file mode 100644 index 00000000..855c845e --- /dev/null +++ b/docs/5.0.1/_static/css/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/5.0.1/_static/css/fonts/fontawesome-webfont.ttf b/docs/5.0.1/_static/css/fonts/fontawesome-webfont.ttf new file mode 100644 index 00000000..35acda2f Binary files /dev/null and b/docs/5.0.1/_static/css/fonts/fontawesome-webfont.ttf differ diff --git a/docs/5.0.1/_static/css/fonts/fontawesome-webfont.woff b/docs/5.0.1/_static/css/fonts/fontawesome-webfont.woff new file mode 100644 index 00000000..400014a4 Binary files /dev/null and b/docs/5.0.1/_static/css/fonts/fontawesome-webfont.woff differ diff --git a/docs/5.0.1/_static/css/fonts/fontawesome-webfont.woff2 b/docs/5.0.1/_static/css/fonts/fontawesome-webfont.woff2 new file mode 100644 index 00000000..4d13fc60 Binary files /dev/null and b/docs/5.0.1/_static/css/fonts/fontawesome-webfont.woff2 differ diff --git a/docs/5.0.1/_static/css/fonts/lato-bold-italic.woff b/docs/5.0.1/_static/css/fonts/lato-bold-italic.woff new file mode 100644 index 00000000..88ad05b9 Binary files /dev/null and b/docs/5.0.1/_static/css/fonts/lato-bold-italic.woff differ diff --git a/docs/5.0.1/_static/css/fonts/lato-bold-italic.woff2 b/docs/5.0.1/_static/css/fonts/lato-bold-italic.woff2 new file mode 100644 index 00000000..c4e3d804 Binary files /dev/null and b/docs/5.0.1/_static/css/fonts/lato-bold-italic.woff2 differ diff --git a/docs/5.0.1/_static/css/fonts/lato-bold.woff b/docs/5.0.1/_static/css/fonts/lato-bold.woff new file mode 100644 index 00000000..c6dff51f Binary files /dev/null and b/docs/5.0.1/_static/css/fonts/lato-bold.woff differ diff --git a/docs/5.0.1/_static/css/fonts/lato-bold.woff2 b/docs/5.0.1/_static/css/fonts/lato-bold.woff2 new file mode 100644 index 00000000..bb195043 Binary files /dev/null and b/docs/5.0.1/_static/css/fonts/lato-bold.woff2 differ diff --git a/docs/5.0.1/_static/css/fonts/lato-normal-italic.woff b/docs/5.0.1/_static/css/fonts/lato-normal-italic.woff new file mode 100644 index 00000000..76114bc0 Binary files /dev/null and b/docs/5.0.1/_static/css/fonts/lato-normal-italic.woff differ diff --git a/docs/5.0.1/_static/css/fonts/lato-normal-italic.woff2 b/docs/5.0.1/_static/css/fonts/lato-normal-italic.woff2 new file mode 100644 index 00000000..3404f37e Binary files /dev/null and b/docs/5.0.1/_static/css/fonts/lato-normal-italic.woff2 differ diff --git a/docs/5.0.1/_static/css/fonts/lato-normal.woff b/docs/5.0.1/_static/css/fonts/lato-normal.woff new file mode 100644 index 00000000..ae1307ff Binary files /dev/null and b/docs/5.0.1/_static/css/fonts/lato-normal.woff differ diff --git a/docs/5.0.1/_static/css/fonts/lato-normal.woff2 b/docs/5.0.1/_static/css/fonts/lato-normal.woff2 new file mode 100644 index 00000000..3bf98433 Binary files /dev/null and b/docs/5.0.1/_static/css/fonts/lato-normal.woff2 differ diff --git a/docs/5.0.1/_static/css/theme.css b/docs/5.0.1/_static/css/theme.css new file mode 100644 index 00000000..19a446a0 --- /dev/null +++ b/docs/5.0.1/_static/css/theme.css @@ -0,0 +1,4 @@ +html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden],audio:not([controls]){display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;text-decoration:none}ins,mark{color:#000}mark{background:#ff0;font-style:italic;font-weight:700}.rst-content code,.rst-content tt,code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:after,q:before{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,ol,ul{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure,form{margin:0}label{cursor:pointer}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{body,html,section{background:none!important}*{box-shadow:none!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}.rst-content .toctree-wrapper>p.caption,h2,h3,p{orphans:3;widows:3}.rst-content .toctree-wrapper>p.caption,h2,h3{page-break-after:avoid}}.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .eqno .headerlink:before,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .eqno .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a button.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-left.toctree-expand,.wy-menu-vertical li button.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .eqno .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a button.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-right.toctree-expand,.wy-menu-vertical li button.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .eqno .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a button.pull-left.toctree-expand,.wy-menu-vertical li.on a button.pull-left.toctree-expand,.wy-menu-vertical li button.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .eqno .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a button.pull-right.toctree-expand,.wy-menu-vertical li.on a button.pull-right.toctree-expand,.wy-menu-vertical li button.pull-right.toctree-expand{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li button.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content .eqno a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content p a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li a button.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content .eqno .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content p .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li button.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content .eqno .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a button.toctree-expand,.btn .wy-menu-vertical li.on a button.toctree-expand,.btn .wy-menu-vertical li button.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content .eqno .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a button.toctree-expand,.nav .wy-menu-vertical li.on a button.toctree-expand,.nav .wy-menu-vertical li button.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .eqno .btn .headerlink,.rst-content .eqno .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p .btn .headerlink,.rst-content p .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn button.toctree-expand,.wy-menu-vertical li.current>a .btn button.toctree-expand,.wy-menu-vertical li.current>a .nav button.toctree-expand,.wy-menu-vertical li .nav button.toctree-expand,.wy-menu-vertical li.on a .btn button.toctree-expand,.wy-menu-vertical li.on a .nav button.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .eqno .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li button.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .eqno .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li button.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .eqno .btn .fa-large.headerlink,.rst-content .eqno .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p .btn .fa-large.headerlink,.rst-content p .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn button.fa-large.toctree-expand,.wy-menu-vertical li .nav button.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .eqno .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li button.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .eqno .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li button.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .eqno .btn .fa-spin.headerlink,.rst-content .eqno .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p .btn .fa-spin.headerlink,.rst-content p .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn button.fa-spin.toctree-expand,.wy-menu-vertical li .nav button.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content .eqno .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li button.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content .eqno .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li button.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content .eqno .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li button.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content .eqno .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini button.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.rst-content section ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.rst-content section ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.rst-content section ul li p:last-child,.rst-content section ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.rst-content section ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.rst-content section ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.rst-content section ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content .section ol.arabic,.rst-content .toctree-wrapper ol,.rst-content .toctree-wrapper ol.arabic,.rst-content section ol,.rst-content section ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol.arabic li,.rst-content .section ol li,.rst-content .toctree-wrapper ol.arabic li,.rst-content .toctree-wrapper ol li,.rst-content section ol.arabic li,.rst-content section ol li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol.arabic li ul,.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content .toctree-wrapper ol.arabic li ul,.rst-content .toctree-wrapper ol li p:last-child,.rst-content .toctree-wrapper ol li ul,.rst-content section ol.arabic li ul,.rst-content section ol li p:last-child,.rst-content section ol li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol.arabic li ul li,.rst-content .section ol li ul li,.rst-content .toctree-wrapper ol.arabic li ul li,.rst-content .toctree-wrapper ol li ul li,.rst-content section ol.arabic li ul li,.rst-content section ol li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs>li{display:inline-block;padding-top:5px}.wy-breadcrumbs>li.wy-breadcrumbs-aside{float:right}.rst-content .wy-breadcrumbs>li code,.rst-content .wy-breadcrumbs>li tt,.wy-breadcrumbs>li .rst-content tt,.wy-breadcrumbs>li code{all:inherit;color:inherit}.breadcrumb-item:before{content:"/";color:#bbb;font-size:13px;padding:0 6px 0 3px}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li button.toctree-expand{display:block;float:left;margin-left:-1.2em;line-height:18px;color:#4d4d4d;border:none;background:none;padding:0}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover button.toctree-expand,.wy-menu-vertical li.on a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand{display:block;line-height:18px;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{padding:.4045em 1.618em .4045em 4.045em}.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{padding:.4045em 1.618em .4045em 5.663em}.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a{padding:.4045em 1.618em .4045em 7.281em}.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a{padding:.4045em 1.618em .4045em 8.899em}.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a{padding:.4045em 1.618em .4045em 10.517em}.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a{padding:.4045em 1.618em .4045em 12.135em}.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a{padding:.4045em 1.618em .4045em 13.753em}.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a{padding:.4045em 1.618em .4045em 15.371em}.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 1.618em .4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 button.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 button.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover button.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active button.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em;max-width:100%}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search>a:hover{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.version{margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .eqno .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content .eqno .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}.rst-content .toctree-wrapper>p.caption,.rst-content h1,.rst-content h2,.rst-content h3,.rst-content h4,.rst-content h5,.rst-content h6{margin-bottom:24px}.rst-content img{max-width:100%;height:auto}.rst-content div.figure,.rst-content figure{margin-bottom:24px}.rst-content div.figure .caption-text,.rst-content figure .caption-text{font-style:italic}.rst-content div.figure p:last-child.caption,.rst-content figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center,.rst-content figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img,.rst-content section>a>img,.rst-content section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp,.rst-content div.highlight span.linenos{user-select:none;pointer-events:none}.rst-content div.highlight span.linenos{display:inline-block;padding-left:0;padding-right:12px;margin-right:12px;border-right:1px solid #e6e9ea}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li,.rst-content .toctree-wrapper ol.loweralpha,.rst-content .toctree-wrapper ol.loweralpha>li,.rst-content section ol.loweralpha,.rst-content section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li,.rst-content .toctree-wrapper ol.upperalpha,.rst-content .toctree-wrapper ol.upperalpha>li,.rst-content section ol.upperalpha,.rst-content section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*,.rst-content .toctree-wrapper ol li>*,.rst-content .toctree-wrapper ul li>*,.rst-content section ol li>*,.rst-content section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child,.rst-content .toctree-wrapper ol li>:first-child,.rst-content .toctree-wrapper ul li>:first-child,.rst-content section ol li>:first-child,.rst-content section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child,.rst-content .toctree-wrapper ol li>p,.rst-content .toctree-wrapper ol li>p:last-child,.rst-content .toctree-wrapper ul li>p,.rst-content .toctree-wrapper ul li>p:last-child,.rst-content section ol li>p,.rst-content section ol li>p:last-child,.rst-content section ul li>p,.rst-content section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child,.rst-content .toctree-wrapper ol li>p:only-child,.rst-content .toctree-wrapper ol li>p:only-child:last-child,.rst-content .toctree-wrapper ul li>p:only-child,.rst-content .toctree-wrapper ul li>p:only-child:last-child,.rst-content section ol li>p:only-child,.rst-content section ol li>p:only-child:last-child,.rst-content section ul li>p:only-child,.rst-content section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul,.rst-content .toctree-wrapper ol li>ol,.rst-content .toctree-wrapper ol li>ul,.rst-content .toctree-wrapper ul li>ol,.rst-content .toctree-wrapper ul li>ul,.rst-content section ol li>ol,.rst-content section ol li>ul,.rst-content section ul li>ol,.rst-content section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul,.rst-content .toctree-wrapper ol.simple li>*,.rst-content .toctree-wrapper ol.simple li ol,.rst-content .toctree-wrapper ol.simple li ul,.rst-content .toctree-wrapper ul.simple li>*,.rst-content .toctree-wrapper ul.simple li ol,.rst-content .toctree-wrapper ul.simple li ul,.rst-content section ol.simple li>*,.rst-content section ol.simple li ol,.rst-content section ol.simple li ul,.rst-content section ul.simple li>*,.rst-content section ul.simple li ol,.rst-content section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink{opacity:0;font-size:14px;font-family:FontAwesome;margin-left:.5em}.rst-content .code-block-caption .headerlink:focus,.rst-content .code-block-caption:hover .headerlink,.rst-content .eqno .headerlink:focus,.rst-content .eqno:hover .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink:focus,.rst-content .toctree-wrapper>p.caption:hover .headerlink,.rst-content dl dt .headerlink:focus,.rst-content dl dt:hover .headerlink,.rst-content h1 .headerlink:focus,.rst-content h1:hover .headerlink,.rst-content h2 .headerlink:focus,.rst-content h2:hover .headerlink,.rst-content h3 .headerlink:focus,.rst-content h3:hover .headerlink,.rst-content h4 .headerlink:focus,.rst-content h4:hover .headerlink,.rst-content h5 .headerlink:focus,.rst-content h5:hover .headerlink,.rst-content h6 .headerlink:focus,.rst-content h6:hover .headerlink,.rst-content p.caption .headerlink:focus,.rst-content p.caption:hover .headerlink,.rst-content p .headerlink:focus,.rst-content p:hover .headerlink,.rst-content table>caption .headerlink:focus,.rst-content table>caption:hover .headerlink{opacity:1}.rst-content p a{overflow-wrap:anywhere}.rst-content .wy-table td p,.rst-content .wy-table td ul,.rst-content .wy-table th p,.rst-content .wy-table th ul,.rst-content table.docutils td p,.rst-content table.docutils td ul,.rst-content table.docutils th p,.rst-content table.docutils th ul,.rst-content table.field-list td p,.rst-content table.field-list td ul,.rst-content table.field-list th p,.rst-content table.field-list th ul{font-size:inherit}.rst-content .btn:focus{outline:2px solid}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .citation-reference>span.fn-bracket,.rst-content .footnote-reference>span.fn-bracket{display:none}.rst-content .hlist{width:100%}.rst-content dl dt span.classifier:before{content:" : "}.rst-content dl dt span.classifier-delimiter{display:none!important}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:auto minmax(80%,95%)}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{display:inline-grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{display:grid;grid-template-columns:auto auto minmax(.65rem,auto) minmax(40%,95%)}html.writer-html5 .rst-content aside.citation>span.label,html.writer-html5 .rst-content aside.footnote>span.label,html.writer-html5 .rst-content div.citation>span.label{grid-column-start:1;grid-column-end:2}html.writer-html5 .rst-content aside.citation>span.backrefs,html.writer-html5 .rst-content aside.footnote>span.backrefs,html.writer-html5 .rst-content div.citation>span.backrefs{grid-column-start:2;grid-column-end:3;grid-row-start:1;grid-row-end:3}html.writer-html5 .rst-content aside.citation>p,html.writer-html5 .rst-content aside.footnote>p,html.writer-html5 .rst-content div.citation>p{grid-column-start:4;grid-column-end:5}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{margin-bottom:24px}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.citation>dt>span.brackets:before,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.citation>dt>span.brackets:after,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a{word-break:keep-all}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a:not(:first-child):before,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.citation>dd p,html.writer-html5 .rst-content dl.footnote>dd p{font-size:.9rem}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{padding-left:1rem;padding-right:1rem;font-size:.9rem;line-height:1.2rem}html.writer-html5 .rst-content aside.citation p,html.writer-html5 .rst-content aside.footnote p,html.writer-html5 .rst-content div.citation p{font-size:.9rem;line-height:1.2rem;margin-bottom:12px}html.writer-html5 .rst-content aside.citation span.backrefs,html.writer-html5 .rst-content aside.footnote span.backrefs,html.writer-html5 .rst-content div.citation span.backrefs{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content aside.citation span.backrefs>a,html.writer-html5 .rst-content aside.footnote span.backrefs>a,html.writer-html5 .rst-content div.citation span.backrefs>a{word-break:keep-all}html.writer-html5 .rst-content aside.citation span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content aside.footnote span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content div.citation span.backrefs>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content aside.citation span.label,html.writer-html5 .rst-content aside.footnote span.label,html.writer-html5 .rst-content div.citation span.label{line-height:1.2rem}html.writer-html5 .rst-content aside.citation-list,html.writer-html5 .rst-content aside.footnote-list,html.writer-html5 .rst-content div.citation-list{margin-bottom:24px}html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content aside.footnote-list aside.footnote,html.writer-html5 .rst-content div.citation-list>div.citation,html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content aside.footnote-list aside.footnote code,html.writer-html5 .rst-content aside.footnote-list aside.footnote tt,html.writer-html5 .rst-content aside.footnote code,html.writer-html5 .rst-content aside.footnote tt,html.writer-html5 .rst-content div.citation-list>div.citation code,html.writer-html5 .rst-content div.citation-list>div.citation tt,html.writer-html5 .rst-content dl.citation code,html.writer-html5 .rst-content dl.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c;white-space:normal}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040;overflow-wrap:normal}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}.rst-content dl dd>ol:last-child,.rst-content dl dd>p:last-child,.rst-content dl dd>table:last-child,.rst-content dl dd>ul:last-child{margin-bottom:0}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px;max-width:100%}html.writer-html4 .rst-content dl:not(.docutils) .k,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .k{font-style:italic}html.writer-html4 .rst-content dl:not(.docutils) .descclassname,html.writer-html4 .rst-content dl:not(.docutils) .descname,html.writer-html4 .rst-content dl:not(.docutils) .sig-name,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .sig-name{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#000}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel,.rst-content .menuselection{font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .guilabel,.rst-content .menuselection{border:1px solid #7fbbe3;background:#e7f2fa}.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>.kbd,.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>kbd{color:inherit;font-size:80%;background-color:#fff;border:1px solid #a6a6a6;border-radius:4px;box-shadow:0 2px grey;padding:2.4px 6px;margin:auto 0}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block} \ No newline at end of file diff --git a/docs/5.0.1/_static/doctools.js b/docs/5.0.1/_static/doctools.js new file mode 100644 index 00000000..4d67807d --- /dev/null +++ b/docs/5.0.1/_static/doctools.js @@ -0,0 +1,156 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Base JavaScript utilities for all Sphinx HTML documentation. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"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/docs/5.0.1/_static/documentation_options.js b/docs/5.0.1/_static/documentation_options.js new file mode 100644 index 00000000..e21c068c --- /dev/null +++ b/docs/5.0.1/_static/documentation_options.js @@ -0,0 +1,13 @@ +const DOCUMENTATION_OPTIONS = { + VERSION: '0.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/docs/5.0.1/_static/file.png b/docs/5.0.1/_static/file.png new file mode 100644 index 00000000..a858a410 Binary files /dev/null and b/docs/5.0.1/_static/file.png differ diff --git a/docs/5.0.1/_static/jquery.js b/docs/5.0.1/_static/jquery.js new file mode 100644 index 00000000..c4c6022f --- /dev/null +++ b/docs/5.0.1/_static/jquery.js @@ -0,0 +1,2 @@ +/*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=y.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=y.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),y.elements=c+" "+a,j(b)}function f(a){var b=x[a[v]];return b||(b={},w++,a[v]=w,x[w]=b),b}function g(a,c,d){if(c||(c=b),q)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():u.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||t.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),q)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return y.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(y,b.frag)}function j(a){a||(a=b);var d=f(a);return!y.shivCSS||p||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),q||i(a,d),a}function k(a){for(var b,c=a.getElementsByTagName("*"),e=c.length,f=RegExp("^(?:"+d().join("|")+")$","i"),g=[];e--;)b=c[e],f.test(b.nodeName)&&g.push(b.applyElement(l(b)));return g}function l(a){for(var b,c=a.attributes,d=c.length,e=a.ownerDocument.createElement(A+":"+a.nodeName);d--;)b=c[d],b.specified&&e.setAttribute(b.nodeName,b.nodeValue);return e.style.cssText=a.style.cssText,e}function m(a){for(var b,c=a.split("{"),e=c.length,f=RegExp("(^|[\\s,>+~])("+d().join("|")+")(?=[[\\s,>+~#.:]|$)","gi"),g="$1"+A+"\\:$2";e--;)b=c[e]=c[e].split("}"),b[b.length-1]=b[b.length-1].replace(f,g),c[e]=b.join("}");return c.join("{")}function n(a){for(var b=a.length;b--;)a[b].removeNode()}function o(a){function b(){clearTimeout(g._removeSheetTimer),d&&d.removeNode(!0),d=null}var d,e,g=f(a),h=a.namespaces,i=a.parentWindow;return!B||a.printShived?a:("undefined"==typeof h[A]&&h.add(A),i.attachEvent("onbeforeprint",function(){b();for(var f,g,h,i=a.styleSheets,j=[],l=i.length,n=Array(l);l--;)n[l]=i[l];for(;h=n.pop();)if(!h.disabled&&z.test(h.media)){try{f=h.imports,g=f.length}catch(o){g=0}for(l=0;g>l;l++)n.push(f[l]);try{j.push(h.cssText)}catch(o){}}j=m(j.reverse().join("")),e=k(a),d=c(a,j)}),i.attachEvent("onafterprint",function(){n(e),clearTimeout(g._removeSheetTimer),g._removeSheetTimer=setTimeout(b,500)}),a.printShived=!0,a)}var p,q,r="3.7.3",s=a.html5||{},t=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,u=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,v="_html5shiv",w=0,x={};!function(){try{var a=b.createElement("a");a.innerHTML="",p="hidden"in a,q=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){p=!0,q=!0}}();var y={elements:s.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:r,shivCSS:s.shivCSS!==!1,supportsUnknownElements:q,shivMethods:s.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=y,j(b);var z=/^$|\b(?:all|print)\b/,A="html5shiv",B=!q&&function(){var c=b.documentElement;return!("undefined"==typeof b.namespaces||"undefined"==typeof b.parentWindow||"undefined"==typeof c.applyElement||"undefined"==typeof c.removeNode||"undefined"==typeof a.attachEvent)}();y.type+=" print",y.shivPrint=o,o(b),"object"==typeof module&&module.exports&&(module.exports=y)}("undefined"!=typeof window?window:this,document); \ No newline at end of file diff --git a/docs/5.0.1/_static/js/html5shiv.min.js b/docs/5.0.1/_static/js/html5shiv.min.js new file mode 100644 index 00000000..cd1c674f --- /dev/null +++ b/docs/5.0.1/_static/js/html5shiv.min.js @@ -0,0 +1,4 @@ +/** +* @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed +*/ +!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.3-pre",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b),"object"==typeof module&&module.exports&&(module.exports=t)}("undefined"!=typeof window?window:this,document); \ No newline at end of file diff --git a/docs/5.0.1/_static/js/theme.js b/docs/5.0.1/_static/js/theme.js new file mode 100644 index 00000000..1fddb6ee --- /dev/null +++ b/docs/5.0.1/_static/js/theme.js @@ -0,0 +1 @@ +!function(n){var e={};function t(i){if(e[i])return e[i].exports;var o=e[i]={i:i,l:!1,exports:{}};return n[i].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=n,t.c=e,t.d=function(n,e,i){t.o(n,e)||Object.defineProperty(n,e,{enumerable:!0,get:i})},t.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},t.t=function(n,e){if(1&e&&(n=t(n)),8&e)return n;if(4&e&&"object"==typeof n&&n&&n.__esModule)return n;var i=Object.create(null);if(t.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:n}),2&e&&"string"!=typeof n)for(var o in n)t.d(i,o,function(e){return n[e]}.bind(null,o));return i},t.n=function(n){var e=n&&n.__esModule?function(){return n.default}:function(){return n};return t.d(e,"a",e),e},t.o=function(n,e){return Object.prototype.hasOwnProperty.call(n,e)},t.p="",t(t.s=0)}([function(n,e,t){t(1),n.exports=t(3)},function(n,e,t){(function(){var e="undefined"!=typeof window?window.jQuery:t(2);n.exports.ThemeNav={navBar:null,win:null,winScroll:!1,winResize:!1,linkScroll:!1,winPosition:0,winHeight:null,docHeight:null,isRunning:!1,enable:function(n){var t=this;void 0===n&&(n=!0),t.isRunning||(t.isRunning=!0,e((function(e){t.init(e),t.reset(),t.win.on("hashchange",t.reset),n&&t.win.on("scroll",(function(){t.linkScroll||t.winScroll||(t.winScroll=!0,requestAnimationFrame((function(){t.onScroll()})))})),t.win.on("resize",(function(){t.winResize||(t.winResize=!0,requestAnimationFrame((function(){t.onResize()})))})),t.onResize()})))},enableSticky:function(){this.enable(!0)},init:function(n){n(document);var e=this;this.navBar=n("div.wy-side-scroll:first"),this.win=n(window),n(document).on("click","[data-toggle='wy-nav-top']",(function(){n("[data-toggle='wy-nav-shift']").toggleClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift")})).on("click",".wy-menu-vertical .current ul li a",(function(){var t=n(this);n("[data-toggle='wy-nav-shift']").removeClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift"),e.toggleCurrent(t),e.hashChange()})).on("click","[data-toggle='rst-current-version']",(function(){n("[data-toggle='rst-versions']").toggleClass("shift-up")})),n("table.docutils:not(.field-list,.footnote,.citation)").wrap("
"),n("table.docutils.footnote").wrap("
"),n("table.docutils.citation").wrap("
"),n(".wy-menu-vertical ul").not(".simple").siblings("a").each((function(){var t=n(this);expand=n(''),expand.on("click",(function(n){return e.toggleCurrent(t),n.stopPropagation(),!1})),t.prepend(expand)}))},reset:function(){var n=encodeURI(window.location.hash)||"#";try{var e=$(".wy-menu-vertical"),t=e.find('[href="'+n+'"]');if(0===t.length){var i=$('.document [id="'+n.substring(1)+'"]').closest("div.section");0===(t=e.find('[href="#'+i.attr("id")+'"]')).length&&(t=e.find('[href="#"]'))}if(t.length>0){$(".wy-menu-vertical .current").removeClass("current").attr("aria-expanded","false"),t.addClass("current").attr("aria-expanded","true"),t.closest("li.toctree-l1").parent().addClass("current").attr("aria-expanded","true");for(let n=1;n<=10;n++)t.closest("li.toctree-l"+n).addClass("current").attr("aria-expanded","true");t[0].scrollIntoView()}}catch(n){console.log("Error expanding nav for anchor",n)}},onScroll:function(){this.winScroll=!1;var n=this.win.scrollTop(),e=n+this.winHeight,t=this.navBar.scrollTop()+(n-this.winPosition);n<0||e>this.docHeight||(this.navBar.scrollTop(t),this.winPosition=n)},onResize:function(){this.winResize=!1,this.winHeight=this.win.height(),this.docHeight=$(document).height()},hashChange:function(){this.linkScroll=!0,this.win.one("hashchange",(function(){this.linkScroll=!1}))},toggleCurrent:function(n){var e=n.closest("li");e.siblings("li.current").removeClass("current").attr("aria-expanded","false"),e.siblings().find("li.current").removeClass("current").attr("aria-expanded","false");var t=e.find("> ul li");t.length&&(t.removeClass("current").attr("aria-expanded","false"),e.toggleClass("current").attr("aria-expanded",(function(n,e){return"true"==e?"false":"true"})))}},"undefined"!=typeof window&&(window.SphinxRtdTheme={Navigation:n.exports.ThemeNav,StickyNav:n.exports.ThemeNav}),function(){for(var n=0,e=["ms","moz","webkit","o"],t=0;t0 + 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/docs/5.0.1/_static/minus.png b/docs/5.0.1/_static/minus.png new file mode 100644 index 00000000..d96755fd Binary files /dev/null and b/docs/5.0.1/_static/minus.png differ diff --git a/docs/5.0.1/_static/plus.png b/docs/5.0.1/_static/plus.png new file mode 100644 index 00000000..7107cec9 Binary files /dev/null and b/docs/5.0.1/_static/plus.png differ diff --git a/docs/5.0.1/_static/pygments.css b/docs/5.0.1/_static/pygments.css new file mode 100644 index 00000000..84ab3030 --- /dev/null +++ b/docs/5.0.1/_static/pygments.css @@ -0,0 +1,75 @@ +pre { line-height: 125%; } +td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +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: #3D7B7B; font-style: italic } /* Comment */ +.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .k { color: #008000; font-weight: bold } /* Keyword */ +.highlight .o { color: #666666 } /* Operator */ +.highlight .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */ +.highlight .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #9C6500 } /* Comment.Preproc */ +.highlight .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */ +.highlight .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */ +.highlight .gr { color: #E40000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #008400 } /* Generic.Inserted */ +.highlight .go { color: #717171 } /* Generic.Output */ +.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #0044DD } /* Generic.Traceback */ +.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #008000 } /* Keyword.Pseudo */ +.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #B00040 } /* Keyword.Type */ +.highlight .m { color: #666666 } /* Literal.Number */ +.highlight .s { color: #BA2121 } /* Literal.String */ +.highlight .na { color: #687822 } /* Name.Attribute */ +.highlight .nb { color: #008000 } /* Name.Builtin */ +.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */ +.highlight .no { color: #880000 } /* Name.Constant */ +.highlight .nd { color: #AA22FF } /* Name.Decorator */ +.highlight .ni { color: #717171; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #0000FF } /* Name.Function */ +.highlight .nl { color: #767600 } /* Name.Label */ +.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #19177C } /* Name.Variable */ +.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mb { color: #666666 } /* Literal.Number.Bin */ +.highlight .mf { color: #666666 } /* Literal.Number.Float */ +.highlight .mh { color: #666666 } /* Literal.Number.Hex */ +.highlight .mi { color: #666666 } /* Literal.Number.Integer */ +.highlight .mo { color: #666666 } /* Literal.Number.Oct */ +.highlight .sa { color: #BA2121 } /* Literal.String.Affix */ +.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */ +.highlight .sc { color: #BA2121 } /* Literal.String.Char */ +.highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */ +.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #BA2121 } /* Literal.String.Double */ +.highlight .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */ +.highlight .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */ +.highlight .sx { color: #008000 } /* Literal.String.Other */ +.highlight .sr { color: #A45A77 } /* Literal.String.Regex */ +.highlight .s1 { color: #BA2121 } /* Literal.String.Single */ +.highlight .ss { color: #19177C } /* Literal.String.Symbol */ +.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */ +.highlight .fm { color: #0000FF } /* Name.Function.Magic */ +.highlight .vc { color: #19177C } /* Name.Variable.Class */ +.highlight .vg { color: #19177C } /* Name.Variable.Global */ +.highlight .vi { color: #19177C } /* Name.Variable.Instance */ +.highlight .vm { color: #19177C } /* Name.Variable.Magic */ +.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/docs/5.0.1/_static/searchtools.js b/docs/5.0.1/_static/searchtools.js new file mode 100644 index 00000000..92da3f8b --- /dev/null +++ b/docs/5.0.1/_static/searchtools.js @@ -0,0 +1,619 @@ +/* + * searchtools.js + * ~~~~~~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for the full-text search. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"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] = 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, + }; +} + +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] = item; + + let listItem = document.createElement("li"); + 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 = _( + "Search finished, found ${resultCount} page(s) matching the search query." + ).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]. +// 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 [".headerlinks", "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.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]. + 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) { + let score = Math.round(100 * queryLower.length / title.length) + normalResults.push([ + docNames[file], + titles[file] !== title ? `${titles[file]} > ${title}` : title, + id !== null ? "#" + id : "", + null, + score, + filenames[file], + ]); + } + } + } + + // 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], + ]; + 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]], + ]); + }; + 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], + ]); + } + 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/docs/5.0.1/_static/sphinx_highlight.js b/docs/5.0.1/_static/sphinx_highlight.js new file mode 100644 index 00000000..8a96c69a --- /dev/null +++ b/docs/5.0.1/_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/docs/5.0.1/distinct_counting/cpc.html b/docs/5.0.1/distinct_counting/cpc.html new file mode 100644 index 00000000..6b7c53e3 --- /dev/null +++ b/docs/5.0.1/distinct_counting/cpc.html @@ -0,0 +1,270 @@ + + + + + + + Compressed Probabilistic Counting (CPC) — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Compressed Probabilistic Counting (CPC)

+

High performance C++ implementation of Compressed Probabilistic Counting (CPC) Sketch. +This is a unique-counting sketch that implements the Compressed Probabilistic Counting (CPC, a.k.a FM85) algorithms developed by Kevin Lang in his paper +Back to the Future: an Even More Nearly Optimal Cardinality Estimation Algorithm. +This sketch is extremely space-efficient when serialized. +In an apples-to-apples empirical comparison against compressed HyperLogLog sketches, this new algorithm simultaneously wins on the two dimensions of the space/accuracy tradeoff and produces sketches that are smaller than the entropy of HLL, so no possible implementation of compressed HLL can match its space efficiency for a given accuracy. As described in the paper this sketch implements a newly developed ICON estimator algorithm that survives unioning operations, another well-known estimator, the Historical Inverse Probability (HIP) estimator does not. +The update speed performance of this sketch is quite fast and is comparable to the speed of HLL. +The unioning (merging) capability of this sketch also allows for merging of sketches with different configurations of K. +For additional security this sketch can be configured with a user-specified hash seed.

+
+
+class cpc_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.cpc_sketch
+

Reads a bytes object and returns the corresponding cpc_sketch

+
+ +

Non-static Methods:

+
+
+__init__(self, lg_k: int = 11, seed: int = 9001) None
+

Creates a new CPC sketch

+
+
Parameters:
+
    +
  • lg_k (int, optional) – base 2 logarithm of the number of bins in the sketch

  • +
  • seed (int, optional) – seed value for the hash function

  • +
+
+
+
+ +
+
+get_estimate
+

Estimate of the distinct count of the input stream

+
+ +
+
+get_lower_bound
+

Returns an approximate lower bound on the estimate for kappa values in {1, 2, 3}, roughly corresponding to standard deviations

+
+ +
+
+get_upper_bound
+

Returns an approximate upper bound on the estimate for kappa values in {1, 2, 3}, roughly corresponding to standard deviations

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+property lg_k
+

Configured lg_k of this sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, datum: int) -> None

  2. +
+

Updates the sketch with the given 64-bit integer value

+
    +
  1. update(self, datum: float) -> None

  2. +
+

Updates the sketch with the given 64-bit floating point

+
    +
  1. update(self, datum: str) -> None

  2. +
+

Updates the sketch with the given string

+
+ +
+ +
+
+class cpc_union(*args, **kwargs)
+
+
+__init__(self, lg_k: int, seed: int = 9001) None
+
+ +
+
+get_result
+

Returns a CPC sketch with the result of the union

+
+ +
+
+update
+

Updates the union with the provided CPC sketch

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.1/distinct_counting/hyper_log_log.html b/docs/5.0.1/distinct_counting/hyper_log_log.html new file mode 100644 index 00000000..c28cf5e9 --- /dev/null +++ b/docs/5.0.1/distinct_counting/hyper_log_log.html @@ -0,0 +1,426 @@ + + + + + + + HyperLogLog (HLL) — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

HyperLogLog (HLL)

+

This is a high performance implementation of Phillipe Flajolet’s HLL sketch but with significantly improved error behavior.

+

If the ONLY use case for sketching is counting uniques and merging, the HLL sketch is a reasonable choice, although the highest performing in terms of accuracy for storage space consumed is CPC (Compressed Probabilistic Counting). For large enough counts, this HLL version (with HLL_4) can be 2 to 16 times smaller than the Theta sketch family for the same accuracy.

+

This implementation offers three different types of HLL sketch, each with different trade-offs with accuracy, space and performance. +These types are specified with the target_hll_type parameter.

+

In terms of accuracy, all three types, for the same lg_config_k, have the same error distribution as a function of n, the number of unique values fed to the sketch. +The configuration parameter lg_config_k is the log-base-2 of k, where k is the number of buckets or slots for the sketch.

+

During warmup, when the sketch has only received a small number of unique items (up to about 10% of k), this implementation leverages a new class of estimator algorithms with significantly better accuracy.

+
+
+class tgt_hll_type
+

Target HLL flavor

+
+
+HLL_4 : 4 bits per entry
+
+ +
+
+HLL_6 : 6 bits per entry
+
+ +
+
+HLL_8 : 8 bits per entry
+
+ +
+ +
+
+class hll_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.hll_sketch
+

Reads a bytes object and returns the corresponding hll_sketch

+
+ +
+
+get_max_updatable_serialization_bytes(lg_k: int, tgt_type: _datasketches.tgt_hll_type) int
+

Provides a likely upper bound on serialization size for the given parameters

+
+ +
+
+get_rel_err(upper_bound: bool, unioned: bool, lg_k: int, num_std_devs: int) float
+

Returns the a priori relative error bound for the given parameters

+
+ +

Non-static Methods:

+
+
+__init__(self, lg_k: int, tgt_type: _datasketches.tgt_hll_type = _datasketches.tgt_hll_type.HLL_8, start_max_size: bool = False) None
+

Constructs a new HLL sketch

+
+
Parameters:
+
    +
  • lg_config_k (int) – A full sketch can hold 2^lg_config_k rows. Must be between 7 and 21, inclusive,

  • +
  • tgt_type (tgt_hll_type) – The HLL mode to use, if/when the sketch reaches estimation mode

  • +
  • start_full_size (bool) – Indicates whether to start in HLL mode, keeping memory use constant (if HLL_6 or HLL_8) at the cost of much higher initial memory use. Default (and recommended) is False.

  • +
+
+
+
+ +
+
+get_compact_serialization_bytes
+

Returns the size of the serialized sketch when compressing the exception table if HLL_4

+
+ +
+
+get_estimate
+

Estimate of the distinct count of the input stream

+
+ +
+
+get_lower_bound
+

Returns the approximate lower error bound given the specified number of standard deviations in {1, 2, 3}

+
+ +
+
+get_updatable_serialization_bytes
+

Returns the size of the serialized sketch

+
+ +
+
+get_upper_bound
+

Returns the approximate upper error bound given the specified number of standard deviations in {1, 2, 3}

+
+ +
+
+is_compact
+

True if the sketch is compact, otherwise False

+
+ +
+
+is_empty
+

True if the sketch is empty, otherwise False

+
+ +
+
+property lg_config_k
+

Configured lg_k value for the sketch

+
+ +
+
+reset
+

Resets the sketch to the empty state in coupon collection mode

+
+ +
+
+serialize_compact
+

Serializes the sketch into a bytes object, compressing the exception table if HLL_4

+
+ +
+
+serialize_updatable
+

Serializes the sketch into a bytes object

+
+ +
+
+property tgt_type
+

The HLL type (4, 6, or 8) when in estimation mode

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, datum: int) -> None

  2. +
+

Updates the sketch with the given integral value

+
    +
  1. update(self, datum: float) -> None

  2. +
+

Updates the sketch with the given floating point value

+
    +
  1. update(self, datum: str) -> None

  2. +
+

Updates the sketch with the given string value

+
+ +
+ +
+
+class hll_union(*args, **kwargs)
+

Static Methods:

+
+
+get_rel_err(upper_bound: bool, unioned: bool, lg_k: int, num_std_devs: int) float
+

Returns the a priori relative error bound for the given parameters

+
+ +

Non-static Methods:

+
+
+__init__(self, lg_max_k: int) None
+

Construct an hll_union object if the given size.

+
+
Parameters:
+

lg_max_k (int) – The maximum size, in log2, of k. Must be between 7 and 21, inclusive.

+
+
+
+ +
+
+get_estimate
+

Estimate of the distinct count of the input stream

+
+ +
+
+get_lower_bound
+

Returns the approximate lower error bound given the specified number of standard deviations in {1, 2, 3}

+
+ +
+
+get_result
+

Returns a sketch of the target type representing the current union state

+
+ +
+
+get_upper_bound
+

Returns the approximate upper error bound given the specified number of standard deviations in {1, 2, 3}

+
+ +
+
+is_empty
+

True if the union is empty, otherwise False

+
+ +
+
+property lg_config_k
+

Configured lg_k value for the union

+
+ +
+
+reset
+

Resets the union to the empty state

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, sketch: _datasketches.hll_sketch) -> None

  2. +
+

Updates the union with the given HLL sketch

+
    +
  1. update(self, datum: int) -> None

  2. +
+

Updates the union with the given integral value

+
    +
  1. update(self, datum: float) -> None

  2. +
+

Updates the union with the given floating point value

+
    +
  1. update(self, datum: str) -> None

  2. +
+

Updates the union with the given string value

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.1/distinct_counting/index.html b/docs/5.0.1/distinct_counting/index.html new file mode 100644 index 00000000..e75799a9 --- /dev/null +++ b/docs/5.0.1/distinct_counting/index.html @@ -0,0 +1,152 @@ + + + + + + + Distinct Counting — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Distinct Counting

+

Distinct counting is one of the earliest tasks to which sketches were applied. The concept is simple: +Provide an estimate of the number of unique elements in a set of data. One of the earliest solutions came +from Flajolet and Martin in 1985 with their seminal work +Probabilistic counting Algorithms for Data Base Applications.

+

The DataSketches library offers several types of distinct counting sketches, each with different properties.

+
+
    +
  • hll_sketch: Hyper Log Log, a well-known sketch for distinct counting but no longer state-of-the-art.

  • +
  • cpc_sketch: Provides a better accuracy-space trade-off than HLL, but with a somewhat larger footprint while in-memory.

  • +
  • theta_sketch: Theta sketch, a type of k-minimum value sketch, which provide good performance with intersection and set difference operations.

  • +
  • tuple_sketch: Tuple sketch, which is similar to a theta sketch but supports additional data stored with each key.

  • +
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.1/distinct_counting/theta.html b/docs/5.0.1/distinct_counting/theta.html new file mode 100644 index 00000000..71610cc4 --- /dev/null +++ b/docs/5.0.1/distinct_counting/theta.html @@ -0,0 +1,440 @@ + + + + + + + Theta Sketch — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Theta Sketch

+

Theta sketches are used for distinct counting.

+

The theta package contains the basic sketch classes that are members of the Theta Sketch Framework. +There is a separate Tuple package for many of the sketches that are derived from the same algorithms defined in the Theta Sketch Framework paper.

+

The Theta Sketch sketch is a space-efficient method for estimating cardinalities of sets. +It can also easily handle set operations (such as union, intersection, difference) while maintaining good accuracy. +Theta sketch is a practical variant of the K-Minimum Values sketch which avoids the need to sort the stored +hash values on every insertion to the sketch. +It has better error properties than the HyperLogLog sketch for set operations beyond the simple union.

+

Set operations (union, intersection, A-not-B) are performed through the use of dedicated objects.

+

Several Jaccard similarity +measures can be computed between theta sketches with the theta_jaccard_similarity class.

+
+
+class theta_sketch
+

An abstract base class for theta sketches

+
+
+get_estimate
+

Estimate of the distinct count of the input stream

+
+ +
+
+get_lower_bound
+

Returns an approximate lower bound on the estimate at standard deviations in {1, 2, 3}

+
+ +
+
+get_seed_hash
+

Returns a hash of the seed used in the sketch

+
+ +
+
+get_upper_bound
+

Returns an approximate upper bound on the estimate at standard deviations in {1, 2, 3}

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if sketch is in estimation mode, otherwise False

+
+ +
+
+is_ordered
+

Returns True if the sketch entries are sorted, otherwise False

+
+ +
+
+property num_retained
+

The number of items currently in the sketch

+
+ +
+
+property theta
+

Theta (effective sampling rate) as a fraction from 0 to 1

+
+ +
+
+property theta64
+

Theta as 64-bit value

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+ +
+
+class update_theta_sketch(*args, **kwargs)
+
+
+__init__(self, lg_k: int = 12, p: float = 1.0, seed: int = 9001) None
+

Creates an update_theta_sketch using the provided parameters

+
+
Parameters:
+
    +
  • lg_k (int, optional) – base 2 logarithm of the maximum size of the sketch. Default 12.

  • +
  • p (float, optional) – an initial sampling rate to use. Default 1.0

  • +
  • seed (int, optional) – the seed to use when hashing values

  • +
+
+
+
+ +
+
+compact
+

Returns a compacted form of the sketch, optionally sorting it

+
+ +
+
+reset
+

Resets the sketch to the initial empty state

+
+ +
+
+trim
+

Removes retained entries in excess of the nominal size k (if any)

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, datum: int) -> None

  2. +
+

Updates the sketch with the given integral value

+
    +
  1. update(self, datum: float) -> None

  2. +
+

Updates the sketch with the given floating point value

+
    +
  1. update(self, datum: str) -> None

  2. +
+

Updates the sketch with the given string

+
+ +
+ +
+
+class compact_theta_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, seed: int = 9001) _datasketches.compact_theta_sketch
+

Reads a bytes object and returns the corresponding compact_theta_sketch

+
+ +

Non-static Methods:

+
+
+__init__(self, arg0: _datasketches.theta_sketch, arg1: bool, /) None
+

Creates a compact_theta_sketch from an existing theta_sketch.

+
+
Parameters:
+
    +
  • other (theta_sketch) – a source theta_sketch

  • +
  • ordered (bool) – whether the incoming sketch entries are sorted. Default True

  • +
+
+
+
+ +
+
+serialize
+

Serializes the sketch into a bytes object

+
+ +
+ +
+
+class theta_union(*args, **kwargs)
+
+
+__init__(self, lg_k: int = 12, p: float = 1.0, seed: int = 9001) None
+

Creates a theta_union using the provided parameters

+
+
Parameters:
+
    +
  • lg_k (int, optional) – base 2 logarithm of the maximum size of the union. Default 12.

  • +
  • p (float, optional) – an initial sampling rate to use. Default 1.0

  • +
  • seed (int, optional) – the seed to use when hashing values. Must match all sketch seeds.

  • +
+
+
+
+ +
+
+get_result
+

Returns the sketch corresponding to the union result

+
+ +
+
+update
+

Updates the union with the given sketch

+
+ +
+ +
+
+class theta_intersection(*args, **kwargs)
+
+
+__init__(self, seed: int = 9001) None
+

Creates a theta_intersection using the provided parameters

+
+
Parameters:
+

seed (int, optional) – the seed to use when hashing values. Must match all sketch seeds

+
+
+
+ +
+
+get_result
+

Returns the sketch corresponding to the intersection result

+
+ +
+
+has_result
+

Returns True if the intersection has a valid result, otherwise False

+
+ +
+
+update
+

Intersections the provided sketch with the current intersection state

+
+ +
+ +
+
+class theta_a_not_b(*args, **kwargs)
+
+
+__init__(self, seed: int = 9001) None
+

Creates a tuple_a_not_b object

+
+
Parameters:
+

seed (int, optional) – the seed to use when hashing values. Must match all sketch seeds.

+
+
+
+ +
+
+compute
+

Returns a sketch with the result of applying the A-not-B operation on the given inputs

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.1/distinct_counting/tuple.html b/docs/5.0.1/distinct_counting/tuple.html new file mode 100644 index 00000000..48bcfd61 --- /dev/null +++ b/docs/5.0.1/distinct_counting/tuple.html @@ -0,0 +1,478 @@ + + + + + + + Tuple Sketch — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Tuple Sketch

+

Tuple sketches are an extension of Theta sketches, meaning they provide estimate of distinct counts, that +allow the keeping of arbitrary summaries associated with each retained key +(for example, a count for every key). The use of a tuple_sketch requires a TuplePolicy which +defines how summaries are created, updated, merged, or intersected. The library provides a few basic +examples of TuplePolicy implementations, but the right custom summary and policy can allow very +complicated analysis to be performed quite easily.

+

Set operations (union, intersection, A-not-B) are performed through the use of dedicated objects.

+

Several Jaccard similarity +measures can be computed between theta sketches with the tuple_jaccard_similarity class.

+
+

Note

+

Serializing and deserializing this sketch requires the use of a PyObjectSerDe.

+
+
+
+class tuple_sketch
+

An abstract base class for tuple sketches.

+
+
+DEFAULT_SEED = 9001
+
+ +
+
+get_estimate
+

Estimate of the distinct count of the input stream

+
+ +
+
+get_lower_bound
+

Returns an approximate lower bound on the estimate at standard deviations in {1, 2, 3}

+
+ +
+
+get_seed_hash
+

Returns a hash of the seed used in the sketch

+
+ +
+
+get_upper_bound
+

Returns an approximate upper bound on the estimate at standard deviations in {1, 2, 3}

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if sketch is in estimation mode, otherwise False

+
+ +
+
+is_ordered
+

Returns True if the sketch entries are sorted, otherwise False

+
+ +
+
+property num_retained
+

The number of items currently in the sketch

+
+ +
+
+property theta
+

Theta (effective sampling rate) as a fraction from 0 to 1

+
+ +
+
+property theta64
+

Theta as 64-bit value

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+ +
+
+class update_tuple_sketch(*args, **kwargs)
+
+
+__init__(self, policy: _datasketches.TuplePolicy, lg_k: int = 12, p: float = 1.0, seed: int = 9001) None
+

Creates an update_tuple_sketch using the provided parameters

+
+
Parameters:
+
    +
  • policy (TuplePolicy) – a policy to use when updating

  • +
  • lg_k (int, optional) – base 2 logarithm of the maximum size of the sketch. Default 12.

  • +
  • p (float, optional) – an initial sampling rate to use. Default 1.0

  • +
  • seed (int, optional) – the seed to use when hashing values

  • +
+
+
+
+ +
+
+compact
+

Returns a compacted form of the sketch, optionally sorting it

+
+ +
+
+reset
+

Resets the sketch to the initial empty state

+
+ +
+
+trim
+

Removes retained entries in excess of the nominal size k (if any)

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, datum: int, value: object) -> None

  2. +
+

Updates the sketch with the given integral item and summary value

+
    +
  1. update(self, datum: float, value: object) -> None

  2. +
+

Updates the sketch with the given floating point item and summary value

+
    +
  1. update(self, datum: str, value: object) -> None

  2. +
+

Updates the sketch with the given string item and summary value

+
+ +
+ +
+
+class compact_tuple_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe, seed: int = 9001) _datasketches.compact_tuple_sketch
+

Reads a bytes object and returns the corresponding compact_tuple_sketch

+
+ +

Non-static Methods:

+
+
+__init__(self, other: _datasketches.tuple_sketch, ordered: bool = True) None
+
+__init__(self, other: _datasketches.theta_sketch, summary: object) None
+

Overloaded function.

+
    +
  1. __init__(self, other: _datasketches.tuple_sketch, ordered: bool = True) -> None

  2. +
+

Creates a compact_tuple_sketch from an existing tuple_sketch.

+
+
Parameters:
+
    +
  • other (tuple_sketch) – a sourch tuple_sketch

  • +
  • ordered (bool, optional) – whether the incoming sketch entries are sorted. Default True

  • +
+
+
+
    +
  1. __init__(self, other: _datasketches.theta_sketch, summary: object) -> None

  2. +
+

Creates a compact_tuple_sketch from a theta_sketch using a fixed summary value.

+
+
Parameters:
+
    +
  • other (theta_sketch) – a source theta sketch

  • +
  • summary (object) – a summary to use for every sketch entry

  • +
+
+
+
+ +
+
+serialize
+

Serializes the sketch into a bytes object

+
+ +
+ +
+
+class tuple_union(*args, **kwargs)
+
+
+__init__(self, policy: _datasketches.TuplePolicy, lg_k: int = 12, p: float = 1.0, seed: int = 9001) None
+

Creates a tuple_union using the provided parameters

+
+
Parameters:
+
    +
  • policy (TuplePolicy) – a policy to use when unioning entries

  • +
  • lg_k (int, optional) – base 2 logarithm of the maximum size of the union. Default 12.

  • +
  • p (float, optional) – an initial sampling rate to use. Default 1.0

  • +
  • seed (int, optional) – the seed to use when hashing values. Must match any sketch seeds.

  • +
+
+
+
+ +
+
+get_result
+

Returns the sketch corresponding to the union result

+
+ +
+
+reset
+

Resets the sketch to the initial empty

+
+ +
+
+update
+

Updates the union with the given sketch

+
+ +
+ +
+
+class tuple_intersection(*args, **kwargs)
+
+
+__init__(self, policy: _datasketches.TuplePolicy, seed: int = 9001) None
+

Creates a tuple_intersection using the provided parameters

+
+
Parameters:
+
    +
  • policy (TuplePolicy) – a policy to use when intersecting entries

  • +
  • seed (int, optional) – the seed to use when hashing values. Must match any sketch seeds

  • +
+
+
+
+ +
+
+get_result
+

Returns the sketch corresponding to the intersection result

+
+ +
+
+has_result
+

Returns True if the intersection has a valid result, otherwise False

+
+ +
+
+update
+

Intersects the provided sketch with the current intersection state

+
+ +
+ +
+
+class tuple_a_not_b(*args, **kwargs)
+
+
+__init__(self, seed: int = 9001) None
+

Creates a tuple_a_not_b object

+
+
Parameters:
+

seed (int, optional) – the seed to use when hashing values. Must match any sketch seeds.

+
+
+
+ +
+
+compute
+

Returns a sketch with the result of applying the A-not-B operation on the given inputs

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.1/frequency/count_min_sketch.html b/docs/5.0.1/frequency/count_min_sketch.html new file mode 100644 index 00000000..c6a8e366 --- /dev/null +++ b/docs/5.0.1/frequency/count_min_sketch.html @@ -0,0 +1,303 @@ + + + + + + + CountMin Sketch — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

CountMin Sketch

+

The CountMin sketch, as described in Cormode and Muthukrishnan in +http://dimacs.rutgers.edu/~graham/pubs/papers/cm-full.pdf, +is used for approximate Frequency Estimation. +For an item \(x\) with frequency \(f_x\), the sketch provides an estimate, \(\hat{f_x}\), +such that \(f_x \approx \hat{f_x}.\) +The sketch guarantees that \(f_x \le \hat{f_x}\) and provides a probabilistic upper bound which is dependent on the size parameters. +The sketch provides an estimate of the occurrence frequency for any queried item but, in contrast +to the Frequent Items Sketch, this sketch does not provide a list of +heavy hitters.

+
+
+class count_min_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.count_min_sketch
+

Reads a bytes object and returns the corresponding count_min_sketch

+
+ +
+
+suggest_num_buckets(relative_error: float) int
+

Suggests the number of buckets needed to achieve an accuracy within the provided relative_error. For example, when relative_error = 0.05, the returned frequency estimates satisfy the ‘relative_error’ guarantee that never overestimates the weights but may underestimate the weights by 5% of the total weight in the sketch. Returns the number of hash buckets at every level of the sketch required in order to obtain the specified relative error.

+
+ +
+
+suggest_num_hashes(confidence: float) int
+

Suggests the number of hashes needed to achieve the provided confidence. For example, with 95% confidence, frequency estimates satisfy the ‘relative_error’ guarantee. Returns the number of hash functions that are required in order to achieve the specified confidence of the sketch. confidence = 1 - delta, with delta denoting the sketch failure probability.

+
+ +

Non-static Methods:

+
+
+get_estimate
+

Overloaded function.

+
    +
  1. get_estimate(self, item: int) -> float

  2. +
+

Returns an estimate of the frequency of the provided 64-bit integer value

+
    +
  1. get_estimate(self, item: str) -> float

  2. +
+

Returns an estimate of the frequency of the provided string

+
+ +
+
+get_lower_bound
+

Overloaded function.

+
    +
  1. get_lower_bound(self, item: int) -> float

  2. +
+

Returns a lower bound on the estimate for the given 64-bit integer value

+
    +
  1. get_lower_bound(self, item: str) -> float

  2. +
+

Returns a lower bound on the estimate for the provided string

+
+ +
+
+get_relative_error
+

Returns the maximum permissible error for any frequency estimate query

+
+ +
+
+get_serialized_size_bytes
+

Returns the size in bytes of the serialized image of the sketch

+
+ +
+
+get_upper_bound
+

Overloaded function.

+
    +
  1. get_upper_bound(self, item: int) -> float

  2. +
+

Returns an upper bound on the estimate for the given 64-bit integer value

+
    +
  1. get_upper_bound(self, item: str) -> float

  2. +
+

Returns an upper bound on the estimate for the provided string

+
+ +
+
+is_empty
+

Returns True if the sketch has seen no items, otherwise False

+
+ +
+
+merge
+

Merges the provided other sketch into this one

+
+ +
+
+property num_buckets
+

The configured number of buckets for the sketch

+
+ +
+
+property num_hashes
+

The configured number of hashes for the sketch

+
+ +
+
+property seed
+

The base hash seed for the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+property total_weight
+

The total weight currently inserted into the stream

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: int, weight: float = 1.0) -> None

  2. +
+

Updates the sketch with the given 64-bit integer value

+
    +
  1. update(self, item: str, weight: float = 1.0) -> None

  2. +
+

Updates the sketch with the given string

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.1/frequency/frequent_items.html b/docs/5.0.1/frequency/frequent_items.html new file mode 100644 index 00000000..3b70f66c --- /dev/null +++ b/docs/5.0.1/frequency/frequent_items.html @@ -0,0 +1,479 @@ + + + + + + + Frequent Items — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Frequent Items

+

This sketch is useful for tracking approximate frequencies of items (object or string) with optional associated +integer counts that are members of a multiset of such items. +The true frequency of an item is defined to be the sum of associated counts.

+

This implementation provides the following capabilities:

+
    +
  • Estimate the frequency of an item.

  • +
  • Return upper and lower bounds of any item, such that the true frequency is always between the upper and lower bounds.

  • +
  • Return a global maximum error that holds for all items in the stream.

  • +
  • Return an array of frequent items that qualify either a NO_FALSE_POSITIVES or a NO_FALSE_NEGATIVES error type.

  • +
  • Merge itself with another sketch object created from this class.

  • +
  • Serialize/Deserialize to/from a byte array.

  • +
+

Space Usage

+

The sketch is initialized with a maximum map size, maxMapSize, that specifies the maximum physical length of the internal hash map of the form (object item, int count). +The maximum map size is always a power of 2, defined through the variables lg_max_map_size.

+

The hash map starts at a very small size (8 entries) and grows as needed up to the specified maximum map size.

+

Excluding external space required for the item objects, the internal memory space usage of this sketch is 18 * mapSize bytes (assuming 8 bytes for each reference), +plus a small constant number of additional bytes. +The internal memory space usage of this sketch will never exceed 18 * maxMapSize bytes, plus a small constant number of additional bytes.

+

Maximum Capacity of the Sketch

+

The LOAD_FACTOR for the hash map is internally set at \(75\%\), which means at any time the map capacity of (item, count) pairs is mapCap = 0.75 * mapSize. +The maximum capacity of (item, count) pairs of the sketch is maxMapCap = 0.75 * maxMapSize.

+

Updating the sketch with ``(item, count)`` pairs

+

If the item is found in the hash map, the mapped count field (the “counter”) is incremented by the incoming count; otherwise, a new counter (item, count) pair is created. +If the number of tracked counters reaches the maximum capacity of the hash map, the sketch decrements all of the counters (by an approximately computed median) +and removes any non-positive counters.

+

Accuracy

+

If fewer than 0.75 * maxMapSize different items are inserted into the sketch, the estimated frequencies returned by the sketch will be exact.

+

The logic of the frequent items sketch is such that the stored counts and true counts are never too different. +More specifically, for any item, the sketch can return an estimate of the true frequency of item, along with upper and lower bounds on the frequency (that hold deterministically).

+

For this implementation and for a specific active item, it is guaranteed that the true frequency will be between the Upper Bound (UB) and the Lower Bound (LB) computed for that item. +Specifically, (UB- LB) W * epsilon, where \(W\) denotes the sum of all item counts, and \(epsilon = 3.5/M\), where \(epsilon = M\) is the maxMapSize.

+

This is a worst-case guarantee that applies to arbitrary inputs. +For inputs typically seen in practice, (UB-LB) is usually much smaller.

+

Background

+

This code implements a variant of what is commonly known as the “Misra-Gries algorithm”. +Variants of it were discovered and rediscovered and redesigned several times over the years:

+
    +
  • Finding repeated elements, Misra, Gries, 1982

  • +
  • Frequency estimation of Internet packet streams with limited space Demaine, Lopez-Ortiz, Munro, 2002

  • +
  • A simple algorithm for finding frequent elements in streams and bags Karp, Shenker, Papadimitriou, 2003

  • +
  • Efficient Computation of Frequent and Top-k Elements in Data Streams Metwally, Agrawal, Abbadi, 2006

  • +
+

For speed, we do employ some randomization that introduces a small probability that our proof of the worst-case bound might not apply to a given run. +However, we have ensured that this probability is extremely small. +For example, if the stream causes one table purge (rebuild), our proof of the worst-case bound applies with a probability of at least 1 - 1E-14. +If the stream causes 1E9 purges, our proof applies with a probability of at least 1 - 1E-5.

+

There are two flavors of Frequent Items Sketches, one with generic items (objects) and another specific to strings. +The string version is a legacy name from before the library supported generic objects and is retained +only for backwards compatibility.

+
+

Note

+

The frequent_items_sketch uses an input object’s __hash__ and __eq__ methods.

+
+
+

Note

+

Serializing and deserializing the frequent_items_sketch requires the use of a PyObjectSerDe.

+
+
+
+class frequent_items_error_type
+
+
+NO_FALSE_POSITIVES : Returns only true positives but may miss some heavy hitters.
+
+ +
+
+NO_FALSE_NEGATIVES : Does not miss any heavy hitters but may return false positives.
+
+ +
+ +
+
+class frequent_items_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe) _datasketches.frequent_items_sketch
+

Reads a bytes object using the provided serde and returns the corresponding frequent_strings_sketch.

+
+ +
+
+get_epsilon_for_lg_size(lg_max_map_size: int) float
+

Returns the epsilon value used to compute a priori error for a given log2(max_map_size)

+
+ +
+
+get_apriori_error(lg_max_map_size: int, estimated_total_weight: int) float
+

Returns the estimated a priori error given the max_map_size for the sketch and the estimated_total_stream_weight.

+
+ +

Non-static Methods:

+
+
+__init__(self, lg_max_k: int) None
+

Creates an instance of the sketch

+
+
Parameters:
+

lg_max_k (int) – base 2 logarithm of the maximum size of the internal hash map of the sketch. Maximum capacity is 0.75 of this value, which is the maximum number of distinct items the sketch can contain.

+
+
+
+ +
+
+property epsilon
+

The epsilon value used by the sketch to compute error

+
+ +
+
+get_estimate
+

Returns the estimate of the weight (frequency) of the given item. +Note: The true frequency of a item would be the sum of the counts as a result of the two update functions.

+
+ +
+
+get_frequent_items
+
+ +
+
+get_lower_bound
+

Returns the guaranteed lower bound weight (frequency) of the given item.

+
+ +
+
+get_serialized_size_bytes
+

Computes the size needed to serialize the current state of the sketch using the provided serde. This can be expensive since every item needs to be looked at.

+
+ +
+
+get_upper_bound
+

Returns the guaranteed upper bound weight (frequency) of the given item.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+merge
+

Merges the given sketch into this one

+
+ +
+
+property num_active_items
+

The number of active items in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object using the provided serde.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+property total_weight
+

The sum of the weights (frequencies) in the stream seen so far by the sketch

+
+ +
+
+update
+

Updates the sketch with the given string and, optionally, a weight

+
+ +
+ +
+
+class frequent_strings_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.frequent_strings_sketch
+

Reads a bytes object and returns the corresponding frequent_strings_sketch.

+
+ +
+
+get_epsilon_for_lg_size(lg_max_map_size: int) float
+

Returns the epsilon value used to compute a priori error for a given log2(max_map_size)

+
+ +
+
+get_apriori_error(lg_max_map_size: int, estimated_total_weight: int) float
+

Returns the estimated a priori error given the max_map_size for the sketch and the estimated_total_stream_weight.

+
+ +

Non-static Methods:

+
+
+__init__(self, lg_max_k: int) None
+

Creates an instance of the sketch

+
+
Parameters:
+

lg_max_k (int) – base 2 logarithm of the maximum size of the internal hash map of the sketch. Maximum capacity is 0.75 of this value, which is the maximum number of distinct items the sketch can contain.

+
+
+
+ +
+
+property epsilon
+

The epsilon value used by the sketch to compute error

+
+ +
+
+get_estimate
+

Returns the estimate of the weight (frequency) of the given item. +Note: The true frequency of a item would be the sum of the counts as a result of the two update functions.

+
+ +
+
+get_frequent_items
+
+ +
+
+get_lower_bound
+

Returns the guaranteed lower bound weight (frequency) of the given item.

+
+ +
+
+get_serialized_size_bytes
+

Computes the size needed to serialize the current state of the sketch. This can be expensive since every item needs to be looked at.

+
+ +
+
+get_upper_bound
+

Returns the guaranteed upper bound weight (frequency) of the given item.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+merge
+

Merges the given sketch into this one

+
+ +
+
+property num_active_items
+

The number of active items in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+property total_weight
+

The sum of the weights (frequencies) in the stream seen so far by the sketch

+
+ +
+
+update
+

Updates the sketch with the given string and, optionally, a weight

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.1/frequency/index.html b/docs/5.0.1/frequency/index.html new file mode 100644 index 00000000..99bd3d37 --- /dev/null +++ b/docs/5.0.1/frequency/index.html @@ -0,0 +1,145 @@ + + + + + + + Frequency Sketches — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Frequency Sketches

+

Frequency estimation involves determining how often an item has been seen in a stream. The library currently +offers two types of sketches for frequency estimation, one of which has two closely-related variants.

+
+
    +
  • frequent_items_sketch: Identifies the Top K or heavy hitters in a stream, those items whose weight is above a certain percentage of the entire stream. Does not necessarily provide an estimate for most items outside the heavy hitters.

  • +
  • frequent_strings_sketch: Like the items version but containing snly strings (an implementation from before the library handled generic objects).

  • +
  • count_min_sketch: Provides an estimate for any item, regardless of relative weight, but does not maintain a list of the heaviest items.

  • +
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.1/genindex.html b/docs/5.0.1/genindex.html new file mode 100644 index 00000000..6dbd7d3a --- /dev/null +++ b/docs/5.0.1/genindex.html @@ -0,0 +1,1384 @@ + + + + + + Index — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ + +

Index

+ +
+ _ + | A + | C + | D + | E + | F + | G + | H + | I + | J + | K + | L + | M + | N + | P + | Q + | R + | S + | T + | U + | V + +
+

_

+ + +
+ +

A

+ + +
+ +

C

+ + + +
+ +

D

+ + + +
+ +

E

+ + + +
+ +

F

+ + + +
+ +

G

+ + + +
+ +

H

+ + + +
+ +

I

+ + + +
+ +

J

+ + +
+ +

K

+ + + +
+ +

L

+ + + +
+ +

M

+ + + +
+ +

N

+ + + +
+ +

P

+ + + +
+ +

Q

+ + + +
+ +

R

+ + +
+ +

S

+ + + +
+ +

T

+ + + +
+ +

U

+ + + +
+ +

V

+ + + +
+ + + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.1/helper/index.html b/docs/5.0.1/helper/index.html new file mode 100644 index 00000000..d977f1ec --- /dev/null +++ b/docs/5.0.1/helper/index.html @@ -0,0 +1,154 @@ + + + + + + + Helper Classes — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Helper Classes

+

These classes are required for certain sketches or specific +functionality within sketches. +Some of them are abstract base classes, but in those cases there is at +least one reference example of a concrete class.

+
+
    +
  • serde is used when serializing and deserializing sketches.

  • +
  • jaccard is used to compute the Jaccard similarity between pairs of theta or tuple sketches.

  • +
  • tuple_policy is required to use a tuple_sketch by specifying how summaries are combined.

  • +
  • ks_test() performs a Kolmogorov-Smirnov test on absolute-error quantiles family sketches.

  • +
  • kernel_function is required when using a kernel_sketch for Kernel Density Estimation.

  • +
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.1/helper/jaccard.html b/docs/5.0.1/helper/jaccard.html new file mode 100644 index 00000000..b66dbf01 --- /dev/null +++ b/docs/5.0.1/helper/jaccard.html @@ -0,0 +1,212 @@ + + + + + + + Jaccard Similarity — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Jaccard Similarity

+

These objects provide measures related to the Jaccard similarity +of theta_sketch and tuple_sketch objects.

+

Note that there are separate classes to be used for theta and tuple sketches.

+
+
+class theta_jaccard_similarity
+

An object to help compute Jaccard similarity between theta sketches.

+
+
+jaccard(sketch_a: _datasketches.theta_sketch, sketch_b: _datasketches.theta_sketch, seed: int = 9001) list[float]
+

Returns a list with {lower_bound, estimate, upper_bound} of the Jaccard similarity between sketches

+
+ +
+
+exactly_equal(sketch_a: _datasketches.theta_sketch, sketch_b: _datasketches.theta_sketch, seed: int = 9001) bool
+

Returns True if sketch_a and sketch_b are equivalent, otherwise False

+
+ +
+
+similarity_test(actual: _datasketches.theta_sketch, expected: _datasketches.theta_sketch, threshold: float, seed: int = 9001) bool
+

Tests similarity of an actual sketch against an expected sketch. Computers the lower bound of the Jaccard index J_{LB} of the actual and expected sketches. If J_{LB} >= threshold, then the sketches are considered to be similar with a confidence of 97.7% and returns True, otherwise False.

+
+ +
+
+dissimilarity_test(actual: _datasketches.theta_sketch, expected: _datasketches.theta_sketch, threshold: float, seed: int = 9001) bool
+

Tests dissimilarity of an actual sketch against an expected sketch. Computers the lower bound of the Jaccard index J_{UB} of the actual and expected sketches. If J_{UB} <= threshold, then the sketches are considered to be dissimilar with a confidence of 97.7% and returns True, otherwise False.

+
+ +
+ +
+
+class tuple_jaccard_similarity
+

An object to help compute Jaccard similarity between tuple sketches.

+
+
+jaccard(sketch_a: _datasketches.tuple_sketch, sketch_b: _datasketches.tuple_sketch, seed: int = 9001) list[float]
+

Returns a list with {lower_bound, estimate, upper_bound} of the Jaccard similarity between sketches

+
+ +
+
+exactly_equal(sketch_a: _datasketches.tuple_sketch, sketch_b: _datasketches.tuple_sketch, seed: int = 9001) bool
+

Returns True if sketch_a and sketch_b are equivalent, otherwise False

+
+ +
+
+similarity_test(actual: _datasketches.tuple_sketch, expected: _datasketches.tuple_sketch, threshold: float, seed: int = 9001) bool
+

Tests similarity of an actual sketch against an expected sketch. Computes the lower bound of the Jaccard index J_{LB} of the actual and expected sketches. If J_{LB} >= threshold, then the sketches are considered to be similar with a confidence of 97.7% and returns True, otherwise False.

+
+ +
+
+dissimilarity_test(actual: _datasketches.tuple_sketch, expected: _datasketches.tuple_sketch, threshold: float, seed: int = 9001) bool
+

Tests dissimilarity of an actual sketch against an expected sketch. Computes the upper bound of the Jaccard index J_{UB} of the actual and expected sketches. If J_{UB} <= threshold, then the sketches are considered to be dissimilar with a confidence of 97.7% and returns True, otherwise False.

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.1/helper/kernel.html b/docs/5.0.1/helper/kernel.html new file mode 100644 index 00000000..a2a61177 --- /dev/null +++ b/docs/5.0.1/helper/kernel.html @@ -0,0 +1,184 @@ + + + + + + + Kernel Function — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Kernel Function

+

A kernel function is a specific type of +mathematical funciton that is particularly useful in certain machine learning and pattern recognition +contexts. The density_sketch performs approximate +kernel density estimation which, unsurprisingly, +relies on the use of such a kernel function.

+

The library provides an abstract base class KernelFunction and an example implementation of a +Gaussian (also known as a Radial Basis Function) kernel. Custom classes must override the base class +and provide a floating point value as a score indicating the similarity of two input vectors.

+
+
+class KernelFunction(*args, **kwargs)
+

A generic base class from which user-defined kernels must inherit.

+
+
+__call__(self, a: object, b: object) float
+

A method to evaluate a kernel with given inputs a and b.

+
+
Parameters:
+
    +
  • a (numpy array) – An input vector

  • +
  • b (numpy array) – An input vector

  • +
+
+
Returns:
+

A vector similarity score

+
+
Return type:
+

float

+
+
+
+ +
+ +
+
+class GaussianKernel(bandwidth: float = 1.0)
+

Bases: KernelFunction

+

Implements a basic Gaussian kernel

+
+
Parameters:
+

bandwidth (float) – The kernel bandwidth, default 1.0

+
+
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.1/helper/ks_test.html b/docs/5.0.1/helper/ks_test.html new file mode 100644 index 00000000..721be0a5 --- /dev/null +++ b/docs/5.0.1/helper/ks_test.html @@ -0,0 +1,210 @@ + + + + + + + Kolmogorov-Smirnov Test — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Kolmogorov-Smirnov Test

+

A Kolmogorov-Smirnov Test <https://en.wikipedia.org/wiki/Kolmogorov%E2%80%93Smirnov_test>`_ is +a test of equality of two distributions to determine if they are likely to have come from the same +underlying distribution. +The DataSketches library provides a modified form of the test that takes into account the error +in each underlying sketch in the analysis.

+

Currently, the test assumes both input sketches are of the same family and data type.

+
+
+ks_test(sk_1: _datasketches.kll_ints_sketch, sk_2: _datasketches.kll_ints_sketch, p: float) bool
+
+ks_test(sk_1: _datasketches.kll_floats_sketch, sk_2: _datasketches.kll_floats_sketch, p: float) bool
+
+ks_test(sk_1: _datasketches.kll_doubles_sketch, sk_2: _datasketches.kll_doubles_sketch, p: float) bool
+
+ks_test(sk_1: _datasketches.kll_items_sketch, sk_2: _datasketches.kll_items_sketch, p: float) bool
+
+ks_test(sk_1: _datasketches.quantiles_ints_sketch, sk_2: _datasketches.quantiles_ints_sketch, p: float) bool
+
+ks_test(sk_1: _datasketches.quantiles_floats_sketch, sk_2: _datasketches.quantiles_floats_sketch, p: float) bool
+
+ks_test(sk_1: _datasketches.quantiles_doubles_sketch, sk_2: _datasketches.quantiles_doubles_sketch, p: float) bool
+
+ks_test(sk_1: _datasketches.quantiles_items_sketch, sk_2: _datasketches.quantiles_items_sketch, p: float) bool
+

Overloaded function.

+
    +
  1. ks_test(sk_1: _datasketches.kll_ints_sketch, sk_2: _datasketches.kll_ints_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for kll_ints_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
    +
  1. ks_test(sk_1: _datasketches.kll_floats_sketch, sk_2: _datasketches.kll_floats_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for kll_floats_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
    +
  1. ks_test(sk_1: _datasketches.kll_doubles_sketch, sk_2: _datasketches.kll_doubles_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for kll_doubles_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
    +
  1. ks_test(sk_1: _datasketches.kll_items_sketch, sk_2: _datasketches.kll_items_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for kll_items_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
    +
  1. ks_test(sk_1: _datasketches.quantiles_ints_sketch, sk_2: _datasketches.quantiles_ints_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for quantiles_ints_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
    +
  1. ks_test(sk_1: _datasketches.quantiles_floats_sketch, sk_2: _datasketches.quantiles_floats_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for quantiles_floats_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +:Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
    +
  1. ks_test(sk_1: _datasketches.quantiles_doubles_sketch, sk_2: _datasketches.quantiles_doubles_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for quantiles_doubles_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
    +
  1. ks_test(sk_1: _datasketches.quantiles_items_sketch, sk_2: _datasketches.quantiles_items_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for quantiles_items_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.1/helper/serde.html b/docs/5.0.1/helper/serde.html new file mode 100644 index 00000000..a4ed73d0 --- /dev/null +++ b/docs/5.0.1/helper/serde.html @@ -0,0 +1,253 @@ + + + + + + + Serialize/Deserialize (SerDe) — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Serialize/Deserialize (SerDe)

+

A SerDe is a class used to serialize items sketches to a bytes object in binary. +Several example SerDes are provided as references.

+

The use of binary-compatible SerDes in different languages is critical for cross-language compatibility.

+

Each implementation must extend the PyObjectSerDe class and override all three of its methods.

+
+
+class PyObjectSerDe(*args, **kwargs)
+

An abstract base class for serde objects. All custom serdes must extend this class.

+
+
+get_size(self, item: object) int
+

Returns the size in bytes of an item

+
+
Parameters:
+

item (object) – The specified object

+
+
Returns:
+

The size of the item in bytes

+
+
Return type:
+

int

+
+
+
+ +
+
+to_bytes(self, item: object) bytes
+

Retuns a bytes object with a serialized version of an item

+
+
Parameters:
+

item (object) – The specified object

+
+
Returns:
+

A bytes object with the serialized object

+
+
Return type:
+

bytes

+
+
+
+ +
+
+from_bytes(self, data: bytes, offset: int) tuple
+

Reads a bytes object starting from the given offest and returns a tuple of the reconstructed object and the number of additional bytes read

+
+
Parameters:
+
    +
  • data (bytes) – A bytes object from which to deserialize

  • +
  • offset (int) – The offset, in bytes, at which to start reading

  • +
+
+
Returns:
+

A tuple with the reconstructed object and the number of bytes read

+
+
Return type:
+

tuple(object, int)

+
+
+
+ +
+ +

The provided SerDes are:

+
+
+class PyStringsSerDe(*args, **kwargs)
+

Bases: PyObjectSerDe

+

Implements a simple string-encoding scheme where a string is +written as <num_bytes> <string_contents>, with no null termination. +This format allows pre-allocating each string, at the cost of +additional storage. Using this format, the serialized string consumes +4 + len(item) bytes.

+
+ +
+
+class PyIntsSerDe(*args, **kwargs)
+

Bases: PyObjectSerDe

+

Implements an integer encoding scheme where each integer is written +as a 32-bit (4 byte) little-endian value.

+
+ +
+
+class PyLongsSerDe(*args, **kwargs)
+

Bases: PyObjectSerDe

+

Implements an integer encoding scheme where each integer is written +as a 64-bit (8 byte) little-endian value.

+
+ +
+
+class PyFloatsSerDe(*args, **kwargs)
+

Bases: PyObjectSerDe

+

Implements a floating point encoding scheme where each value is written +as a 32-bit floating point value.

+
+ +
+
+class PyDoublesSerDe(*args, **kwargs)
+

Implements a floating point encoding scheme where each value is written +as a 64-bit floating point value.

+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.1/helper/tuple_policy.html b/docs/5.0.1/helper/tuple_policy.html new file mode 100644 index 00000000..7aec98fb --- /dev/null +++ b/docs/5.0.1/helper/tuple_policy.html @@ -0,0 +1,230 @@ + + + + + + + Tuple Policy — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Tuple Policy

+

A Tuple Policy is needed when using a tuple_sketch in order to specify how the +summary values should be created, updated, combined, or intersected. A summary can consist of +any python object.

+

Each implementation must extend the abstract base class TuplePolicy.

+
+
+class TuplePolicy(*args, **kwargs)
+

An abstract base class for Tuple Policy objects. All custom policies must extend this class.

+
+
+create_summary(self) object
+

Creates a new Summary object

+
+
Returns:
+

a Summary object

+
+
Return type:
+

object

+
+
+
+ +
+
+update_summary(self, summary: object, update: object) object
+

Applies the relevant policy to update the provided summary with the data in update.

+
+
Parameters:
+
    +
  • summary (object) – An existing Summary

  • +
  • update (object) – An update to apply to the Summary

  • +
+
+
Returns:
+

The updated Summary

+
+
Return type:
+

object

+
+
+
+ +
+
+__call__(self, summary: object, update: object) object
+

Similar to update_summary but allows a different implementation for set operations (union and intersection)

+
+
Parameters:
+
    +
  • summary (object) – An existing Summary

  • +
  • update (object) – An update to apply to the Summary

  • +
+
+
Returns:
+

The updated Summary

+
+
Return type:
+

object

+
+
+
+ +
+ +
+
+class AccumulatorPolicy
+

Bases: TuplePolicy

+

Implements an accumulatory summary policy, where new values +are added to the existing value.

+
+ +
+
+class MinIntPolicy
+

Bases: TuplePolicy

+

Implements a MIN rule, where the smallest integer value is always kept.

+
+ +
+
+class MaxIntPolicy
+

Bases: TuplePolicy

+

Implements a MAX rule, where the largest integer value is always kept.

+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.1/index.html b/docs/5.0.1/index.html new file mode 100644 index 00000000..e2ba4b9d --- /dev/null +++ b/docs/5.0.1/index.html @@ -0,0 +1,215 @@ + + + + + + + Apache DataSketches — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Apache DataSketches

+

DataSketches are highly-efficient algorithms to analyze big data quickly.

+
+

Counting Distincts

+ +
+
+

Quantile Estimation

+ +
+
+

Frequency Sketches

+

This problem may also be known as heavy hitters or TopK

+ +
+
+

Vector Sketches

+ +
+
+

Random Sampling

+ +
+
+

Helper Classes

+ +
+

Note

+

This project is under active development.

+
+
+
+
+

Indices and tables

+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.1/objects.inv b/docs/5.0.1/objects.inv new file mode 100644 index 00000000..bd0053f4 Binary files /dev/null and b/docs/5.0.1/objects.inv differ diff --git a/docs/5.0.1/quantiles/index.html b/docs/5.0.1/quantiles/index.html new file mode 100644 index 00000000..184ed4dc --- /dev/null +++ b/docs/5.0.1/quantiles/index.html @@ -0,0 +1,154 @@ + + + + + + + Quantiles Sketches — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Quantiles Sketches

+

Quantile estimation is useful for understanding the distribution of data values in a stream. The sketches currently +in the library are designed to answer queries about the rank of an item in the stream of items. That is, when +applying a global ordering on all the items, what is the portion of items seen so far that are less than (alternatively, +less-than-or-equal-to) the given item. Using straightforward logic, they can also estimate the item at a given rank +in the stream.

+

These sketches may be used to compute approximate histograms, Probability Mass Functions (PMFs), or +Cumulative Distribution Functions (CDFs).

+

The library provides three types of quantiles sketches, each of which has generic items as well as versions +specific to a given numeric type (e.g. integer or floating point values). All three types provide error +bounds on rank estimation with proven probabilistic error distributions.

+
+
    +
  • KLL: Provides uniform rank estimation error over the entire range

  • +
  • REQ: Provides relative rank error estimates, which decreases approaching either the high or low end values.

  • +
  • Classic quantiles: Largely deprecated in favor of KLL, also provides uniform rank estimation error. Included largely for backwards compatibility with historic data.

  • +
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.1/quantiles/kll.html b/docs/5.0.1/quantiles/kll.html new file mode 100644 index 00000000..0dc2a14b --- /dev/null +++ b/docs/5.0.1/quantiles/kll.html @@ -0,0 +1,964 @@ + + + + + + + KLL Sketch — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

KLL Sketch

+

Implementation of a very compact quantiles sketch with lazy compaction scheme +and nearly optimal accuracy per retained item. +See Optimal Quantile Approximation in Streams.

+

This is a stochastic streaming sketch that enables near real-time analysis of the +approximate distribution of items from a very large stream in a single pass, requiring only +that the items are comparable. +The analysis is obtained using get_quantile() function or the +inverse functions get_rank(), get_pmf() (Probability Mass Function), and get_cdf() +(Cumulative Distribution Function).

+

As of May 2020, this implementation produces serialized sketches which are binary-compatible +with the equivalent Java implementation only when template parameter T = float +(32-bit single precision values).

+

Given an input stream of N items, the natural rank of any specific +item is defined as its index (1 to N) in inclusive mode +or (0 to N-1) in exclusive mode +in the hypothetical sorted stream of all N input items.

+

The normalized rank (rank) of any specific item is defined as its +natural rank divided by N. +Thus, the normalized rank is between zero and one. +In the documentation for this sketch natural rank is never used so any +reference to just rank should be interpreted to mean normalized rank.

+

This sketch is configured with a parameter k, which affects the size of the sketch +and its estimation error.

+

The estimation error is commonly called epsilon (or eps) and is a fraction +between zero and one. Larger values of k result in smaller values of epsilon. +Epsilon is always with respect to the rank and cannot be applied to the +corresponding items.

+

The relationship between the normalized rank and the corresponding items can be viewed +as a two-dimensional monotonic plot with the normalized rank on one axis and the +corresponding items on the other axis. If the y-axis is specified as the item-axis and +the x-axis as the normalized rank, then y = get_quantile(x) is a monotonically +increasing function.

+

The function get_quantile(rank) translates ranks into +corresponding quantiles. The functions get_rank(item), +get_cdf(…) (Cumulative Distribution Function), and get_pmf(…) +(Probability Mass Function) perform the opposite operation and translate items into ranks.

+

The get_pmf(…) function has about 13 to 47% worse rank error (depending +on k) than the other queries because the mass of each “bin” of the PMF has +“double-sided” error from the upper and lower edges of the bin as a result of a subtraction, +as the errors from the two edges can sometimes add.

+

The default k of 200 yields a “single-sided” epsilon of about 1.33% and a +“double-sided” (PMF) epsilon of about 1.65%.

+

A get_quantile(rank) query has the following guarantees: +- Let q = get_quantile(r) where r is the rank between zero and one. +- The quantile q will be an item from the input stream. +- Let true_rank be the true rank of q derived from the hypothetical sorted +stream of all N items. +- Let eps = get_normalized_rank_error(false). +- Then r - eps ≤ true_rank ≤ r + eps with a confidence of 99%. Note that the +error is on the rank, not the quantile.

+

A get_rank(item) query has the following guarantees: +- Let r = get_rank(i) where i is an item between the min and max items of +the input stream. +- Let true_rank be the true rank of i derived from the hypothetical sorted +stream of all N items. +- Let eps = get_normalized_rank_error(false). +- Then r - eps ≤ true_rank ≤ r + eps with a confidence of 99%.

+

A get_pmf() query has the following guarantees: +- Let {r1, r2, …, r(m+1)} = get_pmf(s1, s2, …, sm) where s1, s2 are +split points (items from the input domain) between the min and max items of +the input stream. +- Let mass_i = estimated mass between s_i and s_i+1. +- Let true_mass be the true mass between the items of s_i, +s_i+1 derived from the hypothetical sorted stream of all N items. +- Let eps = get_normalized_rank_error(true). +- then mass - eps ≤ true_mass ≤ mass + eps with a confidence of 99%. +- r(m+1) includes the mass of all points larger than s_m.

+

A get_cdf(…) query has the following guarantees; +- Let {r1, r2, …, r(m+1)} = get_cdf(s1, s2, …, sm) where s1, s2, … are +split points (items from the input domain) between the min and max items of +the input stream. +- Let mass_i = r_(i+1) - r_i. +- Let true_mass be the true mass between the true ranks of s_i, +s_i+1 derived from the hypothetical sorted stream of all N items. +- Let eps = get_normalized_rank_error(true). +- then mass - eps ≤ true_mass ≤ mass + eps with a confidence of 99%. +- 1 - r(m+1) includes the mass of all points larger than s_m.

+

From the above, it might seem like we could make some estimates to bound the +item returned from a call to get_quantile(). The sketch, however, does not +let us derive error bounds or confidences around items. Because errors are independent, we +can approximately bracket a value as shown below, but there are no error estimates available. +Additionally, the interval may be quite large for certain distributions. +- Let q = get_quantile(r), the estimated quantile of rank r. +- Let eps = get_normalized_rank_error(false). +- Let q_lo = estimated quantile of rank (r - eps). +- Let q_hi = estimated quantile of rank (r + eps). +- Then q_lo ≤ q ≤ q_hi, with 99% confidence.

+
+

Note

+

For the kll_items_sketch, objects must be comparable with __lt__.

+
+
+

Note

+

Serializing and deserializing a kll_items_sketch requires the use of a PyObjectSerDe.

+
+
+
+class kll_ints_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.kll_ints_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 200) None
+

Creates a KLL sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 200.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given normalized rank in a hypothetical sorted version of the input stream so far. +For kll_floats_sketch: if the sketch is empty this returns nan. For kll_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: int) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=int32]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class kll_floats_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.kll_floats_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 200) None
+

Creates a KLL sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 200.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given normalized rank in a hypothetical sorted version of the input stream so far. +For kll_floats_sketch: if the sketch is empty this returns nan. For kll_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: float) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=float32]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class kll_doubles_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.kll_doubles_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 200) None
+

Creates a KLL sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 200.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given normalized rank in a hypothetical sorted version of the input stream so far. +For kll_floats_sketch: if the sketch is empty this returns nan. For kll_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: float) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=float64]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class kll_items_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe) _datasketches.kll_items_sketch
+

Deserializes the sketch from a bytes object using the provided serde.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 200) None
+

Creates a KLL sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 200.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given normalized rank in a hypothetical sorted version of the input stream so far. +For kll_floats_sketch: if the sketch is empty this returns nan. For kll_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object using the provided serde.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Updates the sketch with the given value

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.1/quantiles/quantiles_depr.html b/docs/5.0.1/quantiles/quantiles_depr.html new file mode 100644 index 00000000..e63e9176 --- /dev/null +++ b/docs/5.0.1/quantiles/quantiles_depr.html @@ -0,0 +1,903 @@ + + + + + + + Quantiles Sketch (Deprecated) — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Quantiles Sketch (Deprecated)

+

This is a deprecated quantiles sketch that is included for cross-language compatibility. +Most new projects will favor the KLL sketch over this one, or the REQ sketch for higher accuracy +at the very edge of a distribution.

+

This is a stochastic streaming sketch that enables near-real time analysis of the +approximate distribution from a very large stream in a single pass. +The analysis is obtained using get_rank() and get_quantile() functions, +the Probability Mass Function from get_pmf()` and the Cumulative Distribution Function from get_cdf.

+

Consider a large stream of one million values such as packet sizes coming into a network node. +The natural rank of any specific size value is its index in the hypothetical sorted +array of values. +The normalized rank is the natural rank divided by the stream size, +in this case one million. +The value corresponding to the normalized rank of 0.5 represents the 50th percentile or median +value of the distribution, or get_quantile(0.5). +Similarly, the 95th percentile is obtained from get_quantile(0.95).

+

From the min and max values, for example, 1 and 1000 bytes, +you can obtain the PMF from get_pmf(100, 500, 900) that will result in an array of +4 fractional values such as {.4, .3, .2, .1}, which means that +40% of the values were < 100, +30% of the values were ≥ 100 and < 500, +20% of the values were ≥ 500 and < 900, and +10% of the values were ≥ 900. +A frequency histogram can be obtained by multiplying these fractions by get_n(), +which is the total count of values received. +The get_cdf()` works similarly, but produces the cumulative distribution instead.

+

As of November 2021, this implementation produces serialized sketches which are binary-compatible +with the equivalent Java implementation only when template parameter T = double +(64-bit double precision values).

+

The accuracy of this sketch is a function of the configured value k, which also affects +the overall size of the sketch. Accuracy of this quantile sketch is always with respect to +the normalized rank. A k of 128 produces a normalized, rank error of about 1.7%. +For example, the median item returned from get_quantile(0.5) will be between the actual items +from the hypothetically sorted array of input items at normalized ranks of 0.483 and 0.517, with +a confidence of about 99%.

+
+

Note

+

For the quantiles_items_sketch, objects must be comparable with __lt__.

+
+
+

Note

+

Serializing and deserializing a quantiles_items_sketch requires the use of a PyObjectSerDe.

+
+
+
+class quantiles_ints_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.quantiles_ints_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 128) None
+

Creates a classic quantiles sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 128.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given rank in a hypothetical sorted version of the input stream so far. +For quantiles_floats_sketch: if the sketch is empty this returns nan. For quantiles_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: int) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=int32]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class quantiles_floats_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.quantiles_floats_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 128) None
+

Creates a classic quantiles sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 128.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given rank in a hypothetical sorted version of the input stream so far. +For quantiles_floats_sketch: if the sketch is empty this returns nan. For quantiles_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: float) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=float32]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class quantiles_doubles_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.quantiles_doubles_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 128) None
+

Creates a classic quantiles sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 128.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given rank in a hypothetical sorted version of the input stream so far. +For quantiles_floats_sketch: if the sketch is empty this returns nan. For quantiles_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: float) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=float64]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class quantiles_items_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe) _datasketches.quantiles_items_sketch
+

Deserializes the sketch from a bytes object using the provided serde.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 128) None
+

Creates a classic quantiles sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 128.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given rank in a hypothetical sorted version of the input stream so far. +For quantiles_floats_sketch: if the sketch is empty this returns nan. For quantiles_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object using the provided serde.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Updates the sketch with the given value

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.1/quantiles/req.html b/docs/5.0.1/quantiles/req.html new file mode 100644 index 00000000..7ece205d --- /dev/null +++ b/docs/5.0.1/quantiles/req.html @@ -0,0 +1,754 @@ + + + + + + + Relative Error Quantiles (REQ) Sketch — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Relative Error Quantiles (REQ) Sketch

+

This is an implementation based on the paper “Relative Error Streaming Quantiles” by Graham Cormode, Zohar Karnin, Edo Liberty, Justin Thaler, Pavel Veselý, and loosely derived from a Python prototype written by Pavel Veselý.

+

This implementation differs from the algorithm described in the paper in the following:

+

The algorithm requires no upper bound on the stream length. +Instead, each relative-compactor counts the number of compaction operations performed so far (via variable state). +Initially, the relative-compactor starts with INIT_NUMBER_OF_SECTIONS. +Each time the number of compactions (variable state) exceeds 2^{numSections - 1}, we double numSections. +Note that after merging the sketch with another one variable state may not correspond to the number of compactions performed at a particular level, however, +since the state variable never exceeds the number of compactions, the guarantees of the sketch remain valid.

+

The size of each section (variable k and section_size in the code and parameter k in the paper) is +initialized with a number set by the user via variable k. +When the number of sections doubles, we decrease section_size by a factor of sqrt(2). +This is applied at each level separately. +Thus, when we double the number of sections, the nominal compactor size increases by a factor of approx. sqrt(2) (+/- rounding).

+

The merge operation here does not perform “special compactions”, which are used in the paper to allow for a tight mathematical analysis of the sketch. +This implementation provides a number of capabilities not discussed in the paper or provided in the Python prototype.

+

The Python prototype only implemented high accuracy for low ranks. This implementation provides the user with the ability to +choose either high rank accuracy or low rank accuracy at the time of sketch construction. +The Python prototype only implemented a comparison criterion of INCLUSIVE. +This implementation allows the user to use both the INCLUSIVE criterion and the EXCLUSIVE criterion. +This implementation provides extensive debug visibility into the operation of the sketch with two levels of detail output. +This is not only useful for debugging, but is a powerful tool to help users understand how the sketch works.

+
+

Note

+

For the req_items_sketch, objects must be comparable with __lt__.

+
+
+

Note

+

Serializing and deserializing a req_items_sketch requires the use of a PyObjectSerDe.

+
+
+
+class req_ints_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.req_ints_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_RSE(k: int, rank: float, is_hra: bool, n: int) float
+

Returns an a priori estimate of relative standard error (RSE, expressed as a number in [0,1]). Derived from Lemma 12 in http://arxiv.org/abs/2004.01668v2, but the constant factors have been modified based on empirical measurements, for a given value of parameter k. +Normalized rank must be a value between 0.0 and 1.0 (inclusive). If is_hra is True, uses high rank accuracy mode, else low rank accuracy. N is an estimate of the total number of points provided to the sketch.

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 12, is_hra: bool = True) None
+

Creates an REQ sketch instance with the given value of k.

+
+
Parameters:
+
    +
  • k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 12.

  • +
  • is_hra (bool, optional) – Specifies whether the skech has High Rank Accuracy (True) or Low Rank Accuracy. Default True.

  • +
+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, req_floats_sketch returns nan; req_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, req_floats_sketch returns nan; req_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given normalized rank in a hypothetical sorted version of the input stream so far. +For req_floats_sketch: if the sketch is empty this returns nan. For req_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+get_rank_lower_bound
+

Returns an approximate lower bound on the given normalized rank. +Normalized rank must be a value between 0.0 and 1.0 (inclusive); the number of standard deviations must be 1, 2, or 3.

+
+ +
+
+get_rank_upper_bound
+

Returns an approximate upper bound on the given normalized rank. +Normalized rank must be a value between 0.0 and 1.0 (inclusive); the number of standard deviations must be 1, 2, or 3.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+is_hra
+

Returns True if the sketch is in High Rank Accuracy mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: int) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=int32]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class req_floats_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.req_floats_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_RSE(k: int, rank: float, is_hra: bool, n: int) float
+

Returns an a priori estimate of relative standard error (RSE, expressed as a number in [0,1]). Derived from Lemma 12 in http://arxiv.org/abs/2004.01668v2, but the constant factors have been modified based on empirical measurements, for a given value of parameter k. +Normalized rank must be a value between 0.0 and 1.0 (inclusive). If is_hra is True, uses high rank accuracy mode, else low rank accuracy. N is an estimate of the total number of points provided to the sketch.

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 12, is_hra: bool = True) None
+

Creates an REQ sketch instance with the given value of k.

+
+
Parameters:
+
    +
  • k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 12.

  • +
  • is_hra (bool, optional) – Specifies whether the skech has High Rank Accuracy (True) or Low Rank Accuracy. Default True.

  • +
+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, req_floats_sketch returns nan; req_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, req_floats_sketch returns nan; req_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given normalized rank in a hypothetical sorted version of the input stream so far. +For req_floats_sketch: if the sketch is empty this returns nan. For req_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+get_rank_lower_bound
+

Returns an approximate lower bound on the given normalized rank. +Normalized rank must be a value between 0.0 and 1.0 (inclusive); the number of standard deviations must be 1, 2, or 3.

+
+ +
+
+get_rank_upper_bound
+

Returns an approximate upper bound on the given normalized rank. +Normalized rank must be a value between 0.0 and 1.0 (inclusive); the number of standard deviations must be 1, 2, or 3.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+is_hra
+

Returns True if the sketch is in High Rank Accuracy mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: float) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=float32]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class req_items_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe) _datasketches.req_items_sketch
+

Deserializes the sketch from a bytes object using the provided serde.

+
+ +
+
+get_RSE(k: int, rank: float, is_hra: bool, n: int) float
+

Returns an a priori estimate of relative standard error (RSE, expressed as a number in [0,1]). Derived from Lemma 12 in http://arxiv.org/abs/2004.01668v2, but the constant factors have been modified based on empirical measurements, for a given value of parameter k. +Normalized rank must be a value between 0.0 and 1.0 (inclusive). If is_hra is True, uses high rank accuracy mode, else low rank accuracy. N is an estimate of the total number of points provided to the sketch.

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 12, is_hra: bool = True) None
+

Creates an REQ sketch instance with the given value of k.

+
+
Parameters:
+
    +
  • k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 12.

  • +
  • is_hra (bool, optional) – Specifies whether the skech has High Rank Accuracy (True) or Low Rank Accuracy. Default True.

  • +
+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, req_floats_sketch returns nan; req_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, req_floats_sketch returns nan; req_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given normalized rank in a hypothetical sorted version of the input stream so far. +For req_floats_sketch: if the sketch is empty this returns nan. For req_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+get_rank_lower_bound
+

Returns an approximate lower bound on the given normalized rank. +Normalized rank must be a value between 0.0 and 1.0 (inclusive); the number of standard deviations must be 1, 2, or 3.

+
+ +
+
+get_rank_upper_bound
+

Returns an approximate upper bound on the given normalized rank. +Normalized rank must be a value between 0.0 and 1.0 (inclusive); the number of standard deviations must be 1, 2, or 3.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+is_hra
+

Returns True if the sketch is in High Rank Accuracy mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object using the provided serde.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Updates the sketch with the given value

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.1/sampling/ebpps.html b/docs/5.0.1/sampling/ebpps.html new file mode 100644 index 00000000..07b97185 --- /dev/null +++ b/docs/5.0.1/sampling/ebpps.html @@ -0,0 +1,238 @@ + + + + + + + Exact and Bounded, Probabilitiy Proportional to Size (EBPPS) Sampling — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Exact and Bounded, Probabilitiy Proportional to Size (EBPPS) Sampling

+

An EBPPS sketch produces a randome sample of data from a stream of items, ensuring that the probability +of including an item is always exactly equal to the item’s size. The size of an item is defined as its +weight relative to the total weight of all items seen so far by the sketch. In contrast to VarOpt sampling, +this sketch may return fewer than k items in order to keep the probability of including an item strictly +proportional to its size.

+

This sketch is based on: B. Hentschel, P. J. Haas, Y. Tian +“Exact PPS Sampling with Bounded Sample Size”, +Information Processing Letters, 2023.

+

EBPPS sampling is related to reservoir sampling, but handles unequal item weights. +Feeding the sketch items with a uniform weight value will produce a sample equivalent to reservoir sampling.

+
+

Note

+

Serializing and deserializing this sketch requires the use of a PyObjectSerDe.

+
+
+
+class ebpps_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe) _datasketches.ebpps_sketch
+

Reads a bytes object and returns the corresponding ebpps_sketch

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int) None
+

Creates a new EBPPS sketch instance

+
+
Parameters:
+

k (int) – Maximum number of samples in the sketch

+
+
+
+ +
+
+property c
+

The expected number of samples returned upon a call to get_result() or the creation of an iterator. The number is a floating point value, where the fractional portion represents the probability of including a “partial item” from the sample. The value C should be no larger than the sketch’s configured value of k, although numerical precision limitations mean it may exceed k by double precision floating point error margins in certain cases.

+
+ +
+
+get_serialized_size_bytes
+

Computes the size in bytes needed to serialize the current sketch

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+property k
+

The sketch’s maximum configured sample size

+
+ +
+
+merge
+

Merges the sketch with the given sketch

+
+ +
+
+property n
+

The total stream length

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object

+
+ +
+
+to_string
+

Produces a string summary of the sketch and optionally prints the items

+
+ +
+
+update
+

Updates the sketch with the given value and weight

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.1/sampling/index.html b/docs/5.0.1/sampling/index.html new file mode 100644 index 00000000..7cc2cb53 --- /dev/null +++ b/docs/5.0.1/sampling/index.html @@ -0,0 +1,147 @@ + + + + + + + Random Sampling Sketches — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Random Sampling Sketches

+

These sketches are used to randomly sample items. The length of the input +stream does not need to be known in advance.

+

Both VarOpt (Variance Optimal) and EBPPS (Exact and Bounded, +Probability Proportional to Size) sketches will include sample items based on +each item’s weight relative to the weight of the entire stream but +they differ in details:

+
+
    +
  • ebpps_sketch ensures that the probability of including an item is always exactly proportional to the item’s weight.

  • +
  • var_opt_sketch optimizes for applying a predicate to the resulting sample such that the variance of the subset sum after applying the predicate is minimized, even if the inclusion probability differs somewhat from being proportional to the item’s weight.

  • +
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.1/sampling/varopt.html b/docs/5.0.1/sampling/varopt.html new file mode 100644 index 00000000..1b3889f6 --- /dev/null +++ b/docs/5.0.1/sampling/varopt.html @@ -0,0 +1,300 @@ + + + + + + + Variance Optimal Sampling (VarOpt) — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Variance Optimal Sampling (VarOpt)

+

A VarOpt sketch samples data from a stream of items. The sketch is desinged for optimal (minimum) +variance when querying the sketch to estimate subset sums of items matching a provided predicate. +The sketch will produce a sample of size k (or smaller if fewer items have been presented), with +the probability of including an item roughly corresponding it the item’s weight relative to the total +weight of all items presented to the sketch.

+

VarOpt sampling is related to reservoir sampling, with improved error bounds for subset sum estimation. +Feeding the sketch items with a uniform weight value will produce a sample equivalent to reservoir sampling.

+
+

Note

+

Serializing and deserializing this sketch requires the use of a PyObjectSerDe.

+
+
+
+class var_opt_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe) _datasketches.var_opt_sketch
+

Reads a bytes object and returns the corresponding var opt sketch

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int) None
+

Creates a new Var Opt sketch instance

+
+
Parameters:
+

k (int) – Maximum number of samples in the sketch

+
+
+
+ +
+
+estimate_subset_sum
+

Applies a provided predicate to the sketch and returns the estimated total weight matching the predicate, as well as upper and lower bounds on the estimate and the total weight processed by the sketch

+
+ +
+
+get_serialized_size_bytes
+

Computes the size in bytes needed to serialize the current sketch

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+property k
+

Returns the sketch’s maximum configured sample size

+
+ +
+
+property n
+

Returns the total stream length

+
+ +
+
+property num_samples
+

Returns the number of samples currently in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object

+
+ +
+
+to_string
+

Produces a string summary of the sketch and optionally prints the items

+
+ +
+
+update
+

Updates the sketch with the given value and weight

+
+ +
+ +
+
+class var_opt_union(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe) _datasketches.var_opt_union
+

Constructs a var opt union from the given bytes using the provided serde

+
+ +

Non-static Methods:

+
+
+__init__(self, max_k: int) None
+
+ +
+
+get_result
+

Returns a sketch corresponding to the union result

+
+ +
+
+get_serialized_size_bytes
+

Computes the size in bytes needed to serialize the current union

+
+ +
+
+reset
+

Resets the union to the empty state

+
+ +
+
+serialize
+

Serializes the union into a bytes object with the provided serde

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Updates the union with the given sketch

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.1/search.html b/docs/5.0.1/search.html new file mode 100644 index 00000000..21031339 --- /dev/null +++ b/docs/5.0.1/search.html @@ -0,0 +1,136 @@ + + + + + + Search — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ + + + +
+ +
+ +
+
+ +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/docs/5.0.1/searchindex.js b/docs/5.0.1/searchindex.js new file mode 100644 index 00000000..5206d48d --- /dev/null +++ b/docs/5.0.1/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"alltitles": {"Apache DataSketches": [[14, "apache-datasketches"]], "Compressed Probabilistic Counting (CPC)": [[0, "compressed-probabilistic-counting-cpc"]], "CountMin Sketch": [[5, "countmin-sketch"]], "Counting Distincts": [[14, "counting-distincts"]], "Density Sketch": [[22, "density-sketch"]], "Distinct Counting": [[2, "distinct-counting"]], "Exact and Bounded, Probabilitiy Proportional to Size (EBPPS) Sampling": [[19, "exact-and-bounded-probabilitiy-proportional-to-size-ebpps-sampling"]], "Frequency Sketches": [[7, "frequency-sketches"], [14, "frequency-sketches"]], "Frequent Items": [[6, "frequent-items"]], "Helper Classes": [[8, "helper-classes"], [14, "helper-classes"]], "HyperLogLog (HLL)": [[1, "hyperloglog-hll"]], "Indices and tables": [[14, "indices-and-tables"]], "Jaccard Similarity": [[9, "jaccard-similarity"]], "KLL Sketch": [[16, "kll-sketch"]], "Kernel Function": [[10, "kernel-function"]], "Kolmogorov-Smirnov Test": [[11, "kolmogorov-smirnov-test"]], "Quantile Estimation": [[14, "quantile-estimation"]], "Quantiles Sketch (Deprecated)": [[17, "quantiles-sketch-deprecated"]], "Quantiles Sketches": [[15, "quantiles-sketches"]], "Random Sampling": [[14, "random-sampling"]], "Random Sampling Sketches": [[20, "random-sampling-sketches"]], "Relative Error Quantiles (REQ) Sketch": [[18, "relative-error-quantiles-req-sketch"]], "Serialize/Deserialize (SerDe)": [[12, "serialize-deserialize-serde"]], "Theta Sketch": [[3, "theta-sketch"]], "Tuple Policy": [[13, "tuple-policy"]], "Tuple Sketch": [[4, "tuple-sketch"]], "Variance Optimal Sampling (VarOpt)": [[21, "variance-optimal-sampling-varopt"]], "Vector Sketches": [[14, "vector-sketches"], [23, "vector-sketches"]]}, "docnames": ["distinct_counting/cpc", "distinct_counting/hyper_log_log", "distinct_counting/index", "distinct_counting/theta", "distinct_counting/tuple", "frequency/count_min_sketch", "frequency/frequent_items", "frequency/index", "helper/index", "helper/jaccard", "helper/kernel", "helper/ks_test", "helper/serde", "helper/tuple_policy", "index", "quantiles/index", "quantiles/kll", "quantiles/quantiles_depr", "quantiles/req", "sampling/ebpps", "sampling/index", "sampling/varopt", "vector/density_sketch", "vector/index"], "envversion": {"sphinx": 61, "sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2}, "filenames": ["distinct_counting/cpc.rst", "distinct_counting/hyper_log_log.rst", "distinct_counting/index.rst", "distinct_counting/theta.rst", "distinct_counting/tuple.rst", "frequency/count_min_sketch.rst", "frequency/frequent_items.rst", "frequency/index.rst", "helper/index.rst", "helper/jaccard.rst", "helper/kernel.rst", "helper/ks_test.rst", "helper/serde.rst", "helper/tuple_policy.rst", "index.rst", "quantiles/index.rst", "quantiles/kll.rst", "quantiles/quantiles_depr.rst", "quantiles/req.rst", "sampling/ebpps.rst", "sampling/index.rst", "sampling/varopt.rst", "vector/density_sketch.rst", "vector/index.rst"], "indexentries": {"__call__() (kernelfunction method)": [[10, "datasketches.KernelFunction.__call__", false]], "__call__() (tuplepolicy method)": [[13, "datasketches.TuplePolicy.__call__", false]], "__init__() (compact_theta_sketch method)": [[3, "datasketches.compact_theta_sketch.__init__", false]], "__init__() (compact_tuple_sketch method)": [[4, "datasketches.compact_tuple_sketch.__init__", false]], "__init__() (cpc_sketch method)": [[0, "datasketches.cpc_sketch.__init__", false]], "__init__() (cpc_union method)": [[0, "datasketches.cpc_union.__init__", false]], "__init__() (density_sketch method)": [[22, "datasketches.density_sketch.__init__", false]], "__init__() (ebpps_sketch method)": [[19, "datasketches.ebpps_sketch.__init__", false]], "__init__() (frequent_items_sketch method)": [[6, "datasketches.frequent_items_sketch.__init__", false]], "__init__() (frequent_strings_sketch method)": [[6, "datasketches.frequent_strings_sketch.__init__", false]], "__init__() (hll_sketch method)": [[1, "datasketches.hll_sketch.__init__", false]], "__init__() (hll_union method)": [[1, "datasketches.hll_union.__init__", false]], "__init__() (kll_doubles_sketch method)": [[16, "datasketches.kll_doubles_sketch.__init__", false]], "__init__() (kll_floats_sketch method)": [[16, "datasketches.kll_floats_sketch.__init__", false]], "__init__() (kll_ints_sketch method)": [[16, "datasketches.kll_ints_sketch.__init__", false]], "__init__() (kll_items_sketch method)": [[16, "datasketches.kll_items_sketch.__init__", false]], "__init__() (quantiles_doubles_sketch method)": [[17, "datasketches.quantiles_doubles_sketch.__init__", false]], "__init__() (quantiles_floats_sketch method)": [[17, "datasketches.quantiles_floats_sketch.__init__", false]], "__init__() (quantiles_ints_sketch method)": [[17, "datasketches.quantiles_ints_sketch.__init__", false]], "__init__() (quantiles_items_sketch method)": [[17, "datasketches.quantiles_items_sketch.__init__", false]], "__init__() (req_floats_sketch method)": [[18, "datasketches.req_floats_sketch.__init__", false]], "__init__() (req_ints_sketch method)": [[18, "datasketches.req_ints_sketch.__init__", false]], "__init__() (req_items_sketch method)": [[18, "datasketches.req_items_sketch.__init__", false]], "__init__() (theta_a_not_b method)": [[3, "datasketches.theta_a_not_b.__init__", false]], "__init__() (theta_intersection method)": [[3, "datasketches.theta_intersection.__init__", false]], "__init__() (theta_union method)": [[3, "datasketches.theta_union.__init__", false]], "__init__() (tuple_a_not_b method)": [[4, "datasketches.tuple_a_not_b.__init__", false]], "__init__() (tuple_intersection method)": [[4, "datasketches.tuple_intersection.__init__", false]], "__init__() (tuple_union method)": [[4, "datasketches.tuple_union.__init__", false]], "__init__() (update_theta_sketch method)": [[3, "datasketches.update_theta_sketch.__init__", false]], "__init__() (update_tuple_sketch method)": [[4, "datasketches.update_tuple_sketch.__init__", false]], "__init__() (var_opt_sketch method)": [[21, "datasketches.var_opt_sketch.__init__", false]], "__init__() (var_opt_union method)": [[21, "datasketches.var_opt_union.__init__", false]], "accumulatorpolicy (class in datasketches)": [[13, "datasketches.AccumulatorPolicy", false]], "c (ebpps_sketch property)": [[19, "datasketches.ebpps_sketch.c", false]], "compact (update_theta_sketch attribute)": [[3, "datasketches.update_theta_sketch.compact", false]], "compact (update_tuple_sketch attribute)": [[4, "datasketches.update_tuple_sketch.compact", false]], "compact_theta_sketch (class in datasketches)": [[3, "datasketches.compact_theta_sketch", false]], "compact_tuple_sketch (class in datasketches)": [[4, "datasketches.compact_tuple_sketch", false]], "compute (theta_a_not_b attribute)": [[3, "datasketches.theta_a_not_b.compute", false]], "compute (tuple_a_not_b attribute)": [[4, "datasketches.tuple_a_not_b.compute", false]], "count_min_sketch (class in _datasketches)": [[5, "datasketches.count_min_sketch", false]], "cpc_sketch (class in _datasketches)": [[0, "datasketches.cpc_sketch", false]], "cpc_union (class in _datasketches)": [[0, "datasketches.cpc_union", false]], "create_summary() (tuplepolicy method)": [[13, "datasketches.TuplePolicy.create_summary", false]], "default_seed (tuple_sketch attribute)": [[4, "datasketches.tuple_sketch.DEFAULT_SEED", false]], "density_sketch (class in datasketches)": [[22, "datasketches.density_sketch", false]], "deserialize() (compact_theta_sketch method)": [[3, "datasketches.compact_theta_sketch.deserialize", false]], "deserialize() (compact_tuple_sketch method)": [[4, "datasketches.compact_tuple_sketch.deserialize", false]], "deserialize() (count_min_sketch method)": [[5, "datasketches.count_min_sketch.deserialize", false]], "deserialize() (cpc_sketch method)": [[0, "datasketches.cpc_sketch.deserialize", false]], "deserialize() (density_sketch method)": [[22, "datasketches.density_sketch.deserialize", false]], "deserialize() (ebpps_sketch method)": [[19, "datasketches.ebpps_sketch.deserialize", false]], "deserialize() (frequent_items_sketch method)": [[6, "datasketches.frequent_items_sketch.deserialize", false]], "deserialize() (frequent_strings_sketch method)": [[6, "datasketches.frequent_strings_sketch.deserialize", false]], "deserialize() (hll_sketch method)": [[1, "datasketches.hll_sketch.deserialize", false]], "deserialize() (kll_doubles_sketch method)": [[16, "datasketches.kll_doubles_sketch.deserialize", false]], "deserialize() (kll_floats_sketch method)": [[16, "datasketches.kll_floats_sketch.deserialize", false]], "deserialize() (kll_ints_sketch method)": [[16, "datasketches.kll_ints_sketch.deserialize", false]], "deserialize() (kll_items_sketch method)": [[16, "datasketches.kll_items_sketch.deserialize", false]], "deserialize() (quantiles_doubles_sketch method)": [[17, "datasketches.quantiles_doubles_sketch.deserialize", false]], "deserialize() (quantiles_floats_sketch method)": [[17, "datasketches.quantiles_floats_sketch.deserialize", false]], "deserialize() (quantiles_ints_sketch method)": [[17, "datasketches.quantiles_ints_sketch.deserialize", false]], "deserialize() (quantiles_items_sketch method)": [[17, "datasketches.quantiles_items_sketch.deserialize", false]], "deserialize() (req_floats_sketch method)": [[18, "datasketches.req_floats_sketch.deserialize", false]], "deserialize() (req_ints_sketch method)": [[18, "datasketches.req_ints_sketch.deserialize", false]], "deserialize() (req_items_sketch method)": [[18, "datasketches.req_items_sketch.deserialize", false]], "deserialize() (var_opt_sketch method)": [[21, "datasketches.var_opt_sketch.deserialize", false]], "deserialize() (var_opt_union method)": [[21, "datasketches.var_opt_union.deserialize", false]], "dim (density_sketch property)": [[22, "datasketches.density_sketch.dim", false]], "dissimilarity_test() (theta_jaccard_similarity method)": [[9, "datasketches.theta_jaccard_similarity.dissimilarity_test", false]], "dissimilarity_test() (tuple_jaccard_similarity method)": [[9, "datasketches.tuple_jaccard_similarity.dissimilarity_test", false]], "ebpps_sketch (class in datasketches)": [[19, "datasketches.ebpps_sketch", false]], "epsilon (frequent_items_sketch property)": [[6, "datasketches.frequent_items_sketch.epsilon", false]], "epsilon (frequent_strings_sketch property)": [[6, "datasketches.frequent_strings_sketch.epsilon", false]], "estimate_subset_sum (var_opt_sketch attribute)": [[21, "datasketches.var_opt_sketch.estimate_subset_sum", false]], "exactly_equal() (theta_jaccard_similarity method)": [[9, "datasketches.theta_jaccard_similarity.exactly_equal", false]], "exactly_equal() (tuple_jaccard_similarity method)": [[9, "datasketches.tuple_jaccard_similarity.exactly_equal", false]], "frequent_items_error_type (class in datasketches)": [[6, "datasketches.frequent_items_error_type", false]], "frequent_items_sketch (class in datasketches)": [[6, "datasketches.frequent_items_sketch", false]], "frequent_strings_sketch (class in datasketches)": [[6, "datasketches.frequent_strings_sketch", false]], "from_bytes() (pyobjectserde method)": [[12, "datasketches.PyObjectSerDe.from_bytes", false]], "gaussiankernel (class in datasketches)": [[10, "datasketches.GaussianKernel", false]], "get_apriori_error() (frequent_items_sketch method)": [[6, "datasketches.frequent_items_sketch.get_apriori_error", false]], "get_apriori_error() (frequent_strings_sketch method)": [[6, "datasketches.frequent_strings_sketch.get_apriori_error", false]], "get_cdf (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.get_cdf", false]], "get_cdf (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.get_cdf", false]], "get_cdf (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.get_cdf", false]], "get_cdf (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.get_cdf", false]], "get_cdf (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.get_cdf", false]], "get_cdf (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.get_cdf", false]], "get_cdf (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.get_cdf", false]], "get_cdf (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.get_cdf", false]], "get_cdf (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.get_cdf", false]], "get_cdf (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.get_cdf", false]], "get_cdf (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.get_cdf", false]], "get_compact_serialization_bytes (hll_sketch attribute)": [[1, "datasketches.hll_sketch.get_compact_serialization_bytes", false]], "get_epsilon_for_lg_size() (frequent_items_sketch method)": [[6, "datasketches.frequent_items_sketch.get_epsilon_for_lg_size", false]], "get_epsilon_for_lg_size() (frequent_strings_sketch method)": [[6, "datasketches.frequent_strings_sketch.get_epsilon_for_lg_size", false]], "get_estimate (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.get_estimate", false]], "get_estimate (cpc_sketch attribute)": [[0, "datasketches.cpc_sketch.get_estimate", false]], "get_estimate (density_sketch attribute)": [[22, "datasketches.density_sketch.get_estimate", false]], "get_estimate (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.get_estimate", false]], "get_estimate (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.get_estimate", false]], "get_estimate (hll_sketch attribute)": [[1, "datasketches.hll_sketch.get_estimate", false]], "get_estimate (hll_union attribute)": [[1, "datasketches.hll_union.get_estimate", false]], "get_estimate (theta_sketch attribute)": [[3, "datasketches.theta_sketch.get_estimate", false]], "get_estimate (tuple_sketch attribute)": [[4, "datasketches.tuple_sketch.get_estimate", false]], "get_frequent_items (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.get_frequent_items", false]], "get_frequent_items (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.get_frequent_items", false]], "get_lower_bound (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.get_lower_bound", false]], "get_lower_bound (cpc_sketch attribute)": [[0, "datasketches.cpc_sketch.get_lower_bound", false]], "get_lower_bound (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.get_lower_bound", false]], "get_lower_bound (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.get_lower_bound", false]], "get_lower_bound (hll_sketch attribute)": [[1, "datasketches.hll_sketch.get_lower_bound", false]], "get_lower_bound (hll_union attribute)": [[1, "datasketches.hll_union.get_lower_bound", false]], "get_lower_bound (theta_sketch attribute)": [[3, "datasketches.theta_sketch.get_lower_bound", false]], "get_lower_bound (tuple_sketch attribute)": [[4, "datasketches.tuple_sketch.get_lower_bound", false]], "get_max_updatable_serialization_bytes() (hll_sketch method)": [[1, "datasketches.hll_sketch.get_max_updatable_serialization_bytes", false]], "get_max_value (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.get_max_value", false]], "get_max_value (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.get_max_value", false]], "get_max_value (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.get_max_value", false]], "get_max_value (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.get_max_value", false]], "get_max_value (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.get_max_value", false]], "get_max_value (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.get_max_value", false]], "get_max_value (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.get_max_value", false]], "get_max_value (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.get_max_value", false]], "get_max_value (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.get_max_value", false]], "get_max_value (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.get_max_value", false]], "get_max_value (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.get_max_value", false]], "get_min_value (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.get_min_value", false]], "get_min_value (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.get_min_value", false]], "get_min_value (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.get_min_value", false]], "get_min_value (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.get_min_value", false]], "get_min_value (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.get_min_value", false]], "get_min_value (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.get_min_value", false]], "get_min_value (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.get_min_value", false]], "get_min_value (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.get_min_value", false]], "get_min_value (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.get_min_value", false]], "get_min_value (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.get_min_value", false]], "get_min_value (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.get_min_value", false]], "get_normalized_rank_error() (kll_doubles_sketch method)": [[16, "datasketches.kll_doubles_sketch.get_normalized_rank_error", false]], "get_normalized_rank_error() (kll_floats_sketch method)": [[16, "datasketches.kll_floats_sketch.get_normalized_rank_error", false]], "get_normalized_rank_error() (kll_ints_sketch method)": [[16, "datasketches.kll_ints_sketch.get_normalized_rank_error", false]], "get_normalized_rank_error() (kll_items_sketch method)": [[16, "datasketches.kll_items_sketch.get_normalized_rank_error", false]], "get_normalized_rank_error() (quantiles_doubles_sketch method)": [[17, "datasketches.quantiles_doubles_sketch.get_normalized_rank_error", false]], "get_normalized_rank_error() (quantiles_floats_sketch method)": [[17, "datasketches.quantiles_floats_sketch.get_normalized_rank_error", false]], "get_normalized_rank_error() (quantiles_ints_sketch method)": [[17, "datasketches.quantiles_ints_sketch.get_normalized_rank_error", false]], "get_normalized_rank_error() (quantiles_items_sketch method)": [[17, "datasketches.quantiles_items_sketch.get_normalized_rank_error", false]], "get_pmf (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.get_pmf", false]], "get_pmf (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.get_pmf", false]], "get_pmf (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.get_pmf", false]], "get_pmf (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.get_pmf", false]], "get_pmf (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.get_pmf", false]], "get_pmf (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.get_pmf", false]], "get_pmf (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.get_pmf", false]], "get_pmf (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.get_pmf", false]], "get_pmf (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.get_pmf", false]], "get_pmf (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.get_pmf", false]], "get_pmf (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.get_pmf", false]], "get_quantile (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.get_quantile", false]], "get_quantile (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.get_quantile", false]], "get_quantile (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.get_quantile", false]], "get_quantile (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.get_quantile", false]], "get_quantile (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.get_quantile", false]], "get_quantile (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.get_quantile", false]], "get_quantile (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.get_quantile", false]], "get_quantile (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.get_quantile", false]], "get_quantile (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.get_quantile", false]], "get_quantile (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.get_quantile", false]], "get_quantile (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.get_quantile", false]], "get_quantiles (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.get_quantiles", false]], "get_quantiles (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.get_quantiles", false]], "get_quantiles (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.get_quantiles", false]], "get_quantiles (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.get_quantiles", false]], "get_quantiles (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.get_quantiles", false]], "get_quantiles (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.get_quantiles", false]], "get_quantiles (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.get_quantiles", false]], "get_quantiles (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.get_quantiles", false]], "get_quantiles (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.get_quantiles", false]], "get_quantiles (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.get_quantiles", false]], "get_quantiles (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.get_quantiles", false]], "get_rank (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.get_rank", false]], "get_rank (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.get_rank", false]], "get_rank (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.get_rank", false]], "get_rank (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.get_rank", false]], "get_rank (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.get_rank", false]], "get_rank (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.get_rank", false]], "get_rank (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.get_rank", false]], "get_rank (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.get_rank", false]], "get_rank (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.get_rank", false]], "get_rank (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.get_rank", false]], "get_rank (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.get_rank", false]], "get_rank_lower_bound (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.get_rank_lower_bound", false]], "get_rank_lower_bound (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.get_rank_lower_bound", false]], "get_rank_lower_bound (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.get_rank_lower_bound", false]], "get_rank_upper_bound (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.get_rank_upper_bound", false]], "get_rank_upper_bound (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.get_rank_upper_bound", false]], "get_rank_upper_bound (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.get_rank_upper_bound", false]], "get_rel_err() (hll_sketch method)": [[1, "datasketches.hll_sketch.get_rel_err", false]], "get_rel_err() (hll_union method)": [[1, "datasketches.hll_union.get_rel_err", false]], "get_relative_error (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.get_relative_error", false]], "get_result (cpc_union attribute)": [[0, "datasketches.cpc_union.get_result", false]], "get_result (hll_union attribute)": [[1, "datasketches.hll_union.get_result", false]], "get_result (theta_intersection attribute)": [[3, "datasketches.theta_intersection.get_result", false]], "get_result (theta_union attribute)": [[3, "datasketches.theta_union.get_result", false]], "get_result (tuple_intersection attribute)": [[4, "datasketches.tuple_intersection.get_result", false]], "get_result (tuple_union attribute)": [[4, "datasketches.tuple_union.get_result", false]], "get_result (var_opt_union attribute)": [[21, "datasketches.var_opt_union.get_result", false]], "get_rse() (req_floats_sketch method)": [[18, "datasketches.req_floats_sketch.get_RSE", false]], "get_rse() (req_ints_sketch method)": [[18, "datasketches.req_ints_sketch.get_RSE", false]], "get_rse() (req_items_sketch method)": [[18, "datasketches.req_items_sketch.get_RSE", false]], "get_seed_hash (theta_sketch attribute)": [[3, "datasketches.theta_sketch.get_seed_hash", false]], "get_seed_hash (tuple_sketch attribute)": [[4, "datasketches.tuple_sketch.get_seed_hash", false]], "get_serialized_size_bytes (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.get_serialized_size_bytes", false]], "get_serialized_size_bytes (ebpps_sketch attribute)": [[19, "datasketches.ebpps_sketch.get_serialized_size_bytes", false]], "get_serialized_size_bytes (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.get_serialized_size_bytes", false]], "get_serialized_size_bytes (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.get_serialized_size_bytes", false]], "get_serialized_size_bytes (var_opt_sketch attribute)": [[21, "datasketches.var_opt_sketch.get_serialized_size_bytes", false]], "get_serialized_size_bytes (var_opt_union attribute)": [[21, "datasketches.var_opt_union.get_serialized_size_bytes", false]], "get_size() (pyobjectserde method)": [[12, "datasketches.PyObjectSerDe.get_size", false]], "get_updatable_serialization_bytes (hll_sketch attribute)": [[1, "datasketches.hll_sketch.get_updatable_serialization_bytes", false]], "get_upper_bound (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.get_upper_bound", false]], "get_upper_bound (cpc_sketch attribute)": [[0, "datasketches.cpc_sketch.get_upper_bound", false]], "get_upper_bound (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.get_upper_bound", false]], "get_upper_bound (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.get_upper_bound", false]], "get_upper_bound (hll_sketch attribute)": [[1, "datasketches.hll_sketch.get_upper_bound", false]], "get_upper_bound (hll_union attribute)": [[1, "datasketches.hll_union.get_upper_bound", false]], "get_upper_bound (theta_sketch attribute)": [[3, "datasketches.theta_sketch.get_upper_bound", false]], "get_upper_bound (tuple_sketch attribute)": [[4, "datasketches.tuple_sketch.get_upper_bound", false]], "has_result (theta_intersection attribute)": [[3, "datasketches.theta_intersection.has_result", false]], "has_result (tuple_intersection attribute)": [[4, "datasketches.tuple_intersection.has_result", false]], "hll_4 (tgt_hll_type attribute)": [[1, "datasketches.tgt_hll_type.HLL_4", false]], "hll_6 (tgt_hll_type attribute)": [[1, "datasketches.tgt_hll_type.HLL_6", false]], "hll_8 (tgt_hll_type attribute)": [[1, "datasketches.tgt_hll_type.HLL_8", false]], "hll_sketch (class in _datasketches)": [[1, "datasketches.hll_sketch", false]], "hll_union (class in _datasketches)": [[1, "datasketches.hll_union", false]], "is_compact (hll_sketch attribute)": [[1, "datasketches.hll_sketch.is_compact", false]], "is_empty (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.is_empty", false]], "is_empty (cpc_sketch attribute)": [[0, "datasketches.cpc_sketch.is_empty", false]], "is_empty (density_sketch attribute)": [[22, "datasketches.density_sketch.is_empty", false]], "is_empty (ebpps_sketch attribute)": [[19, "datasketches.ebpps_sketch.is_empty", false]], "is_empty (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.is_empty", false]], "is_empty (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.is_empty", false]], "is_empty (hll_sketch attribute)": [[1, "datasketches.hll_sketch.is_empty", false]], "is_empty (hll_union attribute)": [[1, "datasketches.hll_union.is_empty", false]], "is_empty (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.is_empty", false]], "is_empty (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.is_empty", false]], "is_empty (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.is_empty", false]], "is_empty (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.is_empty", false]], "is_empty (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.is_empty", false]], "is_empty (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.is_empty", false]], "is_empty (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.is_empty", false]], "is_empty (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.is_empty", false]], "is_empty (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.is_empty", false]], "is_empty (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.is_empty", false]], "is_empty (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.is_empty", false]], "is_empty (theta_sketch attribute)": [[3, "datasketches.theta_sketch.is_empty", false]], "is_empty (tuple_sketch attribute)": [[4, "datasketches.tuple_sketch.is_empty", false]], "is_empty (var_opt_sketch attribute)": [[21, "datasketches.var_opt_sketch.is_empty", false]], "is_estimation_mode (density_sketch attribute)": [[22, "datasketches.density_sketch.is_estimation_mode", false]], "is_estimation_mode (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.is_estimation_mode", false]], "is_estimation_mode (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.is_estimation_mode", false]], "is_estimation_mode (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.is_estimation_mode", false]], "is_estimation_mode (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.is_estimation_mode", false]], "is_estimation_mode (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.is_estimation_mode", false]], "is_estimation_mode (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.is_estimation_mode", false]], "is_estimation_mode (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.is_estimation_mode", false]], "is_estimation_mode (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.is_estimation_mode", false]], "is_estimation_mode (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.is_estimation_mode", false]], "is_estimation_mode (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.is_estimation_mode", false]], "is_estimation_mode (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.is_estimation_mode", false]], "is_estimation_mode (theta_sketch attribute)": [[3, "datasketches.theta_sketch.is_estimation_mode", false]], "is_estimation_mode (tuple_sketch attribute)": [[4, "datasketches.tuple_sketch.is_estimation_mode", false]], "is_hra (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.is_hra", false]], "is_hra (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.is_hra", false]], "is_hra (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.is_hra", false]], "is_ordered (theta_sketch attribute)": [[3, "datasketches.theta_sketch.is_ordered", false]], "is_ordered (tuple_sketch attribute)": [[4, "datasketches.tuple_sketch.is_ordered", false]], "jaccard() (theta_jaccard_similarity method)": [[9, "datasketches.theta_jaccard_similarity.jaccard", false]], "jaccard() (tuple_jaccard_similarity method)": [[9, "datasketches.tuple_jaccard_similarity.jaccard", false]], "k (density_sketch property)": [[22, "datasketches.density_sketch.k", false]], "k (ebpps_sketch property)": [[19, "datasketches.ebpps_sketch.k", false]], "k (kll_doubles_sketch property)": [[16, "datasketches.kll_doubles_sketch.k", false]], "k (kll_floats_sketch property)": [[16, "datasketches.kll_floats_sketch.k", false]], "k (kll_ints_sketch property)": [[16, "datasketches.kll_ints_sketch.k", false]], "k (kll_items_sketch property)": [[16, "datasketches.kll_items_sketch.k", false]], "k (quantiles_doubles_sketch property)": [[17, "datasketches.quantiles_doubles_sketch.k", false]], "k (quantiles_floats_sketch property)": [[17, "datasketches.quantiles_floats_sketch.k", false]], "k (quantiles_ints_sketch property)": [[17, "datasketches.quantiles_ints_sketch.k", false]], "k (quantiles_items_sketch property)": [[17, "datasketches.quantiles_items_sketch.k", false]], "k (req_floats_sketch property)": [[18, "datasketches.req_floats_sketch.k", false]], "k (req_ints_sketch property)": [[18, "datasketches.req_ints_sketch.k", false]], "k (req_items_sketch property)": [[18, "datasketches.req_items_sketch.k", false]], "k (var_opt_sketch property)": [[21, "datasketches.var_opt_sketch.k", false]], "kernelfunction (class in datasketches)": [[10, "datasketches.KernelFunction", false]], "kll_doubles_sketch (class in datasketches)": [[16, "datasketches.kll_doubles_sketch", false]], "kll_floats_sketch (class in datasketches)": [[16, "datasketches.kll_floats_sketch", false]], "kll_ints_sketch (class in datasketches)": [[16, "datasketches.kll_ints_sketch", false]], "kll_items_sketch (class in datasketches)": [[16, "datasketches.kll_items_sketch", false]], "ks_test() (in module datasketches)": [[11, "datasketches.ks_test", false]], "lg_config_k (hll_sketch property)": [[1, "datasketches.hll_sketch.lg_config_k", false]], "lg_config_k (hll_union property)": [[1, "datasketches.hll_union.lg_config_k", false]], "lg_k (cpc_sketch property)": [[0, "datasketches.cpc_sketch.lg_k", false]], "maxintpolicy (class in datasketches)": [[13, "datasketches.MaxIntPolicy", false]], "merge (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.merge", false]], "merge (density_sketch attribute)": [[22, "datasketches.density_sketch.merge", false]], "merge (ebpps_sketch attribute)": [[19, "datasketches.ebpps_sketch.merge", false]], "merge (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.merge", false]], "merge (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.merge", false]], "merge (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.merge", false]], "merge (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.merge", false]], "merge (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.merge", false]], "merge (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.merge", false]], "merge (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.merge", false]], "merge (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.merge", false]], "merge (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.merge", false]], "merge (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.merge", false]], "merge (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.merge", false]], "merge (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.merge", false]], "merge (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.merge", false]], "minintpolicy (class in datasketches)": [[13, "datasketches.MinIntPolicy", false]], "n (density_sketch property)": [[22, "datasketches.density_sketch.n", false]], "n (ebpps_sketch property)": [[19, "datasketches.ebpps_sketch.n", false]], "n (kll_doubles_sketch property)": [[16, "datasketches.kll_doubles_sketch.n", false]], "n (kll_floats_sketch property)": [[16, "datasketches.kll_floats_sketch.n", false]], "n (kll_ints_sketch property)": [[16, "datasketches.kll_ints_sketch.n", false]], "n (kll_items_sketch property)": [[16, "datasketches.kll_items_sketch.n", false]], "n (quantiles_doubles_sketch property)": [[17, "datasketches.quantiles_doubles_sketch.n", false]], "n (quantiles_floats_sketch property)": [[17, "datasketches.quantiles_floats_sketch.n", false]], "n (quantiles_ints_sketch property)": [[17, "datasketches.quantiles_ints_sketch.n", false]], "n (quantiles_items_sketch property)": [[17, "datasketches.quantiles_items_sketch.n", false]], "n (req_floats_sketch property)": [[18, "datasketches.req_floats_sketch.n", false]], "n (req_ints_sketch property)": [[18, "datasketches.req_ints_sketch.n", false]], "n (req_items_sketch property)": [[18, "datasketches.req_items_sketch.n", false]], "n (var_opt_sketch property)": [[21, "datasketches.var_opt_sketch.n", false]], "no_false_negatives (frequent_items_error_type attribute)": [[6, "datasketches.frequent_items_error_type.NO_FALSE_NEGATIVES", false]], "no_false_positives (frequent_items_error_type attribute)": [[6, "datasketches.frequent_items_error_type.NO_FALSE_POSITIVES", false]], "normalized_rank_error (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.normalized_rank_error", false]], "normalized_rank_error (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.normalized_rank_error", false]], "normalized_rank_error (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.normalized_rank_error", false]], "normalized_rank_error (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.normalized_rank_error", false]], "normalized_rank_error (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.normalized_rank_error", false]], "normalized_rank_error (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.normalized_rank_error", false]], "normalized_rank_error (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.normalized_rank_error", false]], "normalized_rank_error (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.normalized_rank_error", false]], "num_active_items (frequent_items_sketch property)": [[6, "datasketches.frequent_items_sketch.num_active_items", false]], "num_active_items (frequent_strings_sketch property)": [[6, "datasketches.frequent_strings_sketch.num_active_items", false]], "num_buckets (count_min_sketch property)": [[5, "datasketches.count_min_sketch.num_buckets", false]], "num_hashes (count_min_sketch property)": [[5, "datasketches.count_min_sketch.num_hashes", false]], "num_retained (density_sketch property)": [[22, "datasketches.density_sketch.num_retained", false]], "num_retained (kll_doubles_sketch property)": [[16, "datasketches.kll_doubles_sketch.num_retained", false]], "num_retained (kll_floats_sketch property)": [[16, "datasketches.kll_floats_sketch.num_retained", false]], "num_retained (kll_ints_sketch property)": [[16, "datasketches.kll_ints_sketch.num_retained", false]], "num_retained (kll_items_sketch property)": [[16, "datasketches.kll_items_sketch.num_retained", false]], "num_retained (quantiles_doubles_sketch property)": [[17, "datasketches.quantiles_doubles_sketch.num_retained", false]], "num_retained (quantiles_floats_sketch property)": [[17, "datasketches.quantiles_floats_sketch.num_retained", false]], "num_retained (quantiles_ints_sketch property)": [[17, "datasketches.quantiles_ints_sketch.num_retained", false]], "num_retained (quantiles_items_sketch property)": [[17, "datasketches.quantiles_items_sketch.num_retained", false]], "num_retained (req_floats_sketch property)": [[18, "datasketches.req_floats_sketch.num_retained", false]], "num_retained (req_ints_sketch property)": [[18, "datasketches.req_ints_sketch.num_retained", false]], "num_retained (req_items_sketch property)": [[18, "datasketches.req_items_sketch.num_retained", false]], "num_retained (theta_sketch property)": [[3, "datasketches.theta_sketch.num_retained", false]], "num_retained (tuple_sketch property)": [[4, "datasketches.tuple_sketch.num_retained", false]], "num_samples (var_opt_sketch property)": [[21, "datasketches.var_opt_sketch.num_samples", false]], "pydoublesserde (class in datasketches)": [[12, "datasketches.PyDoublesSerDe", false]], "pyfloatsserde (class in datasketches)": [[12, "datasketches.PyFloatsSerDe", false]], "pyintsserde (class in datasketches)": [[12, "datasketches.PyIntsSerDe", false]], "pylongsserde (class in datasketches)": [[12, "datasketches.PyLongsSerDe", false]], "pyobjectserde (class in datasketches)": [[12, "datasketches.PyObjectSerDe", false]], "pystringsserde (class in datasketches)": [[12, "datasketches.PyStringsSerDe", false]], "quantiles_doubles_sketch (class in datasketches)": [[17, "datasketches.quantiles_doubles_sketch", false]], "quantiles_floats_sketch (class in datasketches)": [[17, "datasketches.quantiles_floats_sketch", false]], "quantiles_ints_sketch (class in datasketches)": [[17, "datasketches.quantiles_ints_sketch", false]], "quantiles_items_sketch (class in datasketches)": [[17, "datasketches.quantiles_items_sketch", false]], "req_floats_sketch (class in datasketches)": [[18, "datasketches.req_floats_sketch", false]], "req_ints_sketch (class in datasketches)": [[18, "datasketches.req_ints_sketch", false]], "req_items_sketch (class in datasketches)": [[18, "datasketches.req_items_sketch", false]], "reset (hll_sketch attribute)": [[1, "datasketches.hll_sketch.reset", false]], "reset (hll_union attribute)": [[1, "datasketches.hll_union.reset", false]], "reset (tuple_union attribute)": [[4, "datasketches.tuple_union.reset", false]], "reset (update_theta_sketch attribute)": [[3, "datasketches.update_theta_sketch.reset", false]], "reset (update_tuple_sketch attribute)": [[4, "datasketches.update_tuple_sketch.reset", false]], "reset (var_opt_union attribute)": [[21, "datasketches.var_opt_union.reset", false]], "seed (count_min_sketch property)": [[5, "datasketches.count_min_sketch.seed", false]], "serialize (compact_theta_sketch attribute)": [[3, "datasketches.compact_theta_sketch.serialize", false]], "serialize (compact_tuple_sketch attribute)": [[4, "datasketches.compact_tuple_sketch.serialize", false]], "serialize (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.serialize", false]], "serialize (cpc_sketch attribute)": [[0, "datasketches.cpc_sketch.serialize", false]], "serialize (density_sketch attribute)": [[22, "datasketches.density_sketch.serialize", false]], "serialize (ebpps_sketch attribute)": [[19, "datasketches.ebpps_sketch.serialize", false]], "serialize (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.serialize", false]], "serialize (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.serialize", false]], "serialize (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.serialize", false]], "serialize (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.serialize", false]], "serialize (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.serialize", false]], "serialize (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.serialize", false]], "serialize (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.serialize", false]], "serialize (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.serialize", false]], "serialize (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.serialize", false]], "serialize (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.serialize", false]], "serialize (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.serialize", false]], "serialize (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.serialize", false]], "serialize (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.serialize", false]], "serialize (var_opt_sketch attribute)": [[21, "datasketches.var_opt_sketch.serialize", false]], "serialize (var_opt_union attribute)": [[21, "datasketches.var_opt_union.serialize", false]], "serialize_compact (hll_sketch attribute)": [[1, "datasketches.hll_sketch.serialize_compact", false]], "serialize_updatable (hll_sketch attribute)": [[1, "datasketches.hll_sketch.serialize_updatable", false]], "similarity_test() (theta_jaccard_similarity method)": [[9, "datasketches.theta_jaccard_similarity.similarity_test", false]], "similarity_test() (tuple_jaccard_similarity method)": [[9, "datasketches.tuple_jaccard_similarity.similarity_test", false]], "suggest_num_buckets() (count_min_sketch method)": [[5, "datasketches.count_min_sketch.suggest_num_buckets", false]], "suggest_num_hashes() (count_min_sketch method)": [[5, "datasketches.count_min_sketch.suggest_num_hashes", false]], "tgt_hll_type (class in _datasketches)": [[1, "datasketches.tgt_hll_type", false]], "tgt_type (hll_sketch property)": [[1, "datasketches.hll_sketch.tgt_type", false]], "theta (theta_sketch property)": [[3, "datasketches.theta_sketch.theta", false]], "theta (tuple_sketch property)": [[4, "datasketches.tuple_sketch.theta", false]], "theta64 (theta_sketch property)": [[3, "datasketches.theta_sketch.theta64", false]], "theta64 (tuple_sketch property)": [[4, "datasketches.tuple_sketch.theta64", false]], "theta_a_not_b (class in datasketches)": [[3, "datasketches.theta_a_not_b", false]], "theta_intersection (class in datasketches)": [[3, "datasketches.theta_intersection", false]], "theta_jaccard_similarity (class in datasketches)": [[9, "datasketches.theta_jaccard_similarity", false]], "theta_sketch (class in datasketches)": [[3, "datasketches.theta_sketch", false]], "theta_union (class in datasketches)": [[3, "datasketches.theta_union", false]], "to_bytes() (pyobjectserde method)": [[12, "datasketches.PyObjectSerDe.to_bytes", false]], "to_string (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.to_string", false]], "to_string (cpc_sketch attribute)": [[0, "datasketches.cpc_sketch.to_string", false]], "to_string (density_sketch attribute)": [[22, "datasketches.density_sketch.to_string", false]], "to_string (ebpps_sketch attribute)": [[19, "datasketches.ebpps_sketch.to_string", false]], "to_string (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.to_string", false]], "to_string (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.to_string", false]], "to_string (hll_sketch attribute)": [[1, "datasketches.hll_sketch.to_string", false]], "to_string (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.to_string", false]], "to_string (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.to_string", false]], "to_string (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.to_string", false]], "to_string (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.to_string", false]], "to_string (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.to_string", false]], "to_string (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.to_string", false]], "to_string (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.to_string", false]], "to_string (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.to_string", false]], "to_string (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.to_string", false]], "to_string (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.to_string", false]], "to_string (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.to_string", false]], "to_string (theta_sketch attribute)": [[3, "datasketches.theta_sketch.to_string", false]], "to_string (tuple_sketch attribute)": [[4, "datasketches.tuple_sketch.to_string", false]], "to_string (var_opt_sketch attribute)": [[21, "datasketches.var_opt_sketch.to_string", false]], "to_string (var_opt_union attribute)": [[21, "datasketches.var_opt_union.to_string", false]], "total_weight (count_min_sketch property)": [[5, "datasketches.count_min_sketch.total_weight", false]], "total_weight (frequent_items_sketch property)": [[6, "datasketches.frequent_items_sketch.total_weight", false]], "total_weight (frequent_strings_sketch property)": [[6, "datasketches.frequent_strings_sketch.total_weight", false]], "trim (update_theta_sketch attribute)": [[3, "datasketches.update_theta_sketch.trim", false]], "trim (update_tuple_sketch attribute)": [[4, "datasketches.update_tuple_sketch.trim", false]], "tuple_a_not_b (class in datasketches)": [[4, "datasketches.tuple_a_not_b", false]], "tuple_intersection (class in datasketches)": [[4, "datasketches.tuple_intersection", false]], "tuple_jaccard_similarity (class in datasketches)": [[9, "datasketches.tuple_jaccard_similarity", false]], "tuple_sketch (class in datasketches)": [[4, "datasketches.tuple_sketch", false]], "tuple_union (class in datasketches)": [[4, "datasketches.tuple_union", false]], "tuplepolicy (class in datasketches)": [[13, "datasketches.TuplePolicy", false]], "update (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.update", false]], "update (cpc_sketch attribute)": [[0, "datasketches.cpc_sketch.update", false]], "update (cpc_union attribute)": [[0, "datasketches.cpc_union.update", false]], "update (density_sketch attribute)": [[22, "datasketches.density_sketch.update", false]], "update (ebpps_sketch attribute)": [[19, "datasketches.ebpps_sketch.update", false]], "update (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.update", false]], "update (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.update", false]], "update (hll_sketch attribute)": [[1, "datasketches.hll_sketch.update", false]], "update (hll_union attribute)": [[1, "datasketches.hll_union.update", false]], "update (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.update", false]], "update (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.update", false]], "update (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.update", false]], "update (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.update", false]], "update (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.update", false]], "update (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.update", false]], "update (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.update", false]], "update (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.update", false]], "update (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.update", false]], "update (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.update", false]], "update (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.update", false]], "update (theta_intersection attribute)": [[3, "datasketches.theta_intersection.update", false]], "update (theta_union attribute)": [[3, "datasketches.theta_union.update", false]], "update (tuple_intersection attribute)": [[4, "datasketches.tuple_intersection.update", false]], "update (tuple_union attribute)": [[4, "datasketches.tuple_union.update", false]], "update (update_theta_sketch attribute)": [[3, "datasketches.update_theta_sketch.update", false]], "update (update_tuple_sketch attribute)": [[4, "datasketches.update_tuple_sketch.update", false]], "update (var_opt_sketch attribute)": [[21, "datasketches.var_opt_sketch.update", false]], "update (var_opt_union attribute)": [[21, "datasketches.var_opt_union.update", false]], "update_summary() (tuplepolicy method)": [[13, "datasketches.TuplePolicy.update_summary", false]], "update_theta_sketch (class in datasketches)": [[3, "datasketches.update_theta_sketch", false]], "update_tuple_sketch (class in datasketches)": [[4, "datasketches.update_tuple_sketch", false]], "var_opt_sketch (class in datasketches)": [[21, "datasketches.var_opt_sketch", false]], "var_opt_union (class in datasketches)": [[21, "datasketches.var_opt_union", false]]}, "objects": {"_datasketches": [[5, 0, 1, "datasketches.count_min_sketch", "count_min_sketch"], [0, 0, 1, "datasketches.cpc_sketch", "cpc_sketch"], [0, 0, 1, "datasketches.cpc_union", "cpc_union"], [1, 0, 1, "datasketches.hll_sketch", "hll_sketch"], [1, 0, 1, "datasketches.hll_union", "hll_union"], [1, 0, 1, "datasketches.tgt_hll_type", "tgt_hll_type"]], "_datasketches.count_min_sketch": [[5, 1, 1, "datasketches.count_min_sketch.deserialize", "deserialize"], [5, 2, 1, "datasketches.count_min_sketch.get_estimate", "get_estimate"], [5, 2, 1, "datasketches.count_min_sketch.get_lower_bound", "get_lower_bound"], [5, 2, 1, "datasketches.count_min_sketch.get_relative_error", "get_relative_error"], [5, 2, 1, "datasketches.count_min_sketch.get_serialized_size_bytes", "get_serialized_size_bytes"], [5, 2, 1, "datasketches.count_min_sketch.get_upper_bound", "get_upper_bound"], [5, 2, 1, "datasketches.count_min_sketch.is_empty", "is_empty"], [5, 2, 1, "datasketches.count_min_sketch.merge", "merge"], [5, 3, 1, "datasketches.count_min_sketch.num_buckets", "num_buckets"], [5, 3, 1, "datasketches.count_min_sketch.num_hashes", "num_hashes"], [5, 3, 1, "datasketches.count_min_sketch.seed", "seed"], [5, 2, 1, "datasketches.count_min_sketch.serialize", "serialize"], [5, 1, 1, "datasketches.count_min_sketch.suggest_num_buckets", "suggest_num_buckets"], [5, 1, 1, "datasketches.count_min_sketch.suggest_num_hashes", "suggest_num_hashes"], [5, 2, 1, "datasketches.count_min_sketch.to_string", "to_string"], [5, 3, 1, "datasketches.count_min_sketch.total_weight", "total_weight"], [5, 2, 1, "datasketches.count_min_sketch.update", "update"]], "_datasketches.cpc_sketch": [[0, 1, 1, "datasketches.cpc_sketch.__init__", "__init__"], [0, 1, 1, "datasketches.cpc_sketch.deserialize", "deserialize"], [0, 2, 1, "datasketches.cpc_sketch.get_estimate", "get_estimate"], [0, 2, 1, "datasketches.cpc_sketch.get_lower_bound", "get_lower_bound"], [0, 2, 1, "datasketches.cpc_sketch.get_upper_bound", "get_upper_bound"], [0, 2, 1, "datasketches.cpc_sketch.is_empty", "is_empty"], [0, 3, 1, "datasketches.cpc_sketch.lg_k", "lg_k"], [0, 2, 1, "datasketches.cpc_sketch.serialize", "serialize"], [0, 2, 1, "datasketches.cpc_sketch.to_string", "to_string"], [0, 2, 1, "datasketches.cpc_sketch.update", "update"]], "_datasketches.cpc_union": [[0, 1, 1, "datasketches.cpc_union.__init__", "__init__"], [0, 2, 1, "datasketches.cpc_union.get_result", "get_result"], [0, 2, 1, "datasketches.cpc_union.update", "update"]], "_datasketches.hll_sketch": [[1, 1, 1, "datasketches.hll_sketch.__init__", "__init__"], [1, 1, 1, "datasketches.hll_sketch.deserialize", "deserialize"], [1, 2, 1, "datasketches.hll_sketch.get_compact_serialization_bytes", "get_compact_serialization_bytes"], [1, 2, 1, "datasketches.hll_sketch.get_estimate", "get_estimate"], [1, 2, 1, "datasketches.hll_sketch.get_lower_bound", "get_lower_bound"], [1, 1, 1, "datasketches.hll_sketch.get_max_updatable_serialization_bytes", "get_max_updatable_serialization_bytes"], [1, 1, 1, "datasketches.hll_sketch.get_rel_err", "get_rel_err"], [1, 2, 1, "datasketches.hll_sketch.get_updatable_serialization_bytes", "get_updatable_serialization_bytes"], [1, 2, 1, "datasketches.hll_sketch.get_upper_bound", "get_upper_bound"], [1, 2, 1, "datasketches.hll_sketch.is_compact", "is_compact"], [1, 2, 1, "datasketches.hll_sketch.is_empty", "is_empty"], [1, 3, 1, "datasketches.hll_sketch.lg_config_k", "lg_config_k"], [1, 2, 1, "datasketches.hll_sketch.reset", "reset"], [1, 2, 1, "datasketches.hll_sketch.serialize_compact", "serialize_compact"], [1, 2, 1, "datasketches.hll_sketch.serialize_updatable", "serialize_updatable"], [1, 3, 1, "datasketches.hll_sketch.tgt_type", "tgt_type"], [1, 2, 1, "datasketches.hll_sketch.to_string", "to_string"], [1, 2, 1, "datasketches.hll_sketch.update", "update"]], "_datasketches.hll_union": [[1, 1, 1, "datasketches.hll_union.__init__", "__init__"], [1, 2, 1, "datasketches.hll_union.get_estimate", "get_estimate"], [1, 2, 1, "datasketches.hll_union.get_lower_bound", "get_lower_bound"], [1, 1, 1, "datasketches.hll_union.get_rel_err", "get_rel_err"], [1, 2, 1, "datasketches.hll_union.get_result", "get_result"], [1, 2, 1, "datasketches.hll_union.get_upper_bound", "get_upper_bound"], [1, 2, 1, "datasketches.hll_union.is_empty", "is_empty"], [1, 3, 1, "datasketches.hll_union.lg_config_k", "lg_config_k"], [1, 2, 1, "datasketches.hll_union.reset", "reset"], [1, 2, 1, "datasketches.hll_union.update", "update"]], "_datasketches.tgt_hll_type": [[1, 2, 1, "datasketches.tgt_hll_type.HLL_4", "HLL_4"], [1, 2, 1, "datasketches.tgt_hll_type.HLL_6", "HLL_6"], [1, 2, 1, "datasketches.tgt_hll_type.HLL_8", "HLL_8"]], "datasketches": [[13, 0, 1, "", "AccumulatorPolicy"], [10, 0, 1, "", "GaussianKernel"], [10, 0, 1, "", "KernelFunction"], [13, 0, 1, "", "MaxIntPolicy"], [13, 0, 1, "", "MinIntPolicy"], [12, 0, 1, "", "PyDoublesSerDe"], [12, 0, 1, "", "PyFloatsSerDe"], [12, 0, 1, "", "PyIntsSerDe"], [12, 0, 1, "", "PyLongsSerDe"], [12, 0, 1, "", "PyObjectSerDe"], [12, 0, 1, "", "PyStringsSerDe"], [13, 0, 1, "", "TuplePolicy"], [3, 0, 1, "", "compact_theta_sketch"], [4, 0, 1, "", "compact_tuple_sketch"], [22, 0, 1, "", "density_sketch"], [19, 0, 1, "", "ebpps_sketch"], [6, 0, 1, "", "frequent_items_error_type"], [6, 0, 1, "", "frequent_items_sketch"], [6, 0, 1, "", "frequent_strings_sketch"], [16, 0, 1, "", "kll_doubles_sketch"], [16, 0, 1, "", "kll_floats_sketch"], [16, 0, 1, "", "kll_ints_sketch"], [16, 0, 1, "", "kll_items_sketch"], [11, 4, 1, "", "ks_test"], [17, 0, 1, "", "quantiles_doubles_sketch"], [17, 0, 1, "", "quantiles_floats_sketch"], [17, 0, 1, "", "quantiles_ints_sketch"], [17, 0, 1, "", "quantiles_items_sketch"], [18, 0, 1, "", "req_floats_sketch"], [18, 0, 1, "", "req_ints_sketch"], [18, 0, 1, "", "req_items_sketch"], [3, 0, 1, "", "theta_a_not_b"], [3, 0, 1, "", "theta_intersection"], [9, 0, 1, "", "theta_jaccard_similarity"], [3, 0, 1, "", "theta_sketch"], [3, 0, 1, "", "theta_union"], [4, 0, 1, "", "tuple_a_not_b"], [4, 0, 1, "", "tuple_intersection"], [9, 0, 1, "", "tuple_jaccard_similarity"], [4, 0, 1, "", "tuple_sketch"], [4, 0, 1, "", "tuple_union"], [3, 0, 1, "", "update_theta_sketch"], [4, 0, 1, "", "update_tuple_sketch"], [21, 0, 1, "", "var_opt_sketch"], [21, 0, 1, "", "var_opt_union"]], "datasketches.KernelFunction": [[10, 1, 1, "", "__call__"]], "datasketches.PyObjectSerDe": [[12, 1, 1, "", "from_bytes"], [12, 1, 1, "", "get_size"], [12, 1, 1, "", "to_bytes"]], "datasketches.TuplePolicy": [[13, 1, 1, "", "__call__"], [13, 1, 1, "", "create_summary"], [13, 1, 1, "", "update_summary"]], "datasketches.compact_theta_sketch": [[3, 1, 1, "", "__init__"], [3, 1, 1, "", "deserialize"], [3, 2, 1, "", "serialize"]], "datasketches.compact_tuple_sketch": [[4, 1, 1, "", "__init__"], [4, 1, 1, "", "deserialize"], [4, 2, 1, "", "serialize"]], "datasketches.density_sketch": [[22, 1, 1, "", "__init__"], [22, 1, 1, "", "deserialize"], [22, 3, 1, "", "dim"], [22, 2, 1, "", "get_estimate"], [22, 2, 1, "", "is_empty"], [22, 2, 1, "", "is_estimation_mode"], [22, 3, 1, "", "k"], [22, 2, 1, "", "merge"], [22, 3, 1, "", "n"], [22, 3, 1, "", "num_retained"], [22, 2, 1, "", "serialize"], [22, 2, 1, "", "to_string"], [22, 2, 1, "", "update"]], "datasketches.ebpps_sketch": [[19, 1, 1, "", "__init__"], [19, 3, 1, "", "c"], [19, 1, 1, "", "deserialize"], [19, 2, 1, "", "get_serialized_size_bytes"], [19, 2, 1, "", "is_empty"], [19, 3, 1, "", "k"], [19, 2, 1, "", "merge"], [19, 3, 1, "", "n"], [19, 2, 1, "", "serialize"], [19, 2, 1, "", "to_string"], [19, 2, 1, "", "update"]], "datasketches.frequent_items_error_type": [[6, 2, 1, "", "NO_FALSE_NEGATIVES"], [6, 2, 1, "", "NO_FALSE_POSITIVES"]], "datasketches.frequent_items_sketch": [[6, 1, 1, "", "__init__"], [6, 1, 1, "", "deserialize"], [6, 3, 1, "", "epsilon"], [6, 1, 1, "", "get_apriori_error"], [6, 1, 1, "", "get_epsilon_for_lg_size"], [6, 2, 1, "", "get_estimate"], [6, 2, 1, "", "get_frequent_items"], [6, 2, 1, "", "get_lower_bound"], [6, 2, 1, "", "get_serialized_size_bytes"], [6, 2, 1, "", "get_upper_bound"], [6, 2, 1, "", "is_empty"], [6, 2, 1, "", "merge"], [6, 3, 1, "", "num_active_items"], [6, 2, 1, "", "serialize"], [6, 2, 1, "", "to_string"], [6, 3, 1, "", "total_weight"], [6, 2, 1, "", "update"]], "datasketches.frequent_strings_sketch": [[6, 1, 1, "", "__init__"], [6, 1, 1, "", "deserialize"], [6, 3, 1, "", "epsilon"], [6, 1, 1, "", "get_apriori_error"], [6, 1, 1, "", "get_epsilon_for_lg_size"], [6, 2, 1, "", "get_estimate"], [6, 2, 1, "", "get_frequent_items"], [6, 2, 1, "", "get_lower_bound"], [6, 2, 1, "", "get_serialized_size_bytes"], [6, 2, 1, "", "get_upper_bound"], [6, 2, 1, "", "is_empty"], [6, 2, 1, "", "merge"], [6, 3, 1, "", "num_active_items"], [6, 2, 1, "", "serialize"], [6, 2, 1, "", "to_string"], [6, 3, 1, "", "total_weight"], [6, 2, 1, "", "update"]], "datasketches.kll_doubles_sketch": [[16, 1, 1, "", "__init__"], [16, 1, 1, "", "deserialize"], [16, 2, 1, "", "get_cdf"], [16, 2, 1, "", "get_max_value"], [16, 2, 1, "", "get_min_value"], [16, 1, 1, "", "get_normalized_rank_error"], [16, 2, 1, "", "get_pmf"], [16, 2, 1, "", "get_quantile"], [16, 2, 1, "", "get_quantiles"], [16, 2, 1, "", "get_rank"], [16, 2, 1, "", "is_empty"], [16, 2, 1, "", "is_estimation_mode"], [16, 3, 1, "", "k"], [16, 2, 1, "", "merge"], [16, 3, 1, "", "n"], [16, 2, 1, "", "normalized_rank_error"], [16, 3, 1, "", "num_retained"], [16, 2, 1, "", "serialize"], [16, 2, 1, "", "to_string"], [16, 2, 1, "", "update"]], "datasketches.kll_floats_sketch": [[16, 1, 1, "", "__init__"], [16, 1, 1, "", "deserialize"], [16, 2, 1, "", "get_cdf"], [16, 2, 1, "", "get_max_value"], [16, 2, 1, "", "get_min_value"], [16, 1, 1, "", "get_normalized_rank_error"], [16, 2, 1, "", "get_pmf"], [16, 2, 1, "", "get_quantile"], [16, 2, 1, "", "get_quantiles"], [16, 2, 1, "", "get_rank"], [16, 2, 1, "", "is_empty"], [16, 2, 1, "", "is_estimation_mode"], [16, 3, 1, "", "k"], [16, 2, 1, "", "merge"], [16, 3, 1, "", "n"], [16, 2, 1, "", "normalized_rank_error"], [16, 3, 1, "", "num_retained"], [16, 2, 1, "", "serialize"], [16, 2, 1, "", "to_string"], [16, 2, 1, "", "update"]], "datasketches.kll_ints_sketch": [[16, 1, 1, "", "__init__"], [16, 1, 1, "", "deserialize"], [16, 2, 1, "", "get_cdf"], [16, 2, 1, "", "get_max_value"], [16, 2, 1, "", "get_min_value"], [16, 1, 1, "", "get_normalized_rank_error"], [16, 2, 1, "", "get_pmf"], [16, 2, 1, "", "get_quantile"], [16, 2, 1, "", "get_quantiles"], [16, 2, 1, "", "get_rank"], [16, 2, 1, "", "is_empty"], [16, 2, 1, "", "is_estimation_mode"], [16, 3, 1, "", "k"], [16, 2, 1, "", "merge"], [16, 3, 1, "", "n"], [16, 2, 1, "", "normalized_rank_error"], [16, 3, 1, "", "num_retained"], [16, 2, 1, "", "serialize"], [16, 2, 1, "", "to_string"], [16, 2, 1, "", "update"]], "datasketches.kll_items_sketch": [[16, 1, 1, "", "__init__"], [16, 1, 1, "", "deserialize"], [16, 2, 1, "", "get_cdf"], [16, 2, 1, "", "get_max_value"], [16, 2, 1, "", "get_min_value"], [16, 1, 1, "", "get_normalized_rank_error"], [16, 2, 1, "", "get_pmf"], [16, 2, 1, "", "get_quantile"], [16, 2, 1, "", "get_quantiles"], [16, 2, 1, "", "get_rank"], [16, 2, 1, "", "is_empty"], [16, 2, 1, "", "is_estimation_mode"], [16, 3, 1, "", "k"], [16, 2, 1, "", "merge"], [16, 3, 1, "", "n"], [16, 2, 1, "", "normalized_rank_error"], [16, 3, 1, "", "num_retained"], [16, 2, 1, "", "serialize"], [16, 2, 1, "", "to_string"], [16, 2, 1, "", "update"]], "datasketches.quantiles_doubles_sketch": [[17, 1, 1, "", "__init__"], [17, 1, 1, "", "deserialize"], [17, 2, 1, "", "get_cdf"], [17, 2, 1, "", "get_max_value"], [17, 2, 1, "", "get_min_value"], [17, 1, 1, "", "get_normalized_rank_error"], [17, 2, 1, "", "get_pmf"], [17, 2, 1, "", "get_quantile"], [17, 2, 1, "", "get_quantiles"], [17, 2, 1, "", "get_rank"], [17, 2, 1, "", "is_empty"], [17, 2, 1, "", "is_estimation_mode"], [17, 3, 1, "", "k"], [17, 2, 1, "", "merge"], [17, 3, 1, "", "n"], [17, 2, 1, "", "normalized_rank_error"], [17, 3, 1, "", "num_retained"], [17, 2, 1, "", "serialize"], [17, 2, 1, "", "to_string"], [17, 2, 1, "", "update"]], "datasketches.quantiles_floats_sketch": [[17, 1, 1, "", "__init__"], [17, 1, 1, "", "deserialize"], [17, 2, 1, "", "get_cdf"], [17, 2, 1, "", "get_max_value"], [17, 2, 1, "", "get_min_value"], [17, 1, 1, "", "get_normalized_rank_error"], [17, 2, 1, "", "get_pmf"], [17, 2, 1, "", "get_quantile"], [17, 2, 1, "", "get_quantiles"], [17, 2, 1, "", "get_rank"], [17, 2, 1, "", "is_empty"], [17, 2, 1, "", "is_estimation_mode"], [17, 3, 1, "", "k"], [17, 2, 1, "", "merge"], [17, 3, 1, "", "n"], [17, 2, 1, "", "normalized_rank_error"], [17, 3, 1, "", "num_retained"], [17, 2, 1, "", "serialize"], [17, 2, 1, "", "to_string"], [17, 2, 1, "", "update"]], "datasketches.quantiles_ints_sketch": [[17, 1, 1, "", "__init__"], [17, 1, 1, "", "deserialize"], [17, 2, 1, "", "get_cdf"], [17, 2, 1, "", "get_max_value"], [17, 2, 1, "", "get_min_value"], [17, 1, 1, "", "get_normalized_rank_error"], [17, 2, 1, "", "get_pmf"], [17, 2, 1, "", "get_quantile"], [17, 2, 1, "", "get_quantiles"], [17, 2, 1, "", "get_rank"], [17, 2, 1, "", "is_empty"], [17, 2, 1, "", "is_estimation_mode"], [17, 3, 1, "", "k"], [17, 2, 1, "", "merge"], [17, 3, 1, "", "n"], [17, 2, 1, "", "normalized_rank_error"], [17, 3, 1, "", "num_retained"], [17, 2, 1, "", "serialize"], [17, 2, 1, "", "to_string"], [17, 2, 1, "", "update"]], "datasketches.quantiles_items_sketch": [[17, 1, 1, "", "__init__"], [17, 1, 1, "", "deserialize"], [17, 2, 1, "", "get_cdf"], [17, 2, 1, "", "get_max_value"], [17, 2, 1, "", "get_min_value"], [17, 1, 1, "", "get_normalized_rank_error"], [17, 2, 1, "", "get_pmf"], [17, 2, 1, "", "get_quantile"], [17, 2, 1, "", "get_quantiles"], [17, 2, 1, "", "get_rank"], [17, 2, 1, "", "is_empty"], [17, 2, 1, "", "is_estimation_mode"], [17, 3, 1, "", "k"], [17, 2, 1, "", "merge"], [17, 3, 1, "", "n"], [17, 2, 1, "", "normalized_rank_error"], [17, 3, 1, "", "num_retained"], [17, 2, 1, "", "serialize"], [17, 2, 1, "", "to_string"], [17, 2, 1, "", "update"]], "datasketches.req_floats_sketch": [[18, 1, 1, "", "__init__"], [18, 1, 1, "", "deserialize"], [18, 1, 1, "", "get_RSE"], [18, 2, 1, "", "get_cdf"], [18, 2, 1, "", "get_max_value"], [18, 2, 1, "", "get_min_value"], [18, 2, 1, "", "get_pmf"], [18, 2, 1, "", "get_quantile"], [18, 2, 1, "", "get_quantiles"], [18, 2, 1, "", "get_rank"], [18, 2, 1, "", "get_rank_lower_bound"], [18, 2, 1, "", "get_rank_upper_bound"], [18, 2, 1, "", "is_empty"], [18, 2, 1, "", "is_estimation_mode"], [18, 2, 1, "", "is_hra"], [18, 3, 1, "", "k"], [18, 2, 1, "", "merge"], [18, 3, 1, "", "n"], [18, 3, 1, "", "num_retained"], [18, 2, 1, "", "serialize"], [18, 2, 1, "", "to_string"], [18, 2, 1, "", "update"]], "datasketches.req_ints_sketch": [[18, 1, 1, "", "__init__"], [18, 1, 1, "", "deserialize"], [18, 1, 1, "", "get_RSE"], [18, 2, 1, "", "get_cdf"], [18, 2, 1, "", "get_max_value"], [18, 2, 1, "", "get_min_value"], [18, 2, 1, "", "get_pmf"], [18, 2, 1, "", "get_quantile"], [18, 2, 1, "", "get_quantiles"], [18, 2, 1, "", "get_rank"], [18, 2, 1, "", "get_rank_lower_bound"], [18, 2, 1, "", "get_rank_upper_bound"], [18, 2, 1, "", "is_empty"], [18, 2, 1, "", "is_estimation_mode"], [18, 2, 1, "", "is_hra"], [18, 3, 1, "", "k"], [18, 2, 1, "", "merge"], [18, 3, 1, "", "n"], [18, 3, 1, "", "num_retained"], [18, 2, 1, "", "serialize"], [18, 2, 1, "", "to_string"], [18, 2, 1, "", "update"]], "datasketches.req_items_sketch": [[18, 1, 1, "", "__init__"], [18, 1, 1, "", "deserialize"], [18, 1, 1, "", "get_RSE"], [18, 2, 1, "", "get_cdf"], [18, 2, 1, "", "get_max_value"], [18, 2, 1, "", "get_min_value"], [18, 2, 1, "", "get_pmf"], [18, 2, 1, "", "get_quantile"], [18, 2, 1, "", "get_quantiles"], [18, 2, 1, "", "get_rank"], [18, 2, 1, "", "get_rank_lower_bound"], [18, 2, 1, "", "get_rank_upper_bound"], [18, 2, 1, "", "is_empty"], [18, 2, 1, "", "is_estimation_mode"], [18, 2, 1, "", "is_hra"], [18, 3, 1, "", "k"], [18, 2, 1, "", "merge"], [18, 3, 1, "", "n"], [18, 3, 1, "", "num_retained"], [18, 2, 1, "", "serialize"], [18, 2, 1, "", "to_string"], [18, 2, 1, "", "update"]], "datasketches.theta_a_not_b": [[3, 1, 1, "", "__init__"], [3, 2, 1, "", "compute"]], "datasketches.theta_intersection": [[3, 1, 1, "", "__init__"], [3, 2, 1, "", "get_result"], [3, 2, 1, "", "has_result"], [3, 2, 1, "", "update"]], "datasketches.theta_jaccard_similarity": [[9, 1, 1, "", "dissimilarity_test"], [9, 1, 1, "", "exactly_equal"], [9, 1, 1, "", "jaccard"], [9, 1, 1, "", "similarity_test"]], "datasketches.theta_sketch": [[3, 2, 1, "", "get_estimate"], [3, 2, 1, "", "get_lower_bound"], [3, 2, 1, "", "get_seed_hash"], [3, 2, 1, "", "get_upper_bound"], [3, 2, 1, "", "is_empty"], [3, 2, 1, "", "is_estimation_mode"], [3, 2, 1, "", "is_ordered"], [3, 3, 1, "", "num_retained"], [3, 3, 1, "", "theta"], [3, 3, 1, "", "theta64"], [3, 2, 1, "", "to_string"]], "datasketches.theta_union": [[3, 1, 1, "", "__init__"], [3, 2, 1, "", "get_result"], [3, 2, 1, "", "update"]], "datasketches.tuple_a_not_b": [[4, 1, 1, "", "__init__"], [4, 2, 1, "", "compute"]], "datasketches.tuple_intersection": [[4, 1, 1, "", "__init__"], [4, 2, 1, "", "get_result"], [4, 2, 1, "", "has_result"], [4, 2, 1, "", "update"]], "datasketches.tuple_jaccard_similarity": [[9, 1, 1, "", "dissimilarity_test"], [9, 1, 1, "", "exactly_equal"], [9, 1, 1, "", "jaccard"], [9, 1, 1, "", "similarity_test"]], "datasketches.tuple_sketch": [[4, 2, 1, "", "DEFAULT_SEED"], [4, 2, 1, "", "get_estimate"], [4, 2, 1, "", "get_lower_bound"], [4, 2, 1, "", "get_seed_hash"], [4, 2, 1, "", "get_upper_bound"], [4, 2, 1, "", "is_empty"], [4, 2, 1, "", "is_estimation_mode"], [4, 2, 1, "", "is_ordered"], [4, 3, 1, "", "num_retained"], [4, 3, 1, "", "theta"], [4, 3, 1, "", "theta64"], [4, 2, 1, "", "to_string"]], "datasketches.tuple_union": [[4, 1, 1, "", "__init__"], [4, 2, 1, "", "get_result"], [4, 2, 1, "", "reset"], [4, 2, 1, "", "update"]], "datasketches.update_theta_sketch": [[3, 1, 1, "", "__init__"], [3, 2, 1, "", "compact"], [3, 2, 1, "", "reset"], [3, 2, 1, "", "trim"], [3, 2, 1, "", "update"]], "datasketches.update_tuple_sketch": [[4, 1, 1, "", "__init__"], [4, 2, 1, "", "compact"], [4, 2, 1, "", "reset"], [4, 2, 1, "", "trim"], [4, 2, 1, "", "update"]], "datasketches.var_opt_sketch": [[21, 1, 1, "", "__init__"], [21, 1, 1, "", "deserialize"], [21, 2, 1, "", "estimate_subset_sum"], [21, 2, 1, "", "get_serialized_size_bytes"], [21, 2, 1, "", "is_empty"], [21, 3, 1, "", "k"], [21, 3, 1, "", "n"], [21, 3, 1, "", "num_samples"], [21, 2, 1, "", "serialize"], [21, 2, 1, "", "to_string"], [21, 2, 1, "", "update"]], "datasketches.var_opt_union": [[21, 1, 1, "", "__init__"], [21, 1, 1, "", "deserialize"], [21, 2, 1, "", "get_result"], [21, 2, 1, "", "get_serialized_size_bytes"], [21, 2, 1, "", "reset"], [21, 2, 1, "", "serialize"], [21, 2, 1, "", "to_string"], [21, 2, 1, "", "update"]]}, "objnames": {"0": ["py", "class", "Python class"], "1": ["py", "method", "Python method"], "2": ["py", "attribute", "Python attribute"], "3": ["py", "property", "Python property"], "4": ["py", "function", "Python function"]}, "objtypes": {"0": "py:class", "1": "py:method", "2": "py:attribute", "3": "py:property", "4": "py:function"}, "terms": {"": [1, 6, 19, 20, 21], "0": [3, 4, 5, 6, 10, 16, 17, 18], "01668v2": 18, "05": 5, "1": [0, 1, 3, 4, 5, 6, 10, 16, 17, 18], "10": [1, 17], "100": 17, "1000": 17, "11": 0, "12": [3, 4, 18], "128": 17, "13": 16, "14": 6, "16": 1, "18": 6, "1982": 6, "1985": 2, "1e": 6, "1e9": 6, "2": [0, 1, 3, 4, 6, 17, 18], "20": 17, "200": 16, "2002": 6, "2003": 6, "2004": 18, "2006": 6, "2020": 16, "2021": 17, "2023": 19, "21": 1, "3": [0, 1, 3, 4, 6, 17, 18], "30": 17, "32": [12, 16], "33": 16, "4": [1, 12, 17], "40": 17, "47": 16, "483": 17, "5": [5, 6, 17], "500": 17, "50th": 17, "517": 17, "6": 1, "64": [0, 3, 4, 5, 12, 17], "65": 16, "7": [1, 9, 17], "75": 6, "8": [1, 6, 12], "80": 11, "900": 17, "9001": [0, 3, 4, 9], "93smirnov_test": 11, "95": [5, 17], "95th": 17, "97": 9, "99": [16, 17], "A": [1, 3, 4, 6, 10, 11, 12, 13, 16, 17, 21], "As": [0, 16, 17], "For": [0, 1, 5, 6, 16, 17, 18, 23], "If": [1, 6, 9, 16, 17, 18], "In": [0, 1, 16, 19], "It": [3, 16, 17, 18], "One": 2, "That": 15, "The": [0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 22], "Then": 16, "There": [3, 6], "These": [1, 8, 9, 15, 20, 23], "With": [16, 17, 18], "_": 11, "__call__": [10, 13], "__eq__": 6, "__hash__": 6, "__init__": [0, 1, 3, 4, 6, 16, 17, 18, 19, 21, 22], "__lt__": [16, 17, 18], "_datasketch": [0, 1, 3, 4, 5, 6, 9, 11, 16, 17, 18, 19, 21, 22], "ab": 18, "abbadi": 6, "abil": 18, "about": [1, 15, 16, 17], "abov": [7, 16], "absolut": 8, "abstract": [3, 4, 8, 10, 12, 13], "accept": 23, "account": 11, "accumulatori": 13, "accumulatorpolici": 13, "accuraci": [0, 1, 2, 3, 5, 6, 16, 17, 18], "achiev": 5, "activ": [6, 14], "actual": [9, 17], "ad": 13, "add": 16, "addit": [0, 2, 6, 12], "addition": 16, "advanc": 20, "affect": [16, 17], "after": [18, 20], "against": [0, 9], "agraw": 6, "algorithm": [0, 1, 2, 3, 6, 14, 18], "all": [1, 3, 6, 12, 13, 15, 16, 17, 19, 21], "alloc": 12, "allow": [0, 4, 12, 13, 18], "along": 6, "also": [0, 3, 10, 14, 15, 17], "altern": 15, "although": [1, 19], "alwai": [6, 13, 16, 17, 19, 20], "an": [0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 12, 13, 15, 16, 17, 18, 19, 20, 21, 22], "analog": [16, 17, 18], "analysi": [4, 11, 16, 17, 18], "analyz": 14, "ani": [3, 4, 5, 6, 7, 13, 16, 17], "anoth": [0, 6, 18], "answer": 15, "appl": 0, "appli": [2, 3, 4, 6, 13, 15, 16, 18, 20, 21], "applic": 2, "approach": 15, "approx": [5, 18], "approxim": [0, 1, 3, 4, 5, 6, 10, 15, 16, 17, 18, 22], "ar": [0, 1, 3, 4, 5, 6, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 20, 23], "arbitrari": [4, 6], "arg": [0, 1, 3, 4, 5, 6, 10, 12, 13, 16, 17, 18, 19, 21, 22], "arg0": 3, "arg1": 3, "around": 16, "arrai": [6, 10, 16, 17, 18], "art": 2, "arxiv": 18, "as_pmf": [16, 17], "associ": [4, 6, 16, 17, 18], "assum": [6, 11], "avail": 16, "avoid": 3, "axi": 16, "b": [3, 4, 10, 19], "back": 0, "background": 6, "backward": [6, 15], "bag": 6, "bandwidth": 10, "base": [0, 1, 2, 3, 4, 5, 6, 8, 10, 12, 13, 18, 19, 20, 22], "basi": 10, "basic": [3, 4, 10], "becaus": 16, "been": [7, 16, 17, 18, 21], "befor": [6, 7], "behavior": 1, "being": 20, "below": 16, "best": [16, 17], "better": [1, 2, 3], "between": [1, 3, 4, 6, 8, 9, 16, 17, 18, 22], "beyond": 3, "big": 14, "bin": [0, 16], "binari": [12, 16, 17], "bit": [0, 1, 3, 4, 5, 12, 16, 17], "blob": 22, "bool": [1, 3, 4, 9, 11, 16, 17, 18], "both": [11, 18, 20], "bound": [0, 1, 3, 4, 5, 6, 9, 14, 15, 16, 18, 20, 21], "bracket": 16, "bucket": [1, 5], "build": 22, "byte": [0, 1, 3, 4, 5, 6, 12, 16, 17, 18, 19, 21, 22], "c": [0, 19], "call": [16, 19], "came": 2, "can": [0, 1, 3, 4, 6, 11, 13, 15, 16, 17, 18], "cannot": 16, "capabl": [0, 6, 18], "capac": 6, "cardin": [0, 3], "case": [1, 6, 8, 17, 19], "caus": 6, "cdf": [15, 16, 17, 18], "certain": [7, 8, 10, 16, 19], "choic": 1, "choos": 18, "class": [0, 1, 3, 4, 5, 6, 9, 10, 12, 13, 16, 17, 18, 19, 21, 22], "classic": [15, 17], "close": 7, "cm": 5, "code": [6, 18], "collect": 1, "com": 22, "combin": [8, 13], "come": [11, 17], "commonli": [6, 16], "compact": [1, 3, 4, 16, 18], "compact_theta_sketch": 3, "compact_tuple_sketch": 4, "compactor": 18, "compar": [0, 16, 17, 18], "comparison": [0, 18], "compat": [6, 12, 15, 16, 17], "complic": 4, "compress": [1, 2, 14], "comput": [3, 4, 6, 8, 9, 15, 19, 21, 22], "concept": 2, "concret": 8, "confid": [5, 9, 16, 17], "configur": [0, 1, 5, 16, 17, 18, 19, 21, 22], "consecut": [16, 17, 18], "consid": [9, 17], "consist": 13, "constant": [1, 6, 16, 17, 18], "construct": [1, 18, 21], "consum": [1, 12], "contain": [3, 6, 7], "context": 10, "contrast": [5, 19], "control": [16, 17, 18, 22], "coreset": 22, "cormod": [5, 18], "correspond": [0, 1, 3, 4, 5, 6, 16, 17, 18, 19, 21, 22], "cost": [1, 12], "could": [16, 17, 18], "count": [1, 3, 4, 6, 17, 18], "count_min_sketch": [5, 7], "counter": 6, "countmin": [7, 14], "coupon": 1, "cpc": [1, 2, 14], "cpc_sketch": [0, 2], "cpc_union": 0, "creat": [0, 3, 4, 6, 13, 16, 17, 18, 19, 21, 22], "create_summari": 13, "creation": 19, "criterion": 18, "critic": 12, "cross": [12, 17], "cumul": [15, 16, 17, 18], "current": [1, 3, 4, 5, 6, 7, 11, 15, 19, 21], "custom": [4, 10, 12, 13], "data": [2, 6, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 22], "datasketch": [2, 11], "datum": [0, 1, 3, 4], "debug": 18, "decreas": [15, 18], "decrement": 6, "dedic": [3, 4], "default": [1, 3, 4, 10, 16, 17, 18], "default_se": 4, "defin": [3, 4, 6, 10, 16, 19], "definit": [16, 17, 18], "delta": 5, "demain": 6, "denot": [5, 6], "densiti": [8, 10, 14, 23], "density_sketch": [10, 22, 23], "depend": [5, 16], "deprec": [14, 15], "deriv": [3, 16, 17, 18], "describ": [0, 5, 18], "deseri": [0, 1, 3, 4, 5, 6, 8, 14, 16, 17, 18, 19, 21, 22], "design": [15, 23], "desing": 21, "detail": [18, 20], "determin": [7, 11], "determinist": 6, "develop": [0, 14], "deviat": [0, 1, 3, 4, 18], "differ": [0, 1, 2, 3, 6, 12, 13, 18, 20], "dim": 22, "dimac": 5, "dimens": [0, 22], "dimension": 16, "discov": 6, "discrep": 22, "discuss": 18, "disjoint": [16, 17, 18], "dissimilar": 9, "dissimilarity_test": 9, "distanc": 22, "distinct": [0, 1, 3, 4, 6], "distribut": [1, 11, 15, 16, 17, 18], "divid": [16, 17, 18], "do": 6, "document": 16, "doe": [0, 5, 6, 7, 16, 18, 20], "domain": 16, "doubl": [16, 17, 18, 19], "dtype": [16, 17, 18], "dure": 1, "e": 15, "e2": 11, "each": [1, 2, 4, 6, 11, 12, 13, 15, 16, 17, 18, 20], "earliest": 2, "easili": [3, 4], "ebpp": [14, 20], "ebpps_sketch": [19, 20], "edg": [16, 17], "edo": [18, 22], "edoliberti": 22, "edu": 5, "effect": [3, 4], "effici": [0, 3, 6, 14], "either": [6, 15, 16, 17, 18], "element": [2, 6], "els": 18, "empir": [0, 16, 17, 18], "emploi": 6, "empti": [0, 1, 3, 4, 6, 16, 17, 18, 19, 21, 22], "en": 11, "enabl": [16, 17], "encod": 12, "end": 15, "endian": 12, "enough": 1, "ensur": [6, 19, 20], "entir": [7, 15, 20], "entri": [1, 3, 4, 6], "entropi": 0, "ep": 16, "epsilon": [6, 16], "equal": [11, 15, 16, 17, 18, 19], "equival": [9, 16, 17, 19, 21], "error": [1, 3, 5, 6, 8, 11, 14, 15, 16, 17, 19, 21, 22], "estim": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 16, 17, 18, 21, 22, 23], "estimate_subset_sum": 21, "estimated_total_stream_weight": 6, "estimated_total_weight": 6, "evalu": 10, "even": [0, 20], "everi": [3, 4, 5, 6], "exact": [6, 14, 20], "exactli": [19, 20], "exactly_equ": 9, "exampl": [4, 5, 6, 8, 10, 12, 17], "exce": [6, 18, 19], "except": [1, 16, 17, 18], "excess": [3, 4], "exclud": 6, "exclus": [16, 17, 18], "exist": [3, 4, 13], "expect": [9, 19], "expens": 6, "express": 18, "extend": [12, 13], "extens": [4, 18], "extern": 6, "extrem": [0, 6], "f688c8161a25582457b0a09deb4630a81406293b": 22, "f_x": 5, "factor": 18, "failur": 5, "fals": [0, 1, 3, 4, 5, 6, 9, 11, 16, 17, 18, 19, 21, 22], "famili": [1, 8, 11], "far": [6, 15, 16, 17, 18, 19], "fast": 0, "favor": [15, 17], "fed": 1, "feed": [19, 21], "few": 4, "fewer": [6, 19, 21], "field": 6, "find": 6, "fit": [16, 17], "fix": 4, "flag": [16, 17], "flajolet": [1, 2], "flavor": [1, 6], "float": [0, 1, 3, 4, 5, 6, 9, 10, 11, 12, 15, 16, 17, 18, 19], "float32": [16, 17, 18], "float64": [16, 17], "fm85": 0, "follow": [6, 16, 18, 22], "footprint": 2, "form": [3, 4, 6, 11], "format": 12, "found": 6, "fraction": [3, 4, 16, 17, 19], "framework": 3, "frequenc": [5, 6, 17], "frequent": [5, 7, 14], "frequent_items_error_typ": 6, "frequent_items_sketch": [6, 7], "frequent_strings_sketch": [6, 7], "from": [2, 3, 4, 6, 7, 10, 11, 12, 16, 17, 18, 19, 20, 21, 22], "from_byt": 12, "full": [1, 5], "funciton": 10, "function": [0, 1, 3, 4, 5, 6, 8, 11, 14, 15, 16, 17, 18], "futur": 0, "g": 15, "gaussian": 10, "gaussiankernel": 10, "gde": 22, "gener": [6, 7, 10, 15, 16, 17, 18], "get": [16, 17], "get_apriori_error": 6, "get_cdf": [16, 17, 18], "get_compact_serialization_byt": 1, "get_epsilon_for_lg_s": 6, "get_estim": [0, 1, 3, 4, 5, 6, 22], "get_frequent_item": 6, "get_lower_bound": [0, 1, 3, 4, 5, 6], "get_max_updatable_serialization_byt": 1, "get_max_valu": [16, 17, 18], "get_min_valu": [16, 17, 18], "get_n": 17, "get_normalized_rank_error": [16, 17, 18], "get_pmf": [16, 17, 18], "get_quantil": [16, 17, 18], "get_rank": [16, 17, 18], "get_rank_lower_bound": 18, "get_rank_upper_bound": 18, "get_rel_err": 1, "get_relative_error": 5, "get_result": [0, 1, 3, 4, 19, 21], "get_rs": 18, "get_seed_hash": [3, 4], "get_serialized_size_byt": [5, 6, 19, 21], "get_siz": 12, "get_updatable_serialization_byt": 1, "get_upper_bound": [0, 1, 3, 4, 5, 6], "github": 22, "given": [0, 1, 3, 4, 5, 6, 10, 11, 12, 15, 16, 17, 18, 19, 21, 22], "global": [6, 15], "good": [2, 3], "graham": [5, 18], "gri": 6, "grow": 6, "guarante": [5, 6, 16, 17, 18], "ha": [1, 3, 4, 5, 7, 15, 16, 17, 18], "haa": 19, "handl": [3, 7, 19], "has_result": [3, 4], "hash": [0, 3, 4, 5, 6], "hat": 5, "have": [1, 6, 11, 16, 17, 18, 21], "heavi": [5, 6, 7, 14], "heaviest": 7, "help": [9, 18], "hentschel": 19, "here": 18, "hi": 0, "high": [0, 1, 15, 18], "higher": [1, 17], "highest": 1, "highli": 14, "hip": 0, "histogram": [15, 17], "histor": [0, 15], "hitter": [5, 6, 7, 14], "hll": [0, 2, 14], "hll_4": 1, "hll_6": 1, "hll_8": 1, "hll_sketch": [1, 2], "hll_union": 1, "hold": [1, 6], "how": [4, 7, 8, 13, 18], "howev": [6, 16, 18], "http": [5, 11, 18, 22], "hyper": 2, "hyperloglog": [0, 2, 3, 14], "hypothesi": 11, "hypothet": [16, 17, 18], "i": [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22], "icon": 0, "identifi": 7, "imag": 5, "implement": [0, 1, 4, 6, 7, 10, 12, 13, 16, 17, 18, 22], "improv": [1, 21], "includ": [15, 16, 17, 18, 19, 20, 21], "inclus": [1, 16, 17, 18, 20], "incom": [3, 4, 6], "increas": [16, 17, 18], "increment": 6, "independ": 16, "index": [9, 14, 16, 17], "indic": [1, 10], "inform": 19, "inherit": 10, "init_number_of_sect": 18, "initi": [1, 3, 4, 6, 18], "input": [0, 1, 3, 4, 6, 10, 11, 16, 17, 18, 20, 22, 23], "insert": [3, 5, 6], "inspir": 22, "instanc": [6, 16, 17, 18, 19, 21, 22], "instead": [17, 18], "insuffici": 11, "int": [0, 1, 3, 4, 5, 6, 9, 12, 16, 17, 18, 19, 21, 22], "int32": [16, 17, 18], "integ": [0, 5, 6, 12, 13, 15], "integr": [1, 3, 4], "intern": 6, "internet": 6, "interpret": 16, "intersect": [2, 3, 4, 13], "interv": [16, 17, 18], "introduc": 6, "invers": [0, 16], "involv": 7, "is_compact": 1, "is_empti": [0, 1, 3, 4, 5, 6, 16, 17, 18, 19, 21, 22], "is_estimation_mod": [3, 4, 16, 17, 18, 22], "is_hra": 18, "is_ord": [3, 4], "item": [1, 3, 4, 5, 7, 12, 14, 15, 16, 17, 18, 19, 20, 21, 22], "iter": 19, "its": [0, 12, 16, 17, 19], "itself": 6, "j": 19, "j_": 9, "jaccard": [3, 4, 8, 14], "java": [16, 17], "just": 16, "justin": 18, "k": [0, 1, 2, 3, 4, 6, 7, 16, 17, 18, 19, 21, 22], "kappa": 0, "karnin": [18, 22], "karnin19a": 22, "karp": 6, "keep": [1, 4, 19], "kei": [2, 4], "kept": 13, "kernel": [8, 14, 22, 23], "kernel_funct": 8, "kernel_sketch": 8, "kernelfunct": [10, 22], "kevin": 0, "kll": [14, 15, 17], "kll_doubles_sketch": [11, 16], "kll_floats_sketch": [11, 16], "kll_ints_sketch": [11, 16], "kll_items_sketch": [11, 16], "known": [0, 2, 6, 10, 14, 20], "kolmogorov": [8, 14], "ks_test": [8, 11], "kwarg": [0, 1, 3, 4, 5, 6, 10, 12, 13, 16, 17, 18, 19, 21, 22], "lang": 0, "languag": [12, 17], "larg": [1, 15, 16, 17], "larger": [2, 16, 19], "largest": 13, "last": [16, 17, 18], "lazi": 16, "lb": [6, 9], "le": 5, "learn": [10, 22], "least": [6, 8], "left": [16, 17, 18], "legaci": 6, "lemma": 18, "len": 12, "length": [6, 16, 17, 18, 19, 20, 21, 22], "less": [15, 16, 17, 18], "let": 16, "letter": 19, "level": [5, 18], "leverag": 1, "lg_config_k": 1, "lg_k": [0, 1, 3, 4], "lg_max_k": [1, 6], "lg_max_map_s": 6, "liberti": [18, 22], "librari": [2, 4, 6, 7, 10, 11, 15, 23], "like": [1, 7, 11, 16], "limit": [6, 19], "line": [16, 17, 18], "list": [5, 7, 9], "littl": 12, "load_factor": 6, "log": [1, 2], "log2": [1, 6], "logarithm": [0, 3, 4, 6], "logic": [6, 15], "longer": 2, "look": 6, "loos": 18, "lopez": 6, "low": [15, 18], "lower": [0, 1, 3, 4, 5, 6, 9, 16, 18, 21], "lower_bound": 9, "m": [6, 16, 17, 18], "machin": [10, 22], "mai": [5, 6, 14, 15, 16, 18, 19], "maintain": [3, 7], "make": 16, "mani": 3, "map": 6, "mapcap": 6, "mapsiz": 6, "margin": 19, "martin": 2, "mass": [15, 16, 17, 18], "mass_i": 16, "match": [0, 3, 4, 21], "mathemat": [10, 18], "max": [13, 16, 17, 18], "max_k": 21, "max_map_s": 6, "maximum": [1, 3, 4, 5, 6, 16, 17, 18, 19, 21], "maxintpolici": 13, "maxmapcap": 6, "maxmaps": 6, "mean": [4, 6, 16, 17, 19], "measur": [3, 4, 9, 16, 17, 18], "median": [6, 17], "member": [3, 6], "memori": [1, 2, 6], "merg": [0, 1, 4, 5, 6, 16, 17, 18, 19, 22], "method": [0, 1, 3, 4, 5, 6, 10, 12, 16, 17, 18, 19, 21, 22], "metwal": 6, "might": [6, 16], "million": 17, "min": [13, 16, 17, 18], "minim": 20, "minimum": [2, 3, 16, 17, 18, 21], "minintpolici": 13, "misra": 6, "miss": 6, "mlr": 22, "mode": [1, 3, 4, 16, 17, 18, 22], "modifi": [11, 18], "modul": 14, "monoton": [16, 17, 18], "more": [0, 6], "most": [7, 17], "much": [1, 6], "multipli": 17, "multiset": 6, "munro": 6, "must": [1, 3, 4, 10, 12, 13, 16, 17, 18], "muthukrishnan": 5, "n": [1, 16, 17, 18, 19, 21, 22], "name": 6, "nan": [16, 17, 18], "natur": [16, 17], "ndarrai": [16, 17, 18], "nearli": [0, 16], "necessari": [16, 17, 18], "necessarili": 7, "need": [3, 5, 6, 13, 19, 20, 21], "network": 17, "never": [5, 6, 16, 18], "new": [0, 1, 6, 13, 17, 19, 21, 22], "newli": 0, "no_false_neg": 6, "no_false_posit": 6, "node": 17, "nomin": [3, 4, 18], "non": [0, 1, 3, 4, 5, 6, 16, 17, 18, 19, 21, 22], "none": [0, 1, 3, 4, 5, 6, 16, 17, 18, 19, 21, 22], "normal": [16, 17, 18], "normalized_rank_error": [16, 17], "note": [6, 9, 11, 16, 18], "novemb": 17, "now": 23, "null": [11, 12], "num_active_item": 6, "num_bucket": 5, "num_byt": 12, "num_hash": 5, "num_retain": [3, 4, 16, 17, 18, 22], "num_sampl": 21, "num_std_dev": 1, "number": [0, 1, 2, 3, 4, 5, 6, 12, 16, 17, 18, 19, 21, 22], "numer": [15, 19], "numpi": 10, "numsect": 18, "object": [0, 1, 3, 4, 5, 6, 7, 9, 10, 12, 13, 16, 17, 18, 19, 21, 22], "obtain": [5, 16, 17, 18], "occurr": 5, "off": [1, 2, 16, 17, 18], "offer": [1, 2, 7], "offest": 12, "offset": 12, "often": 7, "one": [2, 5, 6, 7, 8, 16, 17, 18, 22], "onli": [1, 6, 16, 17, 18, 23], "oper": [0, 2, 3, 4, 13, 16, 18], "opposit": 16, "opt": 21, "optim": [0, 14, 16, 20], "option": [0, 3, 4, 6, 16, 17, 18, 19, 21], "order": [3, 4, 5, 13, 15, 19], "org": [11, 18], "ortiz": 6, "other": [3, 4, 5, 16, 17], "otherwis": [0, 1, 3, 4, 5, 6, 9, 11, 16, 17, 18, 19, 21, 22], "our": 6, "output": 18, "outsid": 7, "over": [6, 15, 17], "overal": 17, "overestim": 5, "overload": [0, 1, 3, 4, 5, 11, 16, 17, 18], "overrid": [10, 12], "p": [3, 4, 11, 19], "packag": 3, "packet": [6, 17], "page": 14, "pair": [6, 8, 11], "papadimitri": 6, "paper": [0, 3, 5, 18, 22], "paramet": [0, 1, 3, 4, 5, 6, 10, 12, 13, 16, 17, 18, 19, 21, 22], "partial": 19, "particular": 18, "particularli": 10, "pass": [16, 17], "pattern": 10, "pavel": 18, "pdf": [5, 22], "per": [1, 16], "percentag": 7, "percentil": [16, 17], "perform": [0, 1, 2, 3, 4, 8, 10, 11, 16, 18], "permiss": 5, "phillip": 1, "physic": 6, "plot": 16, "plu": 6, "pmf": [15, 16, 17, 18], "point": [0, 1, 3, 4, 10, 12, 15, 16, 17, 18, 19, 22], "polici": [4, 8, 14], "portion": [15, 19], "posit": 6, "possibl": 0, "power": [6, 18], "pp": 19, "practic": [3, 6], "pre": 12, "precis": [16, 17, 19], "predic": [20, 21], "present": 21, "press": 22, "print": [19, 21], "priori": [1, 6, 18], "probabilist": [1, 2, 5, 14, 15, 16, 17, 18], "probabilitii": [14, 20], "probabl": [0, 5, 6, 15, 16, 17, 18, 19, 20, 21], "problem": 14, "proceed": 22, "process": [19, 21], "produc": [0, 1, 3, 4, 5, 6, 16, 17, 18, 19, 21, 22], "project": [14, 17], "proof": 6, "properti": [0, 1, 2, 3, 4, 5, 6, 16, 17, 18, 19, 21, 22], "proport": [14, 20], "prototyp": 18, "proven": 15, "provid": [0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 15, 16, 17, 18, 21, 22, 23], "pub": 5, "purg": 6, "py": 22, "pydoublesserd": 12, "pyfloatsserd": 12, "pyintsserd": 12, "pylongsserd": 12, "pyobjectserd": [4, 6, 12, 16, 17, 18, 19, 21], "pystringsserd": 12, "python": [13, 18], "q": 16, "q_hi": 16, "q_lo": 16, "qualifi": 6, "quantil": [8, 16, 22], "quantiles_doubles_sketch": [11, 17], "quantiles_floats_sketch": [11, 17], "quantiles_ints_sketch": [11, 17], "quantiles_items_sketch": [11, 17], "queri": [5, 15, 16, 17, 21], "quickli": 14, "quit": [0, 4, 16], "r": 16, "r1": 16, "r2": 16, "r_": 16, "r_i": 16, "radial": 10, "random": [6, 19], "randomli": 20, "rang": 15, "rank": [15, 16, 17, 18], "rate": [3, 4], "reach": [1, 6], "read": [0, 1, 3, 4, 5, 6, 12, 19, 21, 22], "real": [16, 17, 18], "reason": 1, "rebuild": 6, "receiv": [1, 17], "recognit": 10, "recommend": 1, "reconstruct": 12, "redesign": 6, "rediscov": 6, "refer": [6, 8, 12, 16], "reflect": 11, "regardless": 7, "reject": 11, "rel": [1, 5, 7, 14, 15, 19, 20, 21], "relat": [7, 9, 19, 21], "relationship": 16, "relative_error": 5, "relev": 13, "reli": 10, "remain": 18, "remov": [3, 4, 6], "repeat": 6, "repres": [1, 17, 19], "req": [14, 15, 17], "req_floats_sketch": 18, "req_ints_sketch": 18, "req_items_sketch": 18, "requir": [4, 5, 6, 8, 16, 17, 18, 19, 21, 22], "reservoir": [19, 21], "reset": [1, 3, 4, 21], "respect": [16, 17], "result": [0, 3, 4, 6, 16, 17, 18, 20, 21], "retain": [3, 4, 6, 16, 17, 18, 22], "retun": 12, "return": [0, 1, 3, 4, 5, 6, 9, 10, 11, 12, 13, 16, 17, 18, 19, 21, 22], "right": [4, 16, 17, 18], "roughli": [0, 21], "round": 18, "row": 1, "rse": 18, "rule": 13, "run": 6, "runtimeerror": [16, 17, 18], "rutger": 5, "s1": 16, "s2": 16, "s_i": 16, "s_m": 16, "same": [1, 3, 11], "sampl": [3, 4, 16, 17, 18, 22], "satisfi": 5, "scheme": [12, 16], "score": 10, "search": 14, "section": 18, "section_s": 18, "secur": 0, "see": 16, "seed": [0, 3, 4, 5, 9], "seem": 16, "seen": [5, 6, 7, 15, 19], "self": [0, 1, 3, 4, 5, 6, 10, 12, 13, 16, 17, 18, 19, 21, 22], "semin": 2, "separ": [3, 9, 16, 17, 18], "serd": [4, 6, 8, 14, 16, 17, 18, 19, 21], "serial": [0, 1, 3, 4, 5, 6, 8, 14, 16, 17, 18, 19, 21, 22], "serialize_compact": 1, "serialize_updat": 1, "set": [2, 3, 4, 6, 13, 16, 17, 18, 22], "sever": [2, 3, 4, 6, 12], "shenker": 6, "should": [13, 16, 19], "shown": 16, "side": [16, 17], "significantli": 1, "similar": [2, 3, 4, 8, 10, 13, 14], "similarity_test": 9, "similarli": 17, "simpl": [2, 3, 6, 12], "simultan": 0, "sinc": [6, 18], "singl": [16, 17], "size": [1, 3, 4, 5, 6, 11, 12, 14, 16, 17, 18, 20, 21, 22], "sk_1": 11, "sk_2": 11, "skech": 18, "sketch": [0, 1, 2, 6, 8, 9, 11, 12, 19, 21], "sketch_a": 9, "sketch_b": 9, "slot": 1, "sm": 16, "small": [1, 6, 11], "smaller": [0, 1, 6, 16, 21], "smallest": 13, "smirnov": [8, 14], "snly": 7, "so": [0, 6, 15, 16, 17, 18, 19], "solut": 2, "some": [6, 8, 16], "sometim": 16, "somewhat": [2, 20], "sort": [3, 4, 16, 17, 18], "sourc": [3, 4], "sourch": 4, "space": [0, 1, 2, 3, 6], "special": 18, "specif": [6, 8, 10, 15, 16, 17], "specifi": [0, 1, 5, 6, 8, 12, 13, 16, 18], "speed": [0, 6], "split": [16, 17, 18], "split_point": [16, 17, 18], "sqrt": 18, "standard": [0, 1, 3, 4, 18], "start": [1, 6, 12, 18], "start_full_s": 1, "start_max_s": 1, "state": [1, 2, 3, 4, 6, 18, 21], "static": [0, 1, 3, 4, 5, 6, 16, 17, 18, 19, 21, 22], "stochast": [16, 17], "storag": [1, 12], "store": [2, 3, 6], "str": [0, 1, 3, 4, 5], "straightforward": 15, "stream": [0, 1, 3, 4, 5, 6, 7, 15, 16, 17, 18, 19, 20, 21, 22], "strictli": 19, "string": [0, 1, 3, 4, 5, 6, 7, 12, 16, 17, 18, 19, 21, 22], "string_cont": 12, "subset": [20, 21], "subtract": 16, "suggest": 5, "suggest_num_bucket": 5, "suggest_num_hash": 5, "sum": [6, 16, 17, 18, 20, 21], "summari": [0, 1, 3, 4, 5, 6, 8, 13, 16, 17, 18, 19, 21, 22], "support": [2, 6], "surviv": 0, "t": [16, 17], "tabl": [1, 6], "take": 11, "target": 1, "target_hll_typ": 1, "task": 2, "templat": [16, 17], "term": 1, "termin": 12, "test": [8, 9, 14], "tgt_hll_type": 1, "tgt_type": 1, "thaler": 18, "than": [0, 1, 2, 3, 6, 15, 16, 17, 18, 19], "thei": [4, 11, 15, 20], "them": 8, "theta": [1, 2, 4, 8, 9, 14], "theta64": [3, 4], "theta_a_not_b": 3, "theta_intersect": 3, "theta_jaccard_similar": [3, 9], "theta_sketch": [2, 3, 4, 9], "theta_union": 3, "thi": [0, 1, 4, 5, 6, 11, 12, 13, 14, 16, 17, 18, 19, 21, 22], "those": [7, 8], "thousand": [16, 17], "three": [1, 12, 15], "threshold": 9, "through": [3, 4, 6], "throw": [16, 17, 18], "thu": [16, 18], "tian": 19, "tight": 18, "time": [1, 6, 16, 17, 18], "to_byt": 12, "to_str": [0, 1, 3, 4, 5, 6, 16, 17, 18, 19, 21, 22], "too": [6, 11], "tool": 18, "top": [6, 7], "topk": 14, "total": [5, 17, 18, 19, 21], "total_weight": [5, 6], "track": 6, "trade": [1, 2, 16, 17, 18], "tradeoff": 0, "translat": 16, "trial": [16, 17], "trim": [3, 4], "true": [0, 1, 3, 4, 5, 6, 9, 11, 16, 17, 18, 19, 21, 22], "true_mass": 16, "true_rank": 16, "tupl": [2, 3, 8, 9, 12, 14], "tuple_a_not_b": [3, 4], "tuple_intersect": 4, "tuple_jaccard_similar": [4, 9], "tuple_polici": 8, "tuple_sketch": [2, 4, 8, 9, 13], "tuple_union": 4, "tuplepolici": [4, 13], "two": [0, 6, 7, 10, 11, 16, 18, 22], "type": [1, 2, 6, 7, 10, 11, 12, 13, 15], "typic": 6, "u": 16, "ub": [6, 9], "under": 14, "underestim": 5, "underli": 11, "understand": [15, 18], "unequ": 19, "uniform": [15, 19, 21], "union": [0, 1, 3, 4, 13, 21], "uniqu": [0, 1, 2, 16, 17, 18], "unsurprisingli": 10, "up": [1, 6], "updat": [0, 1, 3, 4, 5, 6, 13, 16, 17, 18, 19, 21, 22], "update_summari": 13, "update_theta_sketch": 3, "update_tuple_sketch": 4, "upon": 19, "upper": [0, 1, 3, 4, 5, 6, 9, 16, 18, 21], "upper_bound": [1, 9], "us": [1, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 22], "usag": 6, "user": [0, 10, 18], "usual": 6, "v99": 22, "valid": [3, 4, 18], "valu": [0, 1, 2, 3, 4, 5, 6, 10, 11, 12, 13, 15, 16, 17, 18, 19, 21], "var": 21, "var_opt_sketch": [20, 21], "var_opt_union": 21, "variabl": [6, 18], "varianc": [14, 20], "variant": [3, 6, 7], "varopt": [14, 19, 20], "vector": [10, 16, 17, 18, 22], "veri": [4, 6, 16, 17], "version": [1, 6, 7, 12, 15, 16, 17, 18], "vesel\u00fd": 18, "via": 18, "view": 16, "visibl": 18, "w": 6, "warmup": 1, "we": [6, 11, 16, 18], "weight": [5, 6, 7, 16, 17, 18, 19, 20, 21], "well": [0, 2, 15, 21], "were": [2, 6, 16, 17], "what": [6, 15], "when": [0, 1, 3, 4, 5, 8, 13, 15, 16, 17, 18, 21], "where": [1, 6, 12, 13, 16, 19], "whether": [1, 3, 4, 18], "which": [2, 3, 4, 5, 6, 7, 10, 12, 15, 16, 17, 18], "while": [2, 3], "whose": 7, "wiki": 11, "wikipedia": 11, "win": 0, "within": [5, 8], "work": [2, 17, 18], "wors": 16, "worst": 6, "would": 6, "written": [12, 18], "x": [5, 16], "y": [16, 19], "year": 6, "yield": 16, "you": 17, "zero": 16, "zohar": [18, 22]}, "titles": ["Compressed Probabilistic Counting (CPC)", "HyperLogLog (HLL)", "Distinct Counting", "Theta Sketch", "Tuple Sketch", "CountMin Sketch", "Frequent Items", "Frequency Sketches", "Helper Classes", "Jaccard Similarity", "Kernel Function", "Kolmogorov-Smirnov Test", "Serialize/Deserialize (SerDe)", "Tuple Policy", "Apache DataSketches", "Quantiles Sketches", "KLL Sketch", "Quantiles Sketch (Deprecated)", "Relative Error Quantiles (REQ) Sketch", "Exact and Bounded, Probabilitiy Proportional to Size (EBPPS) Sampling", "Random Sampling Sketches", "Variance Optimal Sampling (VarOpt)", "Density Sketch", "Vector Sketches"], "titleterms": {"apach": 14, "bound": 19, "class": [8, 14], "compress": 0, "count": [0, 2, 14], "countmin": 5, "cpc": 0, "datasketch": 14, "densiti": 22, "deprec": 17, "deseri": 12, "distinct": [2, 14], "ebpp": 19, "error": 18, "estim": 14, "exact": 19, "frequenc": [7, 14], "frequent": 6, "function": 10, "helper": [8, 14], "hll": 1, "hyperloglog": 1, "indic": 14, "item": 6, "jaccard": 9, "kernel": 10, "kll": 16, "kolmogorov": 11, "optim": 21, "polici": 13, "probabilist": 0, "probabilitii": 19, "proport": 19, "quantil": [14, 15, 17, 18], "random": [14, 20], "rel": 18, "req": 18, "sampl": [14, 19, 20, 21], "serd": 12, "serial": 12, "similar": 9, "size": 19, "sketch": [3, 4, 5, 7, 14, 15, 16, 17, 18, 20, 22, 23], "smirnov": 11, "tabl": 14, "test": 11, "theta": 3, "tupl": [4, 13], "varianc": 21, "varopt": 21, "vector": [14, 23]}}) \ No newline at end of file diff --git a/docs/5.0.1/vector/density_sketch.html b/docs/5.0.1/vector/density_sketch.html new file mode 100644 index 00000000..51b650b1 --- /dev/null +++ b/docs/5.0.1/vector/density_sketch.html @@ -0,0 +1,248 @@ + + + + + + + Density Sketch — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Density Sketch

+

Builds a coreset from the given set of input points. +Provides density estimate at a given point.

+

Based on the following paper: Zohar Karnin, Edo Liberty +“Discrepancy, Coresets, and Sketches in Machine Learning” +https://proceedings.mlr.press/v99/karnin19a/karnin19a.pdf

+

Inspired by the following implementation: https://github.com/edoliberty/streaming-quantiles/blob/f688c8161a25582457b0a09deb4630a81406293b/gde.py

+

Requires the use of a KernelFunction to compute the distance between two vectors.

+
+
+class density_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, kernel: _datasketches.KernelFunction) _datasketches.density_sketch
+

Reads a bytes object and returns the corresponding density_sketch

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int, dim: int, kernel: _datasketches.KernelFunction) None
+

Creates a new density sketch

+
+
Parameters:
+
    +
  • k (int) – controls the size and error of the sketch

  • +
  • dim (int) – dimension of the input data

  • +
  • kernel (KernelFunction) – instance of a kernel

  • +
+
+
+
+ +
+
+property dim
+

The configured parameter dim

+
+ +
+
+get_estimate
+

Returns an approximate density at the given point

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Updates the sketch with the given vector

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.1/vector/index.html b/docs/5.0.1/vector/index.html new file mode 100644 index 00000000..808fefda --- /dev/null +++ b/docs/5.0.1/vector/index.html @@ -0,0 +1,135 @@ + + + + + + + Vector Sketches — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Vector Sketches

+

These sketches are designed to accept vector inputs. For now, the library provides only the +density_sketch for Kernel Density Estimation.

+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.2/.buildinfo b/docs/5.0.2/.buildinfo new file mode 100644 index 00000000..6a08c6b8 --- /dev/null +++ b/docs/5.0.2/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. +config: c2b4fc476624577343da93a20886cb56 +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/docs/5.0.2/_sources/distinct_counting/cpc.rst.txt b/docs/5.0.2/_sources/distinct_counting/cpc.rst.txt new file mode 100644 index 00000000..6a28d387 --- /dev/null +++ b/docs/5.0.2/_sources/distinct_counting/cpc.rst.txt @@ -0,0 +1,32 @@ +Compressed Probabilistic Counting (CPC) +--------------------------------------- +High performance C++ implementation of Compressed Probabilistic Counting (CPC) Sketch. +This is a unique-counting sketch that implements the Compressed Probabilistic Counting (CPC, a.k.a FM85) algorithms developed by Kevin Lang in his paper +`Back to the Future: an Even More Nearly Optimal Cardinality Estimation Algorithm `_. +This sketch is extremely space-efficient when serialized. +In an apples-to-apples empirical comparison against compressed HyperLogLog sketches, this new algorithm simultaneously wins on the two dimensions of the space/accuracy tradeoff and produces sketches that are smaller than the entropy of HLL, so no possible implementation of compressed HLL can match its space efficiency for a given accuracy. As described in the paper this sketch implements a newly developed ICON estimator algorithm that survives unioning operations, another well-known estimator, the Historical Inverse Probability (HIP) estimator does not. +The update speed performance of this sketch is quite fast and is comparable to the speed of HLL. +The unioning (merging) capability of this sketch also allows for merging of sketches with different configurations of K. +For additional security this sketch can be configured with a user-specified hash seed. + + +.. autoclass:: _datasketches.cpc_sketch + :members: + :undoc-members: + :exclude-members: deserialize + + .. rubric:: Static Methods: + + .. automethod:: deserialize + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + + +.. autoclass:: _datasketches.cpc_union + :members: + :undoc-members: + :exclude-members: deserialize + + .. automethod:: __init__ diff --git a/docs/5.0.2/_sources/distinct_counting/hyper_log_log.rst.txt b/docs/5.0.2/_sources/distinct_counting/hyper_log_log.rst.txt new file mode 100644 index 00000000..287209b0 --- /dev/null +++ b/docs/5.0.2/_sources/distinct_counting/hyper_log_log.rst.txt @@ -0,0 +1,55 @@ +HyperLogLog (HLL) +----------------- +This is a high performance implementation of Phillipe Flajolet's HLL sketch but with significantly improved error behavior. + +If the ONLY use case for sketching is counting uniques and merging, the HLL sketch is a reasonable choice, although the highest performing in terms of accuracy for storage space consumed is CPC (Compressed Probabilistic Counting). For large enough counts, this HLL version (with HLL_4) can be 2 to 16 times smaller than the Theta sketch family for the same accuracy. + +This implementation offers three different types of HLL sketch, each with different trade-offs with accuracy, space and performance. +These types are specified with the target_hll_type parameter. + +In terms of accuracy, all three types, for the same lg_config_k, have the same error distribution as a function of ``n``, the number of unique values fed to the sketch. +The configuration parameter ``lg_config_k`` is the log-base-2 of ``k``, where ``k`` is the number of buckets or slots for the sketch. + +During warmup, when the sketch has only received a small number of unique items (up to about 10% of ``k``), this implementation leverages a new class of estimator algorithms with significantly better accuracy. + + +.. autoclass:: _datasketches.tgt_hll_type + + .. autoattribute:: HLL_4 + :annotation: : 4 bits per entry + + .. autoattribute:: HLL_6 + :annotation: : 6 bits per entry + + .. autoattribute:: HLL_8 + :annotation: : 8 bits per entry + + +.. autoclass:: _datasketches.hll_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_max_updatable_serialization_bytes, get_rel_err + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_max_updatable_serialization_bytes + .. automethod:: get_rel_err + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: _datasketches.hll_union + :members: + :undoc-members: + :exclude-members: get_rel_err + + .. rubric:: Static Methods: + + .. automethod:: get_rel_err + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + \ No newline at end of file diff --git a/docs/5.0.2/_sources/distinct_counting/index.rst.txt b/docs/5.0.2/_sources/distinct_counting/index.rst.txt new file mode 100644 index 00000000..f4038815 --- /dev/null +++ b/docs/5.0.2/_sources/distinct_counting/index.rst.txt @@ -0,0 +1,24 @@ +Distinct Counting +================= + +.. currentmodule:: datasketches + +Distinct counting is one of the earliest tasks to which sketches were applied. The concept is simple: +Provide an estimate of the number of unique elements in a set of data. One of the earliest solutions came +from Flajolet and Martin in 1985 with their seminal work +`Probabilistic counting Algorithms for Data Base Applications `_. + +The DataSketches library offers several types of distinct counting sketches, each with different properties. + + * :class:`hll_sketch`: Hyper Log Log, a well-known sketch for distinct counting but no longer state-of-the-art. + * :class:`cpc_sketch`: Provides a better accuracy-space trade-off than HLL, but with a somewhat larger footprint while in-memory. + * :class:`theta_sketch`: Theta sketch, a type of k-minimum value sketch, which provide good performance with intersection and set difference operations. + * :class:`tuple_sketch`: Tuple sketch, which is similar to a theta sketch but supports additional data stored with each key. + +.. toctree:: + :maxdepth: 1 + + hyper_log_log + cpc + theta + tuple \ No newline at end of file diff --git a/docs/5.0.2/_sources/distinct_counting/theta.rst.txt b/docs/5.0.2/_sources/distinct_counting/theta.rst.txt new file mode 100644 index 00000000..94951f96 --- /dev/null +++ b/docs/5.0.2/_sources/distinct_counting/theta.rst.txt @@ -0,0 +1,65 @@ +Theta Sketch +------------ + +.. currentmodule:: datasketches + +Theta sketches are used for distinct counting. + +The theta package contains the basic sketch classes that are members of the `Theta Sketch Framework `_. +There is a separate Tuple package for many of the sketches that are derived from the same algorithms defined in the Theta Sketch Framework paper. + +The *Theta Sketch* sketch is a space-efficient method for estimating cardinalities of sets. +It can also easily handle set operations (such as union, intersection, difference) while maintaining good accuracy. +Theta sketch is a practical variant of the K-Minimum Values sketch which avoids the need to sort the stored +hash values on every insertion to the sketch. +It has better error properties than the HyperLogLog sketch for set operations beyond the simple union. + +Set operations (union, intersection, A-not-B) are performed through the use of dedicated objects. + +Several `Jaccard similarity `_ +measures can be computed between theta sketches with the :class:`theta_jaccard_similarity` class. + +.. autoclass:: theta_sketch + :members: + :undoc-members: + +.. autoclass:: update_theta_sketch + :members: + :undoc-members: + + .. automethod:: __init__ + + +.. autoclass:: compact_theta_sketch + :members: + :undoc-members: + :exclude-members: deserialize + + .. rubric:: Static Methods: + + .. automethod:: deserialize + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + + +.. autoclass:: theta_union + :members: + :undoc-members: + + .. automethod:: __init__ + + +.. autoclass:: theta_intersection + :members: + :undoc-members: + + .. automethod:: __init__ + + +.. autoclass:: theta_a_not_b + :members: + :undoc-members: + + .. automethod:: __init__ diff --git a/docs/5.0.2/_sources/distinct_counting/tuple.rst.txt b/docs/5.0.2/_sources/distinct_counting/tuple.rst.txt new file mode 100644 index 00000000..e4a369f2 --- /dev/null +++ b/docs/5.0.2/_sources/distinct_counting/tuple.rst.txt @@ -0,0 +1,64 @@ +Tuple Sketch +------------ + +.. currentmodule:: datasketches + +Tuple sketches are an extension of Theta sketches, meaning they provide estimate of distinct counts, that +allow the keeping of arbitrary summaries associated with each retained key +(for example, a count for every key). The use of a :class:`tuple_sketch` requires a :class:`TuplePolicy` which +defines how summaries are created, updated, merged, or intersected. The library provides a few basic +examples of :class:`TuplePolicy` implementations, but the right custom summary and policy can allow very +complicated analysis to be performed quite easily. + +Set operations (union, intersection, A-not-B) are performed through the use of dedicated objects. + +Several `Jaccard similarity `_ +measures can be computed between theta sketches with the :class:`tuple_jaccard_similarity` class. + +.. note:: + Serializing and deserializing this sketch requires the use of a :class:`PyObjectSerDe`. + +.. autoclass:: tuple_sketch + :members: + :undoc-members: + +.. autoclass:: update_tuple_sketch + :members: + :undoc-members: + + .. automethod:: __init__ + + +.. autoclass:: compact_tuple_sketch + :members: + :undoc-members: + :exclude-members: deserialize + + .. rubric:: Static Methods: + + .. automethod:: deserialize + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + + +.. autoclass:: tuple_union + :members: + :undoc-members: + + .. automethod:: __init__ + + +.. autoclass:: tuple_intersection + :members: + :undoc-members: + + .. automethod:: __init__ + + +.. autoclass:: tuple_a_not_b + :members: + :undoc-members: + + .. automethod:: __init__ diff --git a/docs/5.0.2/_sources/frequency/count_min_sketch.rst.txt b/docs/5.0.2/_sources/frequency/count_min_sketch.rst.txt new file mode 100644 index 00000000..b53b02e4 --- /dev/null +++ b/docs/5.0.2/_sources/frequency/count_min_sketch.rst.txt @@ -0,0 +1,27 @@ +CountMin Sketch +--------------- + +The CountMin sketch, as described in Cormode and Muthukrishnan in +http://dimacs.rutgers.edu/~graham/pubs/papers/cm-full.pdf, +is used for approximate Frequency Estimation. +For an item :math:`x` with frequency :math:`f_x`, the sketch provides an estimate, :math:`\hat{f_x}`, +such that :math:`f_x \approx \hat{f_x}.` +The sketch guarantees that :math:`f_x \le \hat{f_x}` and provides a probabilistic upper bound which is dependent on the size parameters. +The sketch provides an estimate of the occurrence frequency for any queried item but, in contrast +to the Frequent Items Sketch, this sketch does not provide a list of +heavy hitters. + +.. currentmodule:: _datasketches + +.. autoclass:: count_min_sketch + :members: + :undoc-members: + :exclude-members: deserialize, suggest_num_buckets, suggest_num_hashes + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: suggest_num_buckets + .. automethod:: suggest_num_hashes + + .. rubric:: Non-static Methods: diff --git a/docs/5.0.2/_sources/frequency/frequent_items.rst.txt b/docs/5.0.2/_sources/frequency/frequent_items.rst.txt new file mode 100644 index 00000000..76d81f58 --- /dev/null +++ b/docs/5.0.2/_sources/frequency/frequent_items.rst.txt @@ -0,0 +1,120 @@ +Frequent Items +-------------- + +.. currentmodule:: datasketches + +This sketch is useful for tracking approximate frequencies of items (``object`` or ``string``) with optional associated +integer counts that are members of a multiset of such items. +The true frequency of an item is defined to be the sum of associated counts. + +This implementation provides the following capabilities: + +* Estimate the *frequency* of an item. +* Return *upper* and *lower bounds* of any item, such that the true frequency is always between the upper and lower bounds. +* Return a global *maximum error* that holds for all items in the stream. +* Return an array of frequent items that qualify either a *NO_FALSE_POSITIVES* or a *NO_FALSE_NEGATIVES* error type. +* *Merge* itself with another sketch object created from this class. +* *Serialize/Deserialize* to/from a byte array. + +**Space Usage** + +The sketch is initialized with a maximum map size, ``maxMapSize``, that specifies the maximum physical length of the internal hash map of the form ``(object item, int count)``. +The maximum map size is always a power of 2, defined through the variables ``lg_max_map_size``. + +The hash map starts at a very small size (8 entries) and grows as needed up to the specified maximum map size. + +Excluding external space required for the item objects, the internal memory space usage of this sketch is ``18 * mapSize`` bytes (assuming 8 bytes for each reference), +plus a small constant number of additional bytes. +The internal memory space usage of this sketch will never exceed ``18 * maxMapSize`` bytes, plus a small constant number of additional bytes. + +**Maximum Capacity of the Sketch** + +The ``LOAD_FACTOR`` for the hash map is internally set at :math:`75\%`, which means at any time the map capacity of ``(item, count)`` pairs is ``mapCap = 0.75 * mapSize``. +The maximum capacity of ``(item, count)`` pairs of the sketch is ``maxMapCap = 0.75 * maxMapSize``. + +**Updating the sketch with ``(item, count)`` pairs** + +If the item is found in the hash map, the mapped count field (the "counter") is incremented by the incoming count; otherwise, a new counter ``(item, count)`` pair is created. +If the number of tracked counters reaches the maximum capacity of the hash map, the sketch decrements all of the counters (by an approximately computed median) +and removes any non-positive counters. + +**Accuracy** + +If fewer than ``0.75 * maxMapSize`` different items are inserted into the sketch, the estimated frequencies returned by the sketch will be exact. + +The logic of the frequent items sketch is such that the stored counts and true counts are never too different. +More specifically, for any item, the sketch can return an estimate of the true frequency of item, along with upper and lower bounds on the frequency (that hold deterministically). + +For this implementation and for a specific active item, it is guaranteed that the true frequency will be between the Upper Bound (UB) and the Lower Bound (LB) computed for that item. +Specifically, ``(UB- LB) ≤ W * epsilon``, where :math:`W` denotes the sum of all item counts, and :math:`epsilon = 3.5/M`, where :math:`epsilon = M` is the maxMapSize. + +This is a worst-case guarantee that applies to arbitrary inputs. +For inputs typically seen in practice, ``(UB-LB)`` is usually much smaller. + +**Background** + +This code implements a variant of what is commonly known as the "Misra-Gries algorithm". +Variants of it were discovered and rediscovered and redesigned several times over the years: + +* *Finding repeated elements*, Misra, Gries, 1982 +* *Frequency estimation of Internet packet streams with limited space* Demaine, Lopez-Ortiz, Munro, 2002 +* *A simple algorithm for finding frequent elements in streams and bags* Karp, Shenker, Papadimitriou, 2003 +* *Efficient Computation of Frequent and Top-k Elements in Data Streams* Metwally, Agrawal, Abbadi, 2006 + + +For speed, we do employ some randomization that introduces a small probability that our proof of the worst-case bound might not apply to a given run. +However, we have ensured that this probability is extremely small. +For example, if the stream causes one table purge (rebuild), our proof of the worst-case bound applies with a probability of at least `1 - 1E-14`. +If the stream causes ``1E9`` purges, our proof applies with a probability of at least ``1 - 1E-5``. + +There are two flavors of Frequent Items Sketches, one with generic items (objects) and another specific to strings. +The string version is a legacy name from before the library supported generic objects and is retained +only for backwards compatibility. + +.. note:: + The :class:`frequent_items_sketch` uses an input object's ``__hash__`` and ``__eq__`` methods. + +.. note:: + Serializing and deserializing the :class:`frequent_items_sketch` requires the use of a :class:`PyObjectSerDe`. + +.. autoclass:: frequent_items_error_type + + .. autoattribute:: NO_FALSE_POSITIVES + :annotation: : Returns only true positives but may miss some heavy hitters. + + .. autoattribute:: NO_FALSE_NEGATIVES + :annotation: : Does not miss any heavy hitters but may return false positives. + + +.. autoclass:: frequent_items_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_epsilon_for_lg_size, get_apriori_error + :member-order: groupwise + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_epsilon_for_lg_size + .. automethod:: get_apriori_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + + +.. autoclass:: frequent_strings_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_epsilon_for_lg_size, get_apriori_error + :member-order: groupwise + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_epsilon_for_lg_size + .. automethod:: get_apriori_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ diff --git a/docs/5.0.2/_sources/frequency/index.rst.txt b/docs/5.0.2/_sources/frequency/index.rst.txt new file mode 100644 index 00000000..3cd3dfa5 --- /dev/null +++ b/docs/5.0.2/_sources/frequency/index.rst.txt @@ -0,0 +1,15 @@ +Frequency Sketches +================== + +Frequency estimation involves determining how often an item has been seen in a stream. The library currently +offers two types of sketches for frequency estimation, one of which has two closely-related variants. + + * :class:`frequent_items_sketch`: Identifies the *Top K* or *heavy hitters* in a stream, those items whose weight is above a certain percentage of the entire stream. Does not necessarily provide an estimate for most items outside the heavy hitters. + * :class:`frequent_strings_sketch`: Like the items version but containing snly strings (an implementation from before the library handled generic objects). + * :class:`count_min_sketch`: Provides an estimate for any item, regardless of relative weight, but does not maintain a list of the heaviest items. + +.. toctree:: + :maxdepth: 1 + + frequent_items + count_min_sketch \ No newline at end of file diff --git a/docs/5.0.2/_sources/helper/index.rst.txt b/docs/5.0.2/_sources/helper/index.rst.txt new file mode 100644 index 00000000..182b8e85 --- /dev/null +++ b/docs/5.0.2/_sources/helper/index.rst.txt @@ -0,0 +1,24 @@ +Helper Classes +============== + +.. currentmodule:: dataksetches + +These classes are required for certain sketches or specific +functionality within sketches. +Some of them are abstract base classes, but in those cases there is at +least one reference example of a concrete class. + + * :class:`serde` is used when serializing and deserializing sketches. + * :class:`jaccard` is used to compute the Jaccard similarity between pairs of theta or tuple sketches. + * :class:`tuple_policy` is required to use a :class:`tuple_sketch` by specifying how summaries are combined. + * :func:`ks_test` performs a Kolmogorov-Smirnov test on absolute-error quantiles family sketches. + * :class:`kernel_function` is required when using a :class:`kernel_sketch` for Kernel Density Estimation. + +.. toctree:: + :maxdepth: 1 + + serde + jaccard + tuple_policy + ks_test + kernel diff --git a/docs/5.0.2/_sources/helper/jaccard.rst.txt b/docs/5.0.2/_sources/helper/jaccard.rst.txt new file mode 100644 index 00000000..d3b9bfa3 --- /dev/null +++ b/docs/5.0.2/_sources/helper/jaccard.rst.txt @@ -0,0 +1,23 @@ +Jaccard Similarity +################## + +.. currentmodule:: datasketches + +These objects provide measures related to the `Jaccard similarity `_ +of :class:`theta_sketch` and :class:`tuple_sketch` objects. + +Note that there are separate classes to be used for theta and tuple sketches. + +.. autoclass:: theta_jaccard_similarity + + .. automethod:: jaccard + .. automethod:: exactly_equal + .. automethod:: similarity_test + .. automethod:: dissimilarity_test + +.. autoclass:: tuple_jaccard_similarity + + .. automethod:: jaccard + .. automethod:: exactly_equal + .. automethod:: similarity_test + .. automethod:: dissimilarity_test diff --git a/docs/5.0.2/_sources/helper/kernel.rst.txt b/docs/5.0.2/_sources/helper/kernel.rst.txt new file mode 100644 index 00000000..bdc2c729 --- /dev/null +++ b/docs/5.0.2/_sources/helper/kernel.rst.txt @@ -0,0 +1,21 @@ +Kernel Function +############### + +.. currentmodule:: datasketches + +A `kernel function `_ is a specific type of +mathematical funciton that is particularly useful in certain machine learning and pattern recognition +contexts. The :class:`density_sketch` performs approximate +`kernel density estimation `_ which, unsurprisingly, +relies on the use of such a kernel function. + +The library provides an abstract base class :class:`KernelFunction` and an example implementation of a +Gaussian (also known as a Radial Basis Function) kernel. Custom classes must override the base class +and provide a floating point value as a score indicating the similarity of two input vectors. + +.. autoclass:: KernelFunction + + .. automethod:: __call__ + +.. autoclass:: GaussianKernel + :show-inheritance: \ No newline at end of file diff --git a/docs/5.0.2/_sources/helper/ks_test.rst.txt b/docs/5.0.2/_sources/helper/ks_test.rst.txt new file mode 100644 index 00000000..c9bc19b0 --- /dev/null +++ b/docs/5.0.2/_sources/helper/ks_test.rst.txt @@ -0,0 +1,14 @@ +Kolmogorov-Smirnov Test +####################### + +.. currentmodule:: datasketches + +A `Kolmogorov-Smirnov Test `_` is +a test of equality of two distributions to determine if they are likely to have come from the same +underlying distribution. +The DataSketches library provides a modified form of the test that takes into account the error +in each underlying sketch in the analysis. + +Currently, the test assumes both input sketches are of the same family and data type. + +.. autofunction:: ks_test diff --git a/docs/5.0.2/_sources/helper/serde.rst.txt b/docs/5.0.2/_sources/helper/serde.rst.txt new file mode 100644 index 00000000..ccac1d84 --- /dev/null +++ b/docs/5.0.2/_sources/helper/serde.rst.txt @@ -0,0 +1,34 @@ +Serialize/Deserialize (SerDe) +############################# + +.. currentmodule:: datasketches + +A SerDe is a class used to serialize items sketches to a :class:`bytes` object in binary. +Several example SerDes are provided as references. + +The use of binary-compatible SerDes in different languages is critical for cross-language compatibility. + +Each implementation must extend the :class:`PyObjectSerDe` class and override all three of its methods. + +.. autoclass:: PyObjectSerDe + + .. automethod:: get_size + .. automethod:: to_bytes + .. automethod:: from_bytes + + +The provided SerDes are: + +.. autoclass:: PyStringsSerDe + :show-inheritance: + +.. autoclass:: PyIntsSerDe + :show-inheritance: + +.. autoclass:: PyLongsSerDe + :show-inheritance: + +.. autoclass:: PyFloatsSerDe + :show-inheritance: + +.. autoclass:: PyDoublesSerDe diff --git a/docs/5.0.2/_sources/helper/tuple_policy.rst.txt b/docs/5.0.2/_sources/helper/tuple_policy.rst.txt new file mode 100644 index 00000000..3f5781f2 --- /dev/null +++ b/docs/5.0.2/_sources/helper/tuple_policy.rst.txt @@ -0,0 +1,25 @@ +Tuple Policy +############ + +.. currentmodule:: datasketches + +A Tuple Policy is needed when using a :class:`tuple_sketch` in order to specify how the +summary values should be created, updated, combined, or intersected. A summary can consist of +any python object. + +Each implementation must extend the abstract base class :class:`TuplePolicy`. + +.. autoclass:: TuplePolicy + + .. automethod:: create_summary + .. automethod:: update_summary + .. automethod:: __call__ + +.. autoclass:: AccumulatorPolicy + :show-inheritance: + +.. autoclass:: MinIntPolicy + :show-inheritance: + +.. autoclass:: MaxIntPolicy + :show-inheritance: diff --git a/docs/5.0.2/_sources/index.rst.txt b/docs/5.0.2/_sources/index.rst.txt new file mode 100644 index 00000000..b683e1fd --- /dev/null +++ b/docs/5.0.2/_sources/index.rst.txt @@ -0,0 +1,73 @@ +.. datasketches documentation master file, created by + sphinx-quickstart on Tue Jul 25 11:04:59 2023. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Apache DataSketches +================================================= + +**DataSketches** are highly-efficient algorithms to analyze big data quickly. + + +Counting Distincts +################## +.. + maxdepth: 1 means only the heading is printed in the contents +.. toctree:: + :maxdepth: 2 + + distinct_counting/index + +Quantile Estimation +################### + +.. toctree:: + :maxdepth: 2 + + quantiles/index + +Frequency Sketches +################## +This problem may also be known as **heavy hitters** or **TopK** + +.. toctree:: + :maxdepth: 2 + + frequency/index + +Vector Sketches +############### + +.. toctree:: + :maxdepth: 2 + + vector/index + + +Random Sampling +############### + +.. toctree:: + :maxdepth: 2 + + sampling/index + +Helper Classes +############## + +.. toctree:: + :maxdepth: 2 + + helper/index + + +.. note:: + + This project is under active development. + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/docs/5.0.2/_sources/quantiles/index.rst.txt b/docs/5.0.2/_sources/quantiles/index.rst.txt new file mode 100644 index 00000000..b1928f67 --- /dev/null +++ b/docs/5.0.2/_sources/quantiles/index.rst.txt @@ -0,0 +1,26 @@ +Quantiles Sketches +================== + +Quantile estimation is useful for understanding the distribution of data values in a stream. The sketches currently +in the library are designed to answer queries about the `rank` of an item in the stream of items. That is, when +applying a global ordering on all the items, what is the portion of items seen so far that are less than (alternatively, +less-than-or-equal-to) the given item. Using straightforward logic, they can also estimate the item at a given rank +in the stream. + +These sketches may be used to compute approximate histograms, Probability Mass Functions (PMFs), or +Cumulative Distribution Functions (CDFs). + +The library provides three types of quantiles sketches, each of which has generic items as well as versions +specific to a given numeric type (e.g. integer or floating point values). All three types provide error +bounds on rank estimation with proven probabilistic error distributions. + + * KLL: Provides uniform rank estimation error over the entire range + * REQ: Provides relative rank error estimates, which decreases approaching either the high or low end values. + * Classic quantiles: Largely deprecated in favor of KLL, also provides uniform rank estimation error. Included largely for backwards compatibility with historic data. + +.. toctree:: + :maxdepth: 1 + + kll + req + quantiles_depr \ No newline at end of file diff --git a/docs/5.0.2/_sources/quantiles/kll.rst.txt b/docs/5.0.2/_sources/quantiles/kll.rst.txt new file mode 100644 index 00000000..0e54b443 --- /dev/null +++ b/docs/5.0.2/_sources/quantiles/kll.rst.txt @@ -0,0 +1,171 @@ +KLL Sketch +---------- + +.. currentmodule:: datasketches + +Implementation of a very compact quantiles sketch with lazy compaction scheme +and nearly optimal accuracy per retained item. +See `Optimal Quantile Approximation in Streams`. + +This is a stochastic streaming sketch that enables near real-time analysis of the +approximate distribution of items from a very large stream in a single pass, requiring only +that the items are comparable. +The analysis is obtained using `get_quantile()` function or the +inverse functions `get_rank()`, `get_pmf()` (Probability Mass Function), and `get_cdf()` +(Cumulative Distribution Function). + +As of May 2020, this implementation produces serialized sketches which are binary-compatible +with the equivalent Java implementation only when template parameter `T = float` +(32-bit single precision values). + +Given an input stream of `N` items, the `natural rank` of any specific +item is defined as its index `(1 to N)` in inclusive mode +or `(0 to N-1)` in exclusive mode +in the hypothetical sorted stream of all `N` input items. + +The `normalized rank` (`rank`) of any specific item is defined as its +`natural rank` divided by `N`. +Thus, the `normalized rank` is between zero and one. +In the documentation for this sketch `natural rank` is never used so any +reference to just `rank` should be interpreted to mean `normalized rank`. + +This sketch is configured with a parameter `k`, which affects the size of the sketch +and its estimation error. + +The estimation error is commonly called `epsilon` (or `eps`) and is a fraction +between zero and one. Larger values of `k` result in smaller values of `epsilon`. +Epsilon is always with respect to the rank and cannot be applied to the +corresponding items. + +The relationship between the `normalized rank` and the corresponding items can be viewed +as a two-dimensional monotonic plot with the `normalized rank` on one axis and the +corresponding items on the other axis. If the y-axis is specified as the item-axis and +the x-axis as the `normalized rank`, then `y = get_quantile(x)` is a monotonically +increasing function. + +The function `get_quantile(rank)` translates ranks into +corresponding quantiles. The functions `get_rank(item)`, +`get_cdf(...)` (Cumulative Distribution Function), and `get_pmf(...)` +(Probability Mass Function) perform the opposite operation and translate items into ranks. + +The `get_pmf(...)` function has about 13 to 47% worse rank error (depending +on `k`) than the other queries because the mass of each "bin" of the PMF has +"double-sided" error from the upper and lower edges of the bin as a result of a subtraction, +as the errors from the two edges can sometimes add. + +The default `k` of 200 yields a "single-sided" `epsilon` of about 1.33% and a +"double-sided" (PMF) `epsilon` of about 1.65%. + +A `get_quantile(rank)` query has the following guarantees: +- Let `q = get_quantile(r)` where `r` is the rank between zero and one. +- The quantile `q` will be an item from the input stream. +- Let `true_rank` be the true rank of `q` derived from the hypothetical sorted +stream of all `N` items. +- Let `eps = get_normalized_rank_error(false)`. +- Then `r - eps ≤ true_rank ≤ r + eps` with a confidence of 99%. Note that the +error is on the rank, not the quantile. + +A `get_rank(item)` query has the following guarantees: +- Let `r = get_rank(i)` where `i` is an item between the min and max items of +the input stream. +- Let `true_rank` be the true rank of `i` derived from the hypothetical sorted +stream of all `N` items. +- Let `eps = get_normalized_rank_error(false)`. +- Then `r - eps ≤ true_rank ≤ r + eps` with a confidence of 99%. + +A `get_pmf()` query has the following guarantees: +- Let `{r1, r2, ..., r(m+1)} = get_pmf(s1, s2, ..., sm)` where `s1, s2` are +split points (items from the input domain) between the min and max items of +the input stream. +- Let `mass_i = estimated mass between s_i and s_i+1`. +- Let `true_mass` be the true mass between the items of `s_i`, +`s_i+1` derived from the hypothetical sorted stream of all `N` items. +- Let `eps = get_normalized_rank_error(true)`. +- then `mass - eps ≤ true_mass ≤ mass + eps` with a confidence of 99%. +- `r(m+1)` includes the mass of all points larger than `s_m`. + +A `get_cdf(...)` query has the following guarantees; +- Let `{r1, r2, ..., r(m+1)} = get_cdf(s1, s2, ..., sm)` where `s1, s2, ...` are +split points (items from the input domain) between the min and max items of +the input stream. +- Let `mass_i = r_(i+1) - r_i`. +- Let `true_mass` be the true mass between the true ranks of `s_i`, +`s_i+1` derived from the hypothetical sorted stream of all `N` items. +- Let `eps = get_normalized_rank_error(true)`. +- then `mass - eps ≤ true_mass ≤ mass + eps` with a confidence of 99%. +- `1 - r(m+1)` includes the mass of all points larger than `s_m`. + +From the above, it might seem like we could make some estimates to bound the +`item` returned from a call to `get_quantile()`. The sketch, however, does not +let us derive error bounds or confidences around items. Because errors are independent, we +can approximately bracket a value as shown below, but there are no error estimates available. +Additionally, the interval may be quite large for certain distributions. +- Let `q = get_quantile(r)`, the estimated quantile of rank `r`. +- Let `eps = get_normalized_rank_error(false)`. +- Let `q_lo = estimated quantile of rank (r - eps)`. +- Let `q_hi = estimated quantile of rank (r + eps)`. +- Then `q_lo ≤ q ≤ q_hi`, with 99% confidence. + +.. note:: + For the :class:`kll_items_sketch`, objects must be comparable with ``__lt__``. + +.. note:: + Serializing and deserializing a :class:`kll_items_sketch` requires the use of a :class:`PyObjectSerDe`. + + +.. autoclass:: kll_ints_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_normalized_rank_error + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_normalized_rank_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: kll_floats_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_normalized_rank_error + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_normalized_rank_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: kll_doubles_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_normalized_rank_error + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_normalized_rank_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: kll_items_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_normalized_rank_error + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_normalized_rank_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + diff --git a/docs/5.0.2/_sources/quantiles/quantiles_depr.rst.txt b/docs/5.0.2/_sources/quantiles/quantiles_depr.rst.txt new file mode 100644 index 00000000..18dd5df6 --- /dev/null +++ b/docs/5.0.2/_sources/quantiles/quantiles_depr.rst.txt @@ -0,0 +1,106 @@ +Quantiles Sketch (Deprecated) +----------------------------- + +.. currentmodule:: datasketches + +This is a deprecated quantiles sketch that is included for cross-language compatibility. +Most new projects will favor the KLL sketch over this one, or the REQ sketch for higher accuracy +at the very edge of a distribution. + +This is a stochastic streaming sketch that enables near-real time analysis of the +approximate distribution from a very large stream in a single pass. +The analysis is obtained using `get_rank()` and `get_quantile()` functions, +the Probability Mass Function from `get_pmf()`` and the Cumulative Distribution Function from `get_cdf`. + +Consider a large stream of one million values such as packet sizes coming into a network node. +The natural rank of any specific size value is its index in the hypothetical sorted +array of values. +The normalized rank is the natural rank divided by the stream size, +in this case one million. +The value corresponding to the normalized rank of `0.5` represents the 50th percentile or median +value of the distribution, or `get_quantile(0.5)`. +Similarly, the 95th percentile is obtained from `get_quantile(0.95)`. + +From the min and max values, for example, 1 and 1000 bytes, +you can obtain the PMF from `get_pmf(100, 500, 900)` that will result in an array of +4 fractional values such as {.4, .3, .2, .1}, which means that +40% of the values were < 100, +30% of the values were ≥ 100 and < 500, +20% of the values were ≥ 500 and < 900, and +10% of the values were ≥ 900. +A frequency histogram can be obtained by multiplying these fractions by `get_n()`, +which is the total count of values received. +The `get_cdf()`` works similarly, but produces the cumulative distribution instead. + +As of November 2021, this implementation produces serialized sketches which are binary-compatible +with the equivalent Java implementation only when template parameter T = double +(64-bit double precision values). + +The accuracy of this sketch is a function of the configured value `k`, which also affects +the overall size of the sketch. Accuracy of this quantile sketch is always with respect to +the normalized rank. A `k` of 128 produces a normalized, rank error of about 1.7%. +For example, the median item returned from `get_quantile(0.5)` will be between the actual items +from the hypothetically sorted array of input items at normalized ranks of 0.483 and 0.517, with +a confidence of about 99%. + +.. note:: + For the :class:`quantiles_items_sketch`, objects must be comparable with ``__lt__``. + +.. note:: + Serializing and deserializing a :class:`quantiles_items_sketch` requires the use of a :class:`PyObjectSerDe`. + +.. autoclass:: quantiles_ints_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_normalized_rank_error + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_normalized_rank_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: quantiles_floats_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_normalized_rank_error + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_normalized_rank_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: quantiles_doubles_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_normalized_rank_error + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_normalized_rank_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: quantiles_items_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_normalized_rank_error + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_normalized_rank_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ diff --git a/docs/5.0.2/_sources/quantiles/req.rst.txt b/docs/5.0.2/_sources/quantiles/req.rst.txt new file mode 100644 index 00000000..3f63e01e --- /dev/null +++ b/docs/5.0.2/_sources/quantiles/req.rst.txt @@ -0,0 +1,79 @@ +Relative Error Quantiles (REQ) Sketch +------------------------------------- + +.. currentmodule:: datasketches + +This is an implementation based on the `paper `_ "Relative Error Streaming Quantiles" by Graham Cormode, Zohar Karnin, Edo Liberty, Justin Thaler, Pavel Veselý, and loosely derived from a Python prototype written by Pavel Veselý. + +This implementation differs from the algorithm described in the paper in the following: + +The algorithm requires no upper bound on the stream length. +Instead, each relative-compactor counts the number of compaction operations performed so far (via variable state). +Initially, the relative-compactor starts with `INIT_NUMBER_OF_SECTIONS`. +Each time the number of compactions `(variable state) exceeds 2^{numSections - 1}`, we double `numSections`. +Note that after merging the sketch with another one variable state may not correspond to the number of compactions performed at a particular level, however, +since the state variable never exceeds the number of compactions, the guarantees of the sketch remain valid. + +The size of each section (variable `k` and `section_size` in the code and parameter `k` in the paper) is +initialized with a number set by the user via variable `k`. +When the number of sections doubles, we decrease section_size by a factor of `sqrt(2)`. +This is applied at each level separately. +Thus, when we double the number of sections, the nominal compactor size increases by a factor of approx. `sqrt(2) (+/- rounding)`. + +The merge operation here does not perform "special compactions", which are used in the paper to allow for a tight mathematical analysis of the sketch. +This implementation provides a number of capabilities not discussed in the paper or provided in the Python prototype. + +The Python prototype only implemented high accuracy for low ranks. This implementation provides the user with the ability to +choose either high rank accuracy or low rank accuracy at the time of sketch construction. +The Python prototype only implemented a comparison criterion of `INCLUSIVE`. +This implementation allows the user to use both the `INCLUSIVE` criterion and the `EXCLUSIVE` criterion. +This implementation provides extensive debug visibility into the operation of the sketch with two levels of detail output. +This is not only useful for debugging, but is a powerful tool to help users understand how the sketch works. + +.. note:: + For the :class:`req_items_sketch`, objects must be comparable with ``__lt__``. + +.. note:: + Serializing and deserializing a :class:`req_items_sketch` requires the use of a :class:`PyObjectSerDe`. + +.. autoclass:: req_ints_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_RSE + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_RSE + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: req_floats_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_RSE + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_RSE + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: req_items_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_RSE + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_RSE + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ diff --git a/docs/5.0.2/_sources/sampling/ebpps.rst.txt b/docs/5.0.2/_sources/sampling/ebpps.rst.txt new file mode 100644 index 00000000..b2253209 --- /dev/null +++ b/docs/5.0.2/_sources/sampling/ebpps.rst.txt @@ -0,0 +1,33 @@ +Exact and Bounded, Probabilitiy Proportional to Size (EBPPS) Sampling +--------------------------------------------------------------------- + +.. currentmodule:: datasketches + +An EBPPS sketch produces a randome sample of data from a stream of items, ensuring that the probability +of including an item is always exactly equal to the item's size. The size of an item is defined as its +weight relative to the total weight of all items seen so far by the sketch. In contrast to VarOpt sampling, +this sketch may return fewer than `k` items in order to keep the probability of including an item strictly +proportional to its size. + +This sketch is based on: B. Hentschel, P. J. Haas, Y. Tian +"Exact PPS Sampling with Bounded Sample Size", +Information Processing Letters, 2023. + +EBPPS sampling is related to reservoir sampling, but handles unequal item weights. +Feeding the sketch items with a uniform weight value will produce a sample equivalent to reservoir sampling. + +.. note:: + Serializing and deserializing this sketch requires the use of a :class:`PyObjectSerDe`. + +.. autoclass:: ebpps_sketch + :members: + :undoc-members: + :exclude-members: deserialize + + .. rubric:: Static Methods: + + .. automethod:: deserialize + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ diff --git a/docs/5.0.2/_sources/sampling/index.rst.txt b/docs/5.0.2/_sources/sampling/index.rst.txt new file mode 100644 index 00000000..fca6c3ce --- /dev/null +++ b/docs/5.0.2/_sources/sampling/index.rst.txt @@ -0,0 +1,21 @@ +Random Sampling Sketches +======================== + +.. currentmodule:: datasketches + +These sketches are used to randomly sample items. The length of the input +stream does not need to be known in advance. + +Both VarOpt (Variance Optimal) and EBPPS (Exact and Bounded, +Probability Proportional to Size) sketches will include sample items based on +each item's weight relative to the weight of the entire stream but +they differ in details: + + * :class:`ebpps_sketch` ensures that the probability of including an item is always exactly proportional to the item's weight. + * :class:`var_opt_sketch` optimizes for applying a predicate to the resulting sample such that the variance of the subset sum after applying the predicate is minimized, even if the inclusion probability differs somewhat from being proportional to the item's weight. + +.. toctree:: + :maxdepth: 1 + + varopt + ebpps diff --git a/docs/5.0.2/_sources/sampling/varopt.rst.txt b/docs/5.0.2/_sources/sampling/varopt.rst.txt new file mode 100644 index 00000000..d837835e --- /dev/null +++ b/docs/5.0.2/_sources/sampling/varopt.rst.txt @@ -0,0 +1,42 @@ +Variance Optimal Sampling (VarOpt) +---------------------------------- + +.. currentmodule:: datasketches + +A VarOpt sketch samples data from a stream of items. The sketch is desinged for optimal (minimum) +variance when querying the sketch to estimate subset sums of items matching a provided predicate. +The sketch will produce a sample of size `k` (or smaller if fewer items have been presented), with +the probability of including an item roughly corresponding it the item's weight relative to the total +weight of all items presented to the sketch. + +VarOpt sampling is related to reservoir sampling, with improved error bounds for subset sum estimation. +Feeding the sketch items with a uniform weight value will produce a sample equivalent to reservoir sampling. + +.. note:: + Serializing and deserializing this sketch requires the use of a :class:`PyObjectSerDe`. + +.. autoclass:: var_opt_sketch + :members: + :undoc-members: + :exclude-members: deserialize + + .. rubric:: Static Methods: + + .. automethod:: deserialize + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: var_opt_union + :members: + :undoc-members: + :exclude-members: deserialize + + .. rubric:: Static Methods: + + .. automethod:: deserialize + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ diff --git a/docs/5.0.2/_sources/vector/density_sketch.rst.txt b/docs/5.0.2/_sources/vector/density_sketch.rst.txt new file mode 100644 index 00000000..07d83181 --- /dev/null +++ b/docs/5.0.2/_sources/vector/density_sketch.rst.txt @@ -0,0 +1,28 @@ +Density Sketch +-------------- + +.. currentmodule:: datasketches + +Builds a coreset from the given set of input points. +Provides density estimate at a given point. + +Based on the following paper: Zohar Karnin, Edo Liberty +"Discrepancy, Coresets, and Sketches in Machine Learning" +https://proceedings.mlr.press/v99/karnin19a/karnin19a.pdf + +Inspired by the following implementation: https://github.com/edoliberty/streaming-quantiles/blob/f688c8161a25582457b0a09deb4630a81406293b/gde.py + +Requires the use of a :class:`KernelFunction` to compute the distance between two vectors. + +.. autoclass:: density_sketch + :members: + :undoc-members: + :exclude-members: deserialize + + .. rubric:: Static Methods: + + .. automethod:: deserialize + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ diff --git a/docs/5.0.2/_sources/vector/index.rst.txt b/docs/5.0.2/_sources/vector/index.rst.txt new file mode 100644 index 00000000..1b83a43c --- /dev/null +++ b/docs/5.0.2/_sources/vector/index.rst.txt @@ -0,0 +1,12 @@ +Vector Sketches +================== + +.. currentmodule:: dataksetches + +These sketches are designed to accept vector inputs. For now, the library provides only the +:class:`density_sketch` for Kernel Density Estimation. + +.. toctree:: + :maxdepth: 1 + + density_sketch \ No newline at end of file diff --git a/docs/5.0.2/_static/_sphinx_javascript_frameworks_compat.js b/docs/5.0.2/_static/_sphinx_javascript_frameworks_compat.js new file mode 100644 index 00000000..81415803 --- /dev/null +++ b/docs/5.0.2/_static/_sphinx_javascript_frameworks_compat.js @@ -0,0 +1,123 @@ +/* Compatability shim for jQuery and underscores.js. + * + * Copyright Sphinx contributors + * Released under the two clause BSD licence + */ + +/** + * small helper function to urldecode strings + * + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL + */ +jQuery.urldecode = function(x) { + if (!x) { + return x + } + return decodeURIComponent(x.replace(/\+/g, ' ')); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s === 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node, addItems) { + if (node.nodeType === 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && + !jQuery(node.parentNode).hasClass(className) && + !jQuery(node.parentNode).hasClass("nohighlight")) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.className = className; + } + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + if (isInSVG) { + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + var bbox = node.parentElement.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": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} diff --git a/docs/5.0.2/_static/basic.css b/docs/5.0.2/_static/basic.css new file mode 100644 index 00000000..f316efcb --- /dev/null +++ b/docs/5.0.2/_static/basic.css @@ -0,0 +1,925 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- 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: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +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/docs/5.0.2/_static/css/badge_only.css b/docs/5.0.2/_static/css/badge_only.css new file mode 100644 index 00000000..c718cee4 --- /dev/null +++ b/docs/5.0.2/_static/css/badge_only.css @@ -0,0 +1 @@ +.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}} \ No newline at end of file diff --git a/docs/5.0.2/_static/css/fonts/Roboto-Slab-Bold.woff b/docs/5.0.2/_static/css/fonts/Roboto-Slab-Bold.woff new file mode 100644 index 00000000..6cb60000 Binary files /dev/null and b/docs/5.0.2/_static/css/fonts/Roboto-Slab-Bold.woff differ diff --git a/docs/5.0.2/_static/css/fonts/Roboto-Slab-Bold.woff2 b/docs/5.0.2/_static/css/fonts/Roboto-Slab-Bold.woff2 new file mode 100644 index 00000000..7059e231 Binary files /dev/null and b/docs/5.0.2/_static/css/fonts/Roboto-Slab-Bold.woff2 differ diff --git a/docs/5.0.2/_static/css/fonts/Roboto-Slab-Regular.woff b/docs/5.0.2/_static/css/fonts/Roboto-Slab-Regular.woff new file mode 100644 index 00000000..f815f63f Binary files /dev/null and b/docs/5.0.2/_static/css/fonts/Roboto-Slab-Regular.woff differ diff --git a/docs/5.0.2/_static/css/fonts/Roboto-Slab-Regular.woff2 b/docs/5.0.2/_static/css/fonts/Roboto-Slab-Regular.woff2 new file mode 100644 index 00000000..f2c76e5b Binary files /dev/null and b/docs/5.0.2/_static/css/fonts/Roboto-Slab-Regular.woff2 differ diff --git a/docs/5.0.2/_static/css/fonts/fontawesome-webfont.eot b/docs/5.0.2/_static/css/fonts/fontawesome-webfont.eot new file mode 100644 index 00000000..e9f60ca9 Binary files /dev/null and b/docs/5.0.2/_static/css/fonts/fontawesome-webfont.eot differ diff --git a/docs/5.0.2/_static/css/fonts/fontawesome-webfont.svg b/docs/5.0.2/_static/css/fonts/fontawesome-webfont.svg new file mode 100644 index 00000000..855c845e --- /dev/null +++ b/docs/5.0.2/_static/css/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/5.0.2/_static/css/fonts/fontawesome-webfont.ttf b/docs/5.0.2/_static/css/fonts/fontawesome-webfont.ttf new file mode 100644 index 00000000..35acda2f Binary files /dev/null and b/docs/5.0.2/_static/css/fonts/fontawesome-webfont.ttf differ diff --git a/docs/5.0.2/_static/css/fonts/fontawesome-webfont.woff b/docs/5.0.2/_static/css/fonts/fontawesome-webfont.woff new file mode 100644 index 00000000..400014a4 Binary files /dev/null and b/docs/5.0.2/_static/css/fonts/fontawesome-webfont.woff differ diff --git a/docs/5.0.2/_static/css/fonts/fontawesome-webfont.woff2 b/docs/5.0.2/_static/css/fonts/fontawesome-webfont.woff2 new file mode 100644 index 00000000..4d13fc60 Binary files /dev/null and b/docs/5.0.2/_static/css/fonts/fontawesome-webfont.woff2 differ diff --git a/docs/5.0.2/_static/css/fonts/lato-bold-italic.woff b/docs/5.0.2/_static/css/fonts/lato-bold-italic.woff new file mode 100644 index 00000000..88ad05b9 Binary files /dev/null and b/docs/5.0.2/_static/css/fonts/lato-bold-italic.woff differ diff --git a/docs/5.0.2/_static/css/fonts/lato-bold-italic.woff2 b/docs/5.0.2/_static/css/fonts/lato-bold-italic.woff2 new file mode 100644 index 00000000..c4e3d804 Binary files /dev/null and b/docs/5.0.2/_static/css/fonts/lato-bold-italic.woff2 differ diff --git a/docs/5.0.2/_static/css/fonts/lato-bold.woff b/docs/5.0.2/_static/css/fonts/lato-bold.woff new file mode 100644 index 00000000..c6dff51f Binary files /dev/null and b/docs/5.0.2/_static/css/fonts/lato-bold.woff differ diff --git a/docs/5.0.2/_static/css/fonts/lato-bold.woff2 b/docs/5.0.2/_static/css/fonts/lato-bold.woff2 new file mode 100644 index 00000000..bb195043 Binary files /dev/null and b/docs/5.0.2/_static/css/fonts/lato-bold.woff2 differ diff --git a/docs/5.0.2/_static/css/fonts/lato-normal-italic.woff b/docs/5.0.2/_static/css/fonts/lato-normal-italic.woff new file mode 100644 index 00000000..76114bc0 Binary files /dev/null and b/docs/5.0.2/_static/css/fonts/lato-normal-italic.woff differ diff --git a/docs/5.0.2/_static/css/fonts/lato-normal-italic.woff2 b/docs/5.0.2/_static/css/fonts/lato-normal-italic.woff2 new file mode 100644 index 00000000..3404f37e Binary files /dev/null and b/docs/5.0.2/_static/css/fonts/lato-normal-italic.woff2 differ diff --git a/docs/5.0.2/_static/css/fonts/lato-normal.woff b/docs/5.0.2/_static/css/fonts/lato-normal.woff new file mode 100644 index 00000000..ae1307ff Binary files /dev/null and b/docs/5.0.2/_static/css/fonts/lato-normal.woff differ diff --git a/docs/5.0.2/_static/css/fonts/lato-normal.woff2 b/docs/5.0.2/_static/css/fonts/lato-normal.woff2 new file mode 100644 index 00000000..3bf98433 Binary files /dev/null and b/docs/5.0.2/_static/css/fonts/lato-normal.woff2 differ diff --git a/docs/5.0.2/_static/css/theme.css b/docs/5.0.2/_static/css/theme.css new file mode 100644 index 00000000..19a446a0 --- /dev/null +++ b/docs/5.0.2/_static/css/theme.css @@ -0,0 +1,4 @@ +html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden],audio:not([controls]){display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;text-decoration:none}ins,mark{color:#000}mark{background:#ff0;font-style:italic;font-weight:700}.rst-content code,.rst-content tt,code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:after,q:before{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,ol,ul{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure,form{margin:0}label{cursor:pointer}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{body,html,section{background:none!important}*{box-shadow:none!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}.rst-content .toctree-wrapper>p.caption,h2,h3,p{orphans:3;widows:3}.rst-content .toctree-wrapper>p.caption,h2,h3{page-break-after:avoid}}.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .eqno .headerlink:before,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .eqno .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a button.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-left.toctree-expand,.wy-menu-vertical li button.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .eqno .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a button.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-right.toctree-expand,.wy-menu-vertical li button.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .eqno .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a button.pull-left.toctree-expand,.wy-menu-vertical li.on a button.pull-left.toctree-expand,.wy-menu-vertical li button.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .eqno .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a button.pull-right.toctree-expand,.wy-menu-vertical li.on a button.pull-right.toctree-expand,.wy-menu-vertical li button.pull-right.toctree-expand{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li button.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content .eqno a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content p a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li a button.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content .eqno .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content p .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li button.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content .eqno .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a button.toctree-expand,.btn .wy-menu-vertical li.on a button.toctree-expand,.btn .wy-menu-vertical li button.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content .eqno .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a button.toctree-expand,.nav .wy-menu-vertical li.on a button.toctree-expand,.nav .wy-menu-vertical li button.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .eqno .btn .headerlink,.rst-content .eqno .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p .btn .headerlink,.rst-content p .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn button.toctree-expand,.wy-menu-vertical li.current>a .btn button.toctree-expand,.wy-menu-vertical li.current>a .nav button.toctree-expand,.wy-menu-vertical li .nav button.toctree-expand,.wy-menu-vertical li.on a .btn button.toctree-expand,.wy-menu-vertical li.on a .nav button.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .eqno .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li button.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .eqno .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li button.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .eqno .btn .fa-large.headerlink,.rst-content .eqno .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p .btn .fa-large.headerlink,.rst-content p .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn button.fa-large.toctree-expand,.wy-menu-vertical li .nav button.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .eqno .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li button.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .eqno .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li button.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .eqno .btn .fa-spin.headerlink,.rst-content .eqno .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p .btn .fa-spin.headerlink,.rst-content p .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn button.fa-spin.toctree-expand,.wy-menu-vertical li .nav button.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content .eqno .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li button.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content .eqno .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li button.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content .eqno .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li button.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content .eqno .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini button.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.rst-content section ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.rst-content section ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.rst-content section ul li p:last-child,.rst-content section ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.rst-content section ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.rst-content section ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.rst-content section ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content .section ol.arabic,.rst-content .toctree-wrapper ol,.rst-content .toctree-wrapper ol.arabic,.rst-content section ol,.rst-content section ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol.arabic li,.rst-content .section ol li,.rst-content .toctree-wrapper ol.arabic li,.rst-content .toctree-wrapper ol li,.rst-content section ol.arabic li,.rst-content section ol li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol.arabic li ul,.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content .toctree-wrapper ol.arabic li ul,.rst-content .toctree-wrapper ol li p:last-child,.rst-content .toctree-wrapper ol li ul,.rst-content section ol.arabic li ul,.rst-content section ol li p:last-child,.rst-content section ol li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol.arabic li ul li,.rst-content .section ol li ul li,.rst-content .toctree-wrapper ol.arabic li ul li,.rst-content .toctree-wrapper ol li ul li,.rst-content section ol.arabic li ul li,.rst-content section ol li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs>li{display:inline-block;padding-top:5px}.wy-breadcrumbs>li.wy-breadcrumbs-aside{float:right}.rst-content .wy-breadcrumbs>li code,.rst-content .wy-breadcrumbs>li tt,.wy-breadcrumbs>li .rst-content tt,.wy-breadcrumbs>li code{all:inherit;color:inherit}.breadcrumb-item:before{content:"/";color:#bbb;font-size:13px;padding:0 6px 0 3px}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li button.toctree-expand{display:block;float:left;margin-left:-1.2em;line-height:18px;color:#4d4d4d;border:none;background:none;padding:0}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover button.toctree-expand,.wy-menu-vertical li.on a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand{display:block;line-height:18px;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{padding:.4045em 1.618em .4045em 4.045em}.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{padding:.4045em 1.618em .4045em 5.663em}.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a{padding:.4045em 1.618em .4045em 7.281em}.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a{padding:.4045em 1.618em .4045em 8.899em}.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a{padding:.4045em 1.618em .4045em 10.517em}.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a{padding:.4045em 1.618em .4045em 12.135em}.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a{padding:.4045em 1.618em .4045em 13.753em}.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a{padding:.4045em 1.618em .4045em 15.371em}.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 1.618em .4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 button.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 button.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover button.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active button.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em;max-width:100%}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search>a:hover{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.version{margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .eqno .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content .eqno .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}.rst-content .toctree-wrapper>p.caption,.rst-content h1,.rst-content h2,.rst-content h3,.rst-content h4,.rst-content h5,.rst-content h6{margin-bottom:24px}.rst-content img{max-width:100%;height:auto}.rst-content div.figure,.rst-content figure{margin-bottom:24px}.rst-content div.figure .caption-text,.rst-content figure .caption-text{font-style:italic}.rst-content div.figure p:last-child.caption,.rst-content figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center,.rst-content figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img,.rst-content section>a>img,.rst-content section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp,.rst-content div.highlight span.linenos{user-select:none;pointer-events:none}.rst-content div.highlight span.linenos{display:inline-block;padding-left:0;padding-right:12px;margin-right:12px;border-right:1px solid #e6e9ea}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li,.rst-content .toctree-wrapper ol.loweralpha,.rst-content .toctree-wrapper ol.loweralpha>li,.rst-content section ol.loweralpha,.rst-content section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li,.rst-content .toctree-wrapper ol.upperalpha,.rst-content .toctree-wrapper ol.upperalpha>li,.rst-content section ol.upperalpha,.rst-content section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*,.rst-content .toctree-wrapper ol li>*,.rst-content .toctree-wrapper ul li>*,.rst-content section ol li>*,.rst-content section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child,.rst-content .toctree-wrapper ol li>:first-child,.rst-content .toctree-wrapper ul li>:first-child,.rst-content section ol li>:first-child,.rst-content section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child,.rst-content .toctree-wrapper ol li>p,.rst-content .toctree-wrapper ol li>p:last-child,.rst-content .toctree-wrapper ul li>p,.rst-content .toctree-wrapper ul li>p:last-child,.rst-content section ol li>p,.rst-content section ol li>p:last-child,.rst-content section ul li>p,.rst-content section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child,.rst-content .toctree-wrapper ol li>p:only-child,.rst-content .toctree-wrapper ol li>p:only-child:last-child,.rst-content .toctree-wrapper ul li>p:only-child,.rst-content .toctree-wrapper ul li>p:only-child:last-child,.rst-content section ol li>p:only-child,.rst-content section ol li>p:only-child:last-child,.rst-content section ul li>p:only-child,.rst-content section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul,.rst-content .toctree-wrapper ol li>ol,.rst-content .toctree-wrapper ol li>ul,.rst-content .toctree-wrapper ul li>ol,.rst-content .toctree-wrapper ul li>ul,.rst-content section ol li>ol,.rst-content section ol li>ul,.rst-content section ul li>ol,.rst-content section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul,.rst-content .toctree-wrapper ol.simple li>*,.rst-content .toctree-wrapper ol.simple li ol,.rst-content .toctree-wrapper ol.simple li ul,.rst-content .toctree-wrapper ul.simple li>*,.rst-content .toctree-wrapper ul.simple li ol,.rst-content .toctree-wrapper ul.simple li ul,.rst-content section ol.simple li>*,.rst-content section ol.simple li ol,.rst-content section ol.simple li ul,.rst-content section ul.simple li>*,.rst-content section ul.simple li ol,.rst-content section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink{opacity:0;font-size:14px;font-family:FontAwesome;margin-left:.5em}.rst-content .code-block-caption .headerlink:focus,.rst-content .code-block-caption:hover .headerlink,.rst-content .eqno .headerlink:focus,.rst-content .eqno:hover .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink:focus,.rst-content .toctree-wrapper>p.caption:hover .headerlink,.rst-content dl dt .headerlink:focus,.rst-content dl dt:hover .headerlink,.rst-content h1 .headerlink:focus,.rst-content h1:hover .headerlink,.rst-content h2 .headerlink:focus,.rst-content h2:hover .headerlink,.rst-content h3 .headerlink:focus,.rst-content h3:hover .headerlink,.rst-content h4 .headerlink:focus,.rst-content h4:hover .headerlink,.rst-content h5 .headerlink:focus,.rst-content h5:hover .headerlink,.rst-content h6 .headerlink:focus,.rst-content h6:hover .headerlink,.rst-content p.caption .headerlink:focus,.rst-content p.caption:hover .headerlink,.rst-content p .headerlink:focus,.rst-content p:hover .headerlink,.rst-content table>caption .headerlink:focus,.rst-content table>caption:hover .headerlink{opacity:1}.rst-content p a{overflow-wrap:anywhere}.rst-content .wy-table td p,.rst-content .wy-table td ul,.rst-content .wy-table th p,.rst-content .wy-table th ul,.rst-content table.docutils td p,.rst-content table.docutils td ul,.rst-content table.docutils th p,.rst-content table.docutils th ul,.rst-content table.field-list td p,.rst-content table.field-list td ul,.rst-content table.field-list th p,.rst-content table.field-list th ul{font-size:inherit}.rst-content .btn:focus{outline:2px solid}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .citation-reference>span.fn-bracket,.rst-content .footnote-reference>span.fn-bracket{display:none}.rst-content .hlist{width:100%}.rst-content dl dt span.classifier:before{content:" : "}.rst-content dl dt span.classifier-delimiter{display:none!important}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:auto minmax(80%,95%)}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{display:inline-grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{display:grid;grid-template-columns:auto auto minmax(.65rem,auto) minmax(40%,95%)}html.writer-html5 .rst-content aside.citation>span.label,html.writer-html5 .rst-content aside.footnote>span.label,html.writer-html5 .rst-content div.citation>span.label{grid-column-start:1;grid-column-end:2}html.writer-html5 .rst-content aside.citation>span.backrefs,html.writer-html5 .rst-content aside.footnote>span.backrefs,html.writer-html5 .rst-content div.citation>span.backrefs{grid-column-start:2;grid-column-end:3;grid-row-start:1;grid-row-end:3}html.writer-html5 .rst-content aside.citation>p,html.writer-html5 .rst-content aside.footnote>p,html.writer-html5 .rst-content div.citation>p{grid-column-start:4;grid-column-end:5}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{margin-bottom:24px}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.citation>dt>span.brackets:before,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.citation>dt>span.brackets:after,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a{word-break:keep-all}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a:not(:first-child):before,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.citation>dd p,html.writer-html5 .rst-content dl.footnote>dd p{font-size:.9rem}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{padding-left:1rem;padding-right:1rem;font-size:.9rem;line-height:1.2rem}html.writer-html5 .rst-content aside.citation p,html.writer-html5 .rst-content aside.footnote p,html.writer-html5 .rst-content div.citation p{font-size:.9rem;line-height:1.2rem;margin-bottom:12px}html.writer-html5 .rst-content aside.citation span.backrefs,html.writer-html5 .rst-content aside.footnote span.backrefs,html.writer-html5 .rst-content div.citation span.backrefs{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content aside.citation span.backrefs>a,html.writer-html5 .rst-content aside.footnote span.backrefs>a,html.writer-html5 .rst-content div.citation span.backrefs>a{word-break:keep-all}html.writer-html5 .rst-content aside.citation span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content aside.footnote span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content div.citation span.backrefs>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content aside.citation span.label,html.writer-html5 .rst-content aside.footnote span.label,html.writer-html5 .rst-content div.citation span.label{line-height:1.2rem}html.writer-html5 .rst-content aside.citation-list,html.writer-html5 .rst-content aside.footnote-list,html.writer-html5 .rst-content div.citation-list{margin-bottom:24px}html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content aside.footnote-list aside.footnote,html.writer-html5 .rst-content div.citation-list>div.citation,html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content aside.footnote-list aside.footnote code,html.writer-html5 .rst-content aside.footnote-list aside.footnote tt,html.writer-html5 .rst-content aside.footnote code,html.writer-html5 .rst-content aside.footnote tt,html.writer-html5 .rst-content div.citation-list>div.citation code,html.writer-html5 .rst-content div.citation-list>div.citation tt,html.writer-html5 .rst-content dl.citation code,html.writer-html5 .rst-content dl.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c;white-space:normal}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040;overflow-wrap:normal}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}.rst-content dl dd>ol:last-child,.rst-content dl dd>p:last-child,.rst-content dl dd>table:last-child,.rst-content dl dd>ul:last-child{margin-bottom:0}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px;max-width:100%}html.writer-html4 .rst-content dl:not(.docutils) .k,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .k{font-style:italic}html.writer-html4 .rst-content dl:not(.docutils) .descclassname,html.writer-html4 .rst-content dl:not(.docutils) .descname,html.writer-html4 .rst-content dl:not(.docutils) .sig-name,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .sig-name{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#000}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel,.rst-content .menuselection{font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .guilabel,.rst-content .menuselection{border:1px solid #7fbbe3;background:#e7f2fa}.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>.kbd,.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>kbd{color:inherit;font-size:80%;background-color:#fff;border:1px solid #a6a6a6;border-radius:4px;box-shadow:0 2px grey;padding:2.4px 6px;margin:auto 0}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block} \ No newline at end of file diff --git a/docs/5.0.2/_static/doctools.js b/docs/5.0.2/_static/doctools.js new file mode 100644 index 00000000..4d67807d --- /dev/null +++ b/docs/5.0.2/_static/doctools.js @@ -0,0 +1,156 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Base JavaScript utilities for all Sphinx HTML documentation. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"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/docs/5.0.2/_static/documentation_options.js b/docs/5.0.2/_static/documentation_options.js new file mode 100644 index 00000000..e21c068c --- /dev/null +++ b/docs/5.0.2/_static/documentation_options.js @@ -0,0 +1,13 @@ +const DOCUMENTATION_OPTIONS = { + VERSION: '0.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/docs/5.0.2/_static/file.png b/docs/5.0.2/_static/file.png new file mode 100644 index 00000000..a858a410 Binary files /dev/null and b/docs/5.0.2/_static/file.png differ diff --git a/docs/5.0.2/_static/jquery.js b/docs/5.0.2/_static/jquery.js new file mode 100644 index 00000000..c4c6022f --- /dev/null +++ b/docs/5.0.2/_static/jquery.js @@ -0,0 +1,2 @@ +/*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=y.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=y.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),y.elements=c+" "+a,j(b)}function f(a){var b=x[a[v]];return b||(b={},w++,a[v]=w,x[w]=b),b}function g(a,c,d){if(c||(c=b),q)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():u.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||t.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),q)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return y.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(y,b.frag)}function j(a){a||(a=b);var d=f(a);return!y.shivCSS||p||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),q||i(a,d),a}function k(a){for(var b,c=a.getElementsByTagName("*"),e=c.length,f=RegExp("^(?:"+d().join("|")+")$","i"),g=[];e--;)b=c[e],f.test(b.nodeName)&&g.push(b.applyElement(l(b)));return g}function l(a){for(var b,c=a.attributes,d=c.length,e=a.ownerDocument.createElement(A+":"+a.nodeName);d--;)b=c[d],b.specified&&e.setAttribute(b.nodeName,b.nodeValue);return e.style.cssText=a.style.cssText,e}function m(a){for(var b,c=a.split("{"),e=c.length,f=RegExp("(^|[\\s,>+~])("+d().join("|")+")(?=[[\\s,>+~#.:]|$)","gi"),g="$1"+A+"\\:$2";e--;)b=c[e]=c[e].split("}"),b[b.length-1]=b[b.length-1].replace(f,g),c[e]=b.join("}");return c.join("{")}function n(a){for(var b=a.length;b--;)a[b].removeNode()}function o(a){function b(){clearTimeout(g._removeSheetTimer),d&&d.removeNode(!0),d=null}var d,e,g=f(a),h=a.namespaces,i=a.parentWindow;return!B||a.printShived?a:("undefined"==typeof h[A]&&h.add(A),i.attachEvent("onbeforeprint",function(){b();for(var f,g,h,i=a.styleSheets,j=[],l=i.length,n=Array(l);l--;)n[l]=i[l];for(;h=n.pop();)if(!h.disabled&&z.test(h.media)){try{f=h.imports,g=f.length}catch(o){g=0}for(l=0;g>l;l++)n.push(f[l]);try{j.push(h.cssText)}catch(o){}}j=m(j.reverse().join("")),e=k(a),d=c(a,j)}),i.attachEvent("onafterprint",function(){n(e),clearTimeout(g._removeSheetTimer),g._removeSheetTimer=setTimeout(b,500)}),a.printShived=!0,a)}var p,q,r="3.7.3",s=a.html5||{},t=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,u=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,v="_html5shiv",w=0,x={};!function(){try{var a=b.createElement("a");a.innerHTML="",p="hidden"in a,q=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){p=!0,q=!0}}();var y={elements:s.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:r,shivCSS:s.shivCSS!==!1,supportsUnknownElements:q,shivMethods:s.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=y,j(b);var z=/^$|\b(?:all|print)\b/,A="html5shiv",B=!q&&function(){var c=b.documentElement;return!("undefined"==typeof b.namespaces||"undefined"==typeof b.parentWindow||"undefined"==typeof c.applyElement||"undefined"==typeof c.removeNode||"undefined"==typeof a.attachEvent)}();y.type+=" print",y.shivPrint=o,o(b),"object"==typeof module&&module.exports&&(module.exports=y)}("undefined"!=typeof window?window:this,document); \ No newline at end of file diff --git a/docs/5.0.2/_static/js/html5shiv.min.js b/docs/5.0.2/_static/js/html5shiv.min.js new file mode 100644 index 00000000..cd1c674f --- /dev/null +++ b/docs/5.0.2/_static/js/html5shiv.min.js @@ -0,0 +1,4 @@ +/** +* @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed +*/ +!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.3-pre",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b),"object"==typeof module&&module.exports&&(module.exports=t)}("undefined"!=typeof window?window:this,document); \ No newline at end of file diff --git a/docs/5.0.2/_static/js/theme.js b/docs/5.0.2/_static/js/theme.js new file mode 100644 index 00000000..1fddb6ee --- /dev/null +++ b/docs/5.0.2/_static/js/theme.js @@ -0,0 +1 @@ +!function(n){var e={};function t(i){if(e[i])return e[i].exports;var o=e[i]={i:i,l:!1,exports:{}};return n[i].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=n,t.c=e,t.d=function(n,e,i){t.o(n,e)||Object.defineProperty(n,e,{enumerable:!0,get:i})},t.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},t.t=function(n,e){if(1&e&&(n=t(n)),8&e)return n;if(4&e&&"object"==typeof n&&n&&n.__esModule)return n;var i=Object.create(null);if(t.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:n}),2&e&&"string"!=typeof n)for(var o in n)t.d(i,o,function(e){return n[e]}.bind(null,o));return i},t.n=function(n){var e=n&&n.__esModule?function(){return n.default}:function(){return n};return t.d(e,"a",e),e},t.o=function(n,e){return Object.prototype.hasOwnProperty.call(n,e)},t.p="",t(t.s=0)}([function(n,e,t){t(1),n.exports=t(3)},function(n,e,t){(function(){var e="undefined"!=typeof window?window.jQuery:t(2);n.exports.ThemeNav={navBar:null,win:null,winScroll:!1,winResize:!1,linkScroll:!1,winPosition:0,winHeight:null,docHeight:null,isRunning:!1,enable:function(n){var t=this;void 0===n&&(n=!0),t.isRunning||(t.isRunning=!0,e((function(e){t.init(e),t.reset(),t.win.on("hashchange",t.reset),n&&t.win.on("scroll",(function(){t.linkScroll||t.winScroll||(t.winScroll=!0,requestAnimationFrame((function(){t.onScroll()})))})),t.win.on("resize",(function(){t.winResize||(t.winResize=!0,requestAnimationFrame((function(){t.onResize()})))})),t.onResize()})))},enableSticky:function(){this.enable(!0)},init:function(n){n(document);var e=this;this.navBar=n("div.wy-side-scroll:first"),this.win=n(window),n(document).on("click","[data-toggle='wy-nav-top']",(function(){n("[data-toggle='wy-nav-shift']").toggleClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift")})).on("click",".wy-menu-vertical .current ul li a",(function(){var t=n(this);n("[data-toggle='wy-nav-shift']").removeClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift"),e.toggleCurrent(t),e.hashChange()})).on("click","[data-toggle='rst-current-version']",(function(){n("[data-toggle='rst-versions']").toggleClass("shift-up")})),n("table.docutils:not(.field-list,.footnote,.citation)").wrap("
"),n("table.docutils.footnote").wrap("
"),n("table.docutils.citation").wrap("
"),n(".wy-menu-vertical ul").not(".simple").siblings("a").each((function(){var t=n(this);expand=n(''),expand.on("click",(function(n){return e.toggleCurrent(t),n.stopPropagation(),!1})),t.prepend(expand)}))},reset:function(){var n=encodeURI(window.location.hash)||"#";try{var e=$(".wy-menu-vertical"),t=e.find('[href="'+n+'"]');if(0===t.length){var i=$('.document [id="'+n.substring(1)+'"]').closest("div.section");0===(t=e.find('[href="#'+i.attr("id")+'"]')).length&&(t=e.find('[href="#"]'))}if(t.length>0){$(".wy-menu-vertical .current").removeClass("current").attr("aria-expanded","false"),t.addClass("current").attr("aria-expanded","true"),t.closest("li.toctree-l1").parent().addClass("current").attr("aria-expanded","true");for(let n=1;n<=10;n++)t.closest("li.toctree-l"+n).addClass("current").attr("aria-expanded","true");t[0].scrollIntoView()}}catch(n){console.log("Error expanding nav for anchor",n)}},onScroll:function(){this.winScroll=!1;var n=this.win.scrollTop(),e=n+this.winHeight,t=this.navBar.scrollTop()+(n-this.winPosition);n<0||e>this.docHeight||(this.navBar.scrollTop(t),this.winPosition=n)},onResize:function(){this.winResize=!1,this.winHeight=this.win.height(),this.docHeight=$(document).height()},hashChange:function(){this.linkScroll=!0,this.win.one("hashchange",(function(){this.linkScroll=!1}))},toggleCurrent:function(n){var e=n.closest("li");e.siblings("li.current").removeClass("current").attr("aria-expanded","false"),e.siblings().find("li.current").removeClass("current").attr("aria-expanded","false");var t=e.find("> ul li");t.length&&(t.removeClass("current").attr("aria-expanded","false"),e.toggleClass("current").attr("aria-expanded",(function(n,e){return"true"==e?"false":"true"})))}},"undefined"!=typeof window&&(window.SphinxRtdTheme={Navigation:n.exports.ThemeNav,StickyNav:n.exports.ThemeNav}),function(){for(var n=0,e=["ms","moz","webkit","o"],t=0;t0 + 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/docs/5.0.2/_static/minus.png b/docs/5.0.2/_static/minus.png new file mode 100644 index 00000000..d96755fd Binary files /dev/null and b/docs/5.0.2/_static/minus.png differ diff --git a/docs/5.0.2/_static/plus.png b/docs/5.0.2/_static/plus.png new file mode 100644 index 00000000..7107cec9 Binary files /dev/null and b/docs/5.0.2/_static/plus.png differ diff --git a/docs/5.0.2/_static/pygments.css b/docs/5.0.2/_static/pygments.css new file mode 100644 index 00000000..84ab3030 --- /dev/null +++ b/docs/5.0.2/_static/pygments.css @@ -0,0 +1,75 @@ +pre { line-height: 125%; } +td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +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: #3D7B7B; font-style: italic } /* Comment */ +.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .k { color: #008000; font-weight: bold } /* Keyword */ +.highlight .o { color: #666666 } /* Operator */ +.highlight .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */ +.highlight .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #9C6500 } /* Comment.Preproc */ +.highlight .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */ +.highlight .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */ +.highlight .gr { color: #E40000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #008400 } /* Generic.Inserted */ +.highlight .go { color: #717171 } /* Generic.Output */ +.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #0044DD } /* Generic.Traceback */ +.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #008000 } /* Keyword.Pseudo */ +.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #B00040 } /* Keyword.Type */ +.highlight .m { color: #666666 } /* Literal.Number */ +.highlight .s { color: #BA2121 } /* Literal.String */ +.highlight .na { color: #687822 } /* Name.Attribute */ +.highlight .nb { color: #008000 } /* Name.Builtin */ +.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */ +.highlight .no { color: #880000 } /* Name.Constant */ +.highlight .nd { color: #AA22FF } /* Name.Decorator */ +.highlight .ni { color: #717171; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #0000FF } /* Name.Function */ +.highlight .nl { color: #767600 } /* Name.Label */ +.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #19177C } /* Name.Variable */ +.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mb { color: #666666 } /* Literal.Number.Bin */ +.highlight .mf { color: #666666 } /* Literal.Number.Float */ +.highlight .mh { color: #666666 } /* Literal.Number.Hex */ +.highlight .mi { color: #666666 } /* Literal.Number.Integer */ +.highlight .mo { color: #666666 } /* Literal.Number.Oct */ +.highlight .sa { color: #BA2121 } /* Literal.String.Affix */ +.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */ +.highlight .sc { color: #BA2121 } /* Literal.String.Char */ +.highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */ +.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #BA2121 } /* Literal.String.Double */ +.highlight .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */ +.highlight .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */ +.highlight .sx { color: #008000 } /* Literal.String.Other */ +.highlight .sr { color: #A45A77 } /* Literal.String.Regex */ +.highlight .s1 { color: #BA2121 } /* Literal.String.Single */ +.highlight .ss { color: #19177C } /* Literal.String.Symbol */ +.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */ +.highlight .fm { color: #0000FF } /* Name.Function.Magic */ +.highlight .vc { color: #19177C } /* Name.Variable.Class */ +.highlight .vg { color: #19177C } /* Name.Variable.Global */ +.highlight .vi { color: #19177C } /* Name.Variable.Instance */ +.highlight .vm { color: #19177C } /* Name.Variable.Magic */ +.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/docs/5.0.2/_static/searchtools.js b/docs/5.0.2/_static/searchtools.js new file mode 100644 index 00000000..92da3f8b --- /dev/null +++ b/docs/5.0.2/_static/searchtools.js @@ -0,0 +1,619 @@ +/* + * searchtools.js + * ~~~~~~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for the full-text search. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"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] = 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, + }; +} + +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] = item; + + let listItem = document.createElement("li"); + 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 = _( + "Search finished, found ${resultCount} page(s) matching the search query." + ).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]. +// 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 [".headerlinks", "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.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]. + 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) { + let score = Math.round(100 * queryLower.length / title.length) + normalResults.push([ + docNames[file], + titles[file] !== title ? `${titles[file]} > ${title}` : title, + id !== null ? "#" + id : "", + null, + score, + filenames[file], + ]); + } + } + } + + // 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], + ]; + 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]], + ]); + }; + 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], + ]); + } + 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/docs/5.0.2/_static/sphinx_highlight.js b/docs/5.0.2/_static/sphinx_highlight.js new file mode 100644 index 00000000..8a96c69a --- /dev/null +++ b/docs/5.0.2/_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/docs/5.0.2/distinct_counting/cpc.html b/docs/5.0.2/distinct_counting/cpc.html new file mode 100644 index 00000000..6b7c53e3 --- /dev/null +++ b/docs/5.0.2/distinct_counting/cpc.html @@ -0,0 +1,270 @@ + + + + + + + Compressed Probabilistic Counting (CPC) — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Compressed Probabilistic Counting (CPC)

+

High performance C++ implementation of Compressed Probabilistic Counting (CPC) Sketch. +This is a unique-counting sketch that implements the Compressed Probabilistic Counting (CPC, a.k.a FM85) algorithms developed by Kevin Lang in his paper +Back to the Future: an Even More Nearly Optimal Cardinality Estimation Algorithm. +This sketch is extremely space-efficient when serialized. +In an apples-to-apples empirical comparison against compressed HyperLogLog sketches, this new algorithm simultaneously wins on the two dimensions of the space/accuracy tradeoff and produces sketches that are smaller than the entropy of HLL, so no possible implementation of compressed HLL can match its space efficiency for a given accuracy. As described in the paper this sketch implements a newly developed ICON estimator algorithm that survives unioning operations, another well-known estimator, the Historical Inverse Probability (HIP) estimator does not. +The update speed performance of this sketch is quite fast and is comparable to the speed of HLL. +The unioning (merging) capability of this sketch also allows for merging of sketches with different configurations of K. +For additional security this sketch can be configured with a user-specified hash seed.

+
+
+class cpc_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.cpc_sketch
+

Reads a bytes object and returns the corresponding cpc_sketch

+
+ +

Non-static Methods:

+
+
+__init__(self, lg_k: int = 11, seed: int = 9001) None
+

Creates a new CPC sketch

+
+
Parameters:
+
    +
  • lg_k (int, optional) – base 2 logarithm of the number of bins in the sketch

  • +
  • seed (int, optional) – seed value for the hash function

  • +
+
+
+
+ +
+
+get_estimate
+

Estimate of the distinct count of the input stream

+
+ +
+
+get_lower_bound
+

Returns an approximate lower bound on the estimate for kappa values in {1, 2, 3}, roughly corresponding to standard deviations

+
+ +
+
+get_upper_bound
+

Returns an approximate upper bound on the estimate for kappa values in {1, 2, 3}, roughly corresponding to standard deviations

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+property lg_k
+

Configured lg_k of this sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, datum: int) -> None

  2. +
+

Updates the sketch with the given 64-bit integer value

+
    +
  1. update(self, datum: float) -> None

  2. +
+

Updates the sketch with the given 64-bit floating point

+
    +
  1. update(self, datum: str) -> None

  2. +
+

Updates the sketch with the given string

+
+ +
+ +
+
+class cpc_union(*args, **kwargs)
+
+
+__init__(self, lg_k: int, seed: int = 9001) None
+
+ +
+
+get_result
+

Returns a CPC sketch with the result of the union

+
+ +
+
+update
+

Updates the union with the provided CPC sketch

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.2/distinct_counting/hyper_log_log.html b/docs/5.0.2/distinct_counting/hyper_log_log.html new file mode 100644 index 00000000..c28cf5e9 --- /dev/null +++ b/docs/5.0.2/distinct_counting/hyper_log_log.html @@ -0,0 +1,426 @@ + + + + + + + HyperLogLog (HLL) — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

HyperLogLog (HLL)

+

This is a high performance implementation of Phillipe Flajolet’s HLL sketch but with significantly improved error behavior.

+

If the ONLY use case for sketching is counting uniques and merging, the HLL sketch is a reasonable choice, although the highest performing in terms of accuracy for storage space consumed is CPC (Compressed Probabilistic Counting). For large enough counts, this HLL version (with HLL_4) can be 2 to 16 times smaller than the Theta sketch family for the same accuracy.

+

This implementation offers three different types of HLL sketch, each with different trade-offs with accuracy, space and performance. +These types are specified with the target_hll_type parameter.

+

In terms of accuracy, all three types, for the same lg_config_k, have the same error distribution as a function of n, the number of unique values fed to the sketch. +The configuration parameter lg_config_k is the log-base-2 of k, where k is the number of buckets or slots for the sketch.

+

During warmup, when the sketch has only received a small number of unique items (up to about 10% of k), this implementation leverages a new class of estimator algorithms with significantly better accuracy.

+
+
+class tgt_hll_type
+

Target HLL flavor

+
+
+HLL_4 : 4 bits per entry
+
+ +
+
+HLL_6 : 6 bits per entry
+
+ +
+
+HLL_8 : 8 bits per entry
+
+ +
+ +
+
+class hll_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.hll_sketch
+

Reads a bytes object and returns the corresponding hll_sketch

+
+ +
+
+get_max_updatable_serialization_bytes(lg_k: int, tgt_type: _datasketches.tgt_hll_type) int
+

Provides a likely upper bound on serialization size for the given parameters

+
+ +
+
+get_rel_err(upper_bound: bool, unioned: bool, lg_k: int, num_std_devs: int) float
+

Returns the a priori relative error bound for the given parameters

+
+ +

Non-static Methods:

+
+
+__init__(self, lg_k: int, tgt_type: _datasketches.tgt_hll_type = _datasketches.tgt_hll_type.HLL_8, start_max_size: bool = False) None
+

Constructs a new HLL sketch

+
+
Parameters:
+
    +
  • lg_config_k (int) – A full sketch can hold 2^lg_config_k rows. Must be between 7 and 21, inclusive,

  • +
  • tgt_type (tgt_hll_type) – The HLL mode to use, if/when the sketch reaches estimation mode

  • +
  • start_full_size (bool) – Indicates whether to start in HLL mode, keeping memory use constant (if HLL_6 or HLL_8) at the cost of much higher initial memory use. Default (and recommended) is False.

  • +
+
+
+
+ +
+
+get_compact_serialization_bytes
+

Returns the size of the serialized sketch when compressing the exception table if HLL_4

+
+ +
+
+get_estimate
+

Estimate of the distinct count of the input stream

+
+ +
+
+get_lower_bound
+

Returns the approximate lower error bound given the specified number of standard deviations in {1, 2, 3}

+
+ +
+
+get_updatable_serialization_bytes
+

Returns the size of the serialized sketch

+
+ +
+
+get_upper_bound
+

Returns the approximate upper error bound given the specified number of standard deviations in {1, 2, 3}

+
+ +
+
+is_compact
+

True if the sketch is compact, otherwise False

+
+ +
+
+is_empty
+

True if the sketch is empty, otherwise False

+
+ +
+
+property lg_config_k
+

Configured lg_k value for the sketch

+
+ +
+
+reset
+

Resets the sketch to the empty state in coupon collection mode

+
+ +
+
+serialize_compact
+

Serializes the sketch into a bytes object, compressing the exception table if HLL_4

+
+ +
+
+serialize_updatable
+

Serializes the sketch into a bytes object

+
+ +
+
+property tgt_type
+

The HLL type (4, 6, or 8) when in estimation mode

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, datum: int) -> None

  2. +
+

Updates the sketch with the given integral value

+
    +
  1. update(self, datum: float) -> None

  2. +
+

Updates the sketch with the given floating point value

+
    +
  1. update(self, datum: str) -> None

  2. +
+

Updates the sketch with the given string value

+
+ +
+ +
+
+class hll_union(*args, **kwargs)
+

Static Methods:

+
+
+get_rel_err(upper_bound: bool, unioned: bool, lg_k: int, num_std_devs: int) float
+

Returns the a priori relative error bound for the given parameters

+
+ +

Non-static Methods:

+
+
+__init__(self, lg_max_k: int) None
+

Construct an hll_union object if the given size.

+
+
Parameters:
+

lg_max_k (int) – The maximum size, in log2, of k. Must be between 7 and 21, inclusive.

+
+
+
+ +
+
+get_estimate
+

Estimate of the distinct count of the input stream

+
+ +
+
+get_lower_bound
+

Returns the approximate lower error bound given the specified number of standard deviations in {1, 2, 3}

+
+ +
+
+get_result
+

Returns a sketch of the target type representing the current union state

+
+ +
+
+get_upper_bound
+

Returns the approximate upper error bound given the specified number of standard deviations in {1, 2, 3}

+
+ +
+
+is_empty
+

True if the union is empty, otherwise False

+
+ +
+
+property lg_config_k
+

Configured lg_k value for the union

+
+ +
+
+reset
+

Resets the union to the empty state

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, sketch: _datasketches.hll_sketch) -> None

  2. +
+

Updates the union with the given HLL sketch

+
    +
  1. update(self, datum: int) -> None

  2. +
+

Updates the union with the given integral value

+
    +
  1. update(self, datum: float) -> None

  2. +
+

Updates the union with the given floating point value

+
    +
  1. update(self, datum: str) -> None

  2. +
+

Updates the union with the given string value

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.2/distinct_counting/index.html b/docs/5.0.2/distinct_counting/index.html new file mode 100644 index 00000000..e75799a9 --- /dev/null +++ b/docs/5.0.2/distinct_counting/index.html @@ -0,0 +1,152 @@ + + + + + + + Distinct Counting — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Distinct Counting

+

Distinct counting is one of the earliest tasks to which sketches were applied. The concept is simple: +Provide an estimate of the number of unique elements in a set of data. One of the earliest solutions came +from Flajolet and Martin in 1985 with their seminal work +Probabilistic counting Algorithms for Data Base Applications.

+

The DataSketches library offers several types of distinct counting sketches, each with different properties.

+
+
    +
  • hll_sketch: Hyper Log Log, a well-known sketch for distinct counting but no longer state-of-the-art.

  • +
  • cpc_sketch: Provides a better accuracy-space trade-off than HLL, but with a somewhat larger footprint while in-memory.

  • +
  • theta_sketch: Theta sketch, a type of k-minimum value sketch, which provide good performance with intersection and set difference operations.

  • +
  • tuple_sketch: Tuple sketch, which is similar to a theta sketch but supports additional data stored with each key.

  • +
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.2/distinct_counting/theta.html b/docs/5.0.2/distinct_counting/theta.html new file mode 100644 index 00000000..71610cc4 --- /dev/null +++ b/docs/5.0.2/distinct_counting/theta.html @@ -0,0 +1,440 @@ + + + + + + + Theta Sketch — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Theta Sketch

+

Theta sketches are used for distinct counting.

+

The theta package contains the basic sketch classes that are members of the Theta Sketch Framework. +There is a separate Tuple package for many of the sketches that are derived from the same algorithms defined in the Theta Sketch Framework paper.

+

The Theta Sketch sketch is a space-efficient method for estimating cardinalities of sets. +It can also easily handle set operations (such as union, intersection, difference) while maintaining good accuracy. +Theta sketch is a practical variant of the K-Minimum Values sketch which avoids the need to sort the stored +hash values on every insertion to the sketch. +It has better error properties than the HyperLogLog sketch for set operations beyond the simple union.

+

Set operations (union, intersection, A-not-B) are performed through the use of dedicated objects.

+

Several Jaccard similarity +measures can be computed between theta sketches with the theta_jaccard_similarity class.

+
+
+class theta_sketch
+

An abstract base class for theta sketches

+
+
+get_estimate
+

Estimate of the distinct count of the input stream

+
+ +
+
+get_lower_bound
+

Returns an approximate lower bound on the estimate at standard deviations in {1, 2, 3}

+
+ +
+
+get_seed_hash
+

Returns a hash of the seed used in the sketch

+
+ +
+
+get_upper_bound
+

Returns an approximate upper bound on the estimate at standard deviations in {1, 2, 3}

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if sketch is in estimation mode, otherwise False

+
+ +
+
+is_ordered
+

Returns True if the sketch entries are sorted, otherwise False

+
+ +
+
+property num_retained
+

The number of items currently in the sketch

+
+ +
+
+property theta
+

Theta (effective sampling rate) as a fraction from 0 to 1

+
+ +
+
+property theta64
+

Theta as 64-bit value

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+ +
+
+class update_theta_sketch(*args, **kwargs)
+
+
+__init__(self, lg_k: int = 12, p: float = 1.0, seed: int = 9001) None
+

Creates an update_theta_sketch using the provided parameters

+
+
Parameters:
+
    +
  • lg_k (int, optional) – base 2 logarithm of the maximum size of the sketch. Default 12.

  • +
  • p (float, optional) – an initial sampling rate to use. Default 1.0

  • +
  • seed (int, optional) – the seed to use when hashing values

  • +
+
+
+
+ +
+
+compact
+

Returns a compacted form of the sketch, optionally sorting it

+
+ +
+
+reset
+

Resets the sketch to the initial empty state

+
+ +
+
+trim
+

Removes retained entries in excess of the nominal size k (if any)

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, datum: int) -> None

  2. +
+

Updates the sketch with the given integral value

+
    +
  1. update(self, datum: float) -> None

  2. +
+

Updates the sketch with the given floating point value

+
    +
  1. update(self, datum: str) -> None

  2. +
+

Updates the sketch with the given string

+
+ +
+ +
+
+class compact_theta_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, seed: int = 9001) _datasketches.compact_theta_sketch
+

Reads a bytes object and returns the corresponding compact_theta_sketch

+
+ +

Non-static Methods:

+
+
+__init__(self, arg0: _datasketches.theta_sketch, arg1: bool, /) None
+

Creates a compact_theta_sketch from an existing theta_sketch.

+
+
Parameters:
+
    +
  • other (theta_sketch) – a source theta_sketch

  • +
  • ordered (bool) – whether the incoming sketch entries are sorted. Default True

  • +
+
+
+
+ +
+
+serialize
+

Serializes the sketch into a bytes object

+
+ +
+ +
+
+class theta_union(*args, **kwargs)
+
+
+__init__(self, lg_k: int = 12, p: float = 1.0, seed: int = 9001) None
+

Creates a theta_union using the provided parameters

+
+
Parameters:
+
    +
  • lg_k (int, optional) – base 2 logarithm of the maximum size of the union. Default 12.

  • +
  • p (float, optional) – an initial sampling rate to use. Default 1.0

  • +
  • seed (int, optional) – the seed to use when hashing values. Must match all sketch seeds.

  • +
+
+
+
+ +
+
+get_result
+

Returns the sketch corresponding to the union result

+
+ +
+
+update
+

Updates the union with the given sketch

+
+ +
+ +
+
+class theta_intersection(*args, **kwargs)
+
+
+__init__(self, seed: int = 9001) None
+

Creates a theta_intersection using the provided parameters

+
+
Parameters:
+

seed (int, optional) – the seed to use when hashing values. Must match all sketch seeds

+
+
+
+ +
+
+get_result
+

Returns the sketch corresponding to the intersection result

+
+ +
+
+has_result
+

Returns True if the intersection has a valid result, otherwise False

+
+ +
+
+update
+

Intersections the provided sketch with the current intersection state

+
+ +
+ +
+
+class theta_a_not_b(*args, **kwargs)
+
+
+__init__(self, seed: int = 9001) None
+

Creates a tuple_a_not_b object

+
+
Parameters:
+

seed (int, optional) – the seed to use when hashing values. Must match all sketch seeds.

+
+
+
+ +
+
+compute
+

Returns a sketch with the result of applying the A-not-B operation on the given inputs

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.2/distinct_counting/tuple.html b/docs/5.0.2/distinct_counting/tuple.html new file mode 100644 index 00000000..48bcfd61 --- /dev/null +++ b/docs/5.0.2/distinct_counting/tuple.html @@ -0,0 +1,478 @@ + + + + + + + Tuple Sketch — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Tuple Sketch

+

Tuple sketches are an extension of Theta sketches, meaning they provide estimate of distinct counts, that +allow the keeping of arbitrary summaries associated with each retained key +(for example, a count for every key). The use of a tuple_sketch requires a TuplePolicy which +defines how summaries are created, updated, merged, or intersected. The library provides a few basic +examples of TuplePolicy implementations, but the right custom summary and policy can allow very +complicated analysis to be performed quite easily.

+

Set operations (union, intersection, A-not-B) are performed through the use of dedicated objects.

+

Several Jaccard similarity +measures can be computed between theta sketches with the tuple_jaccard_similarity class.

+
+

Note

+

Serializing and deserializing this sketch requires the use of a PyObjectSerDe.

+
+
+
+class tuple_sketch
+

An abstract base class for tuple sketches.

+
+
+DEFAULT_SEED = 9001
+
+ +
+
+get_estimate
+

Estimate of the distinct count of the input stream

+
+ +
+
+get_lower_bound
+

Returns an approximate lower bound on the estimate at standard deviations in {1, 2, 3}

+
+ +
+
+get_seed_hash
+

Returns a hash of the seed used in the sketch

+
+ +
+
+get_upper_bound
+

Returns an approximate upper bound on the estimate at standard deviations in {1, 2, 3}

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if sketch is in estimation mode, otherwise False

+
+ +
+
+is_ordered
+

Returns True if the sketch entries are sorted, otherwise False

+
+ +
+
+property num_retained
+

The number of items currently in the sketch

+
+ +
+
+property theta
+

Theta (effective sampling rate) as a fraction from 0 to 1

+
+ +
+
+property theta64
+

Theta as 64-bit value

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+ +
+
+class update_tuple_sketch(*args, **kwargs)
+
+
+__init__(self, policy: _datasketches.TuplePolicy, lg_k: int = 12, p: float = 1.0, seed: int = 9001) None
+

Creates an update_tuple_sketch using the provided parameters

+
+
Parameters:
+
    +
  • policy (TuplePolicy) – a policy to use when updating

  • +
  • lg_k (int, optional) – base 2 logarithm of the maximum size of the sketch. Default 12.

  • +
  • p (float, optional) – an initial sampling rate to use. Default 1.0

  • +
  • seed (int, optional) – the seed to use when hashing values

  • +
+
+
+
+ +
+
+compact
+

Returns a compacted form of the sketch, optionally sorting it

+
+ +
+
+reset
+

Resets the sketch to the initial empty state

+
+ +
+
+trim
+

Removes retained entries in excess of the nominal size k (if any)

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, datum: int, value: object) -> None

  2. +
+

Updates the sketch with the given integral item and summary value

+
    +
  1. update(self, datum: float, value: object) -> None

  2. +
+

Updates the sketch with the given floating point item and summary value

+
    +
  1. update(self, datum: str, value: object) -> None

  2. +
+

Updates the sketch with the given string item and summary value

+
+ +
+ +
+
+class compact_tuple_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe, seed: int = 9001) _datasketches.compact_tuple_sketch
+

Reads a bytes object and returns the corresponding compact_tuple_sketch

+
+ +

Non-static Methods:

+
+
+__init__(self, other: _datasketches.tuple_sketch, ordered: bool = True) None
+
+__init__(self, other: _datasketches.theta_sketch, summary: object) None
+

Overloaded function.

+
    +
  1. __init__(self, other: _datasketches.tuple_sketch, ordered: bool = True) -> None

  2. +
+

Creates a compact_tuple_sketch from an existing tuple_sketch.

+
+
Parameters:
+
    +
  • other (tuple_sketch) – a sourch tuple_sketch

  • +
  • ordered (bool, optional) – whether the incoming sketch entries are sorted. Default True

  • +
+
+
+
    +
  1. __init__(self, other: _datasketches.theta_sketch, summary: object) -> None

  2. +
+

Creates a compact_tuple_sketch from a theta_sketch using a fixed summary value.

+
+
Parameters:
+
    +
  • other (theta_sketch) – a source theta sketch

  • +
  • summary (object) – a summary to use for every sketch entry

  • +
+
+
+
+ +
+
+serialize
+

Serializes the sketch into a bytes object

+
+ +
+ +
+
+class tuple_union(*args, **kwargs)
+
+
+__init__(self, policy: _datasketches.TuplePolicy, lg_k: int = 12, p: float = 1.0, seed: int = 9001) None
+

Creates a tuple_union using the provided parameters

+
+
Parameters:
+
    +
  • policy (TuplePolicy) – a policy to use when unioning entries

  • +
  • lg_k (int, optional) – base 2 logarithm of the maximum size of the union. Default 12.

  • +
  • p (float, optional) – an initial sampling rate to use. Default 1.0

  • +
  • seed (int, optional) – the seed to use when hashing values. Must match any sketch seeds.

  • +
+
+
+
+ +
+
+get_result
+

Returns the sketch corresponding to the union result

+
+ +
+
+reset
+

Resets the sketch to the initial empty

+
+ +
+
+update
+

Updates the union with the given sketch

+
+ +
+ +
+
+class tuple_intersection(*args, **kwargs)
+
+
+__init__(self, policy: _datasketches.TuplePolicy, seed: int = 9001) None
+

Creates a tuple_intersection using the provided parameters

+
+
Parameters:
+
    +
  • policy (TuplePolicy) – a policy to use when intersecting entries

  • +
  • seed (int, optional) – the seed to use when hashing values. Must match any sketch seeds

  • +
+
+
+
+ +
+
+get_result
+

Returns the sketch corresponding to the intersection result

+
+ +
+
+has_result
+

Returns True if the intersection has a valid result, otherwise False

+
+ +
+
+update
+

Intersects the provided sketch with the current intersection state

+
+ +
+ +
+
+class tuple_a_not_b(*args, **kwargs)
+
+
+__init__(self, seed: int = 9001) None
+

Creates a tuple_a_not_b object

+
+
Parameters:
+

seed (int, optional) – the seed to use when hashing values. Must match any sketch seeds.

+
+
+
+ +
+
+compute
+

Returns a sketch with the result of applying the A-not-B operation on the given inputs

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.2/frequency/count_min_sketch.html b/docs/5.0.2/frequency/count_min_sketch.html new file mode 100644 index 00000000..c6a8e366 --- /dev/null +++ b/docs/5.0.2/frequency/count_min_sketch.html @@ -0,0 +1,303 @@ + + + + + + + CountMin Sketch — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

CountMin Sketch

+

The CountMin sketch, as described in Cormode and Muthukrishnan in +http://dimacs.rutgers.edu/~graham/pubs/papers/cm-full.pdf, +is used for approximate Frequency Estimation. +For an item \(x\) with frequency \(f_x\), the sketch provides an estimate, \(\hat{f_x}\), +such that \(f_x \approx \hat{f_x}.\) +The sketch guarantees that \(f_x \le \hat{f_x}\) and provides a probabilistic upper bound which is dependent on the size parameters. +The sketch provides an estimate of the occurrence frequency for any queried item but, in contrast +to the Frequent Items Sketch, this sketch does not provide a list of +heavy hitters.

+
+
+class count_min_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.count_min_sketch
+

Reads a bytes object and returns the corresponding count_min_sketch

+
+ +
+
+suggest_num_buckets(relative_error: float) int
+

Suggests the number of buckets needed to achieve an accuracy within the provided relative_error. For example, when relative_error = 0.05, the returned frequency estimates satisfy the ‘relative_error’ guarantee that never overestimates the weights but may underestimate the weights by 5% of the total weight in the sketch. Returns the number of hash buckets at every level of the sketch required in order to obtain the specified relative error.

+
+ +
+
+suggest_num_hashes(confidence: float) int
+

Suggests the number of hashes needed to achieve the provided confidence. For example, with 95% confidence, frequency estimates satisfy the ‘relative_error’ guarantee. Returns the number of hash functions that are required in order to achieve the specified confidence of the sketch. confidence = 1 - delta, with delta denoting the sketch failure probability.

+
+ +

Non-static Methods:

+
+
+get_estimate
+

Overloaded function.

+
    +
  1. get_estimate(self, item: int) -> float

  2. +
+

Returns an estimate of the frequency of the provided 64-bit integer value

+
    +
  1. get_estimate(self, item: str) -> float

  2. +
+

Returns an estimate of the frequency of the provided string

+
+ +
+
+get_lower_bound
+

Overloaded function.

+
    +
  1. get_lower_bound(self, item: int) -> float

  2. +
+

Returns a lower bound on the estimate for the given 64-bit integer value

+
    +
  1. get_lower_bound(self, item: str) -> float

  2. +
+

Returns a lower bound on the estimate for the provided string

+
+ +
+
+get_relative_error
+

Returns the maximum permissible error for any frequency estimate query

+
+ +
+
+get_serialized_size_bytes
+

Returns the size in bytes of the serialized image of the sketch

+
+ +
+
+get_upper_bound
+

Overloaded function.

+
    +
  1. get_upper_bound(self, item: int) -> float

  2. +
+

Returns an upper bound on the estimate for the given 64-bit integer value

+
    +
  1. get_upper_bound(self, item: str) -> float

  2. +
+

Returns an upper bound on the estimate for the provided string

+
+ +
+
+is_empty
+

Returns True if the sketch has seen no items, otherwise False

+
+ +
+
+merge
+

Merges the provided other sketch into this one

+
+ +
+
+property num_buckets
+

The configured number of buckets for the sketch

+
+ +
+
+property num_hashes
+

The configured number of hashes for the sketch

+
+ +
+
+property seed
+

The base hash seed for the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+property total_weight
+

The total weight currently inserted into the stream

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: int, weight: float = 1.0) -> None

  2. +
+

Updates the sketch with the given 64-bit integer value

+
    +
  1. update(self, item: str, weight: float = 1.0) -> None

  2. +
+

Updates the sketch with the given string

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.2/frequency/frequent_items.html b/docs/5.0.2/frequency/frequent_items.html new file mode 100644 index 00000000..3b70f66c --- /dev/null +++ b/docs/5.0.2/frequency/frequent_items.html @@ -0,0 +1,479 @@ + + + + + + + Frequent Items — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Frequent Items

+

This sketch is useful for tracking approximate frequencies of items (object or string) with optional associated +integer counts that are members of a multiset of such items. +The true frequency of an item is defined to be the sum of associated counts.

+

This implementation provides the following capabilities:

+
    +
  • Estimate the frequency of an item.

  • +
  • Return upper and lower bounds of any item, such that the true frequency is always between the upper and lower bounds.

  • +
  • Return a global maximum error that holds for all items in the stream.

  • +
  • Return an array of frequent items that qualify either a NO_FALSE_POSITIVES or a NO_FALSE_NEGATIVES error type.

  • +
  • Merge itself with another sketch object created from this class.

  • +
  • Serialize/Deserialize to/from a byte array.

  • +
+

Space Usage

+

The sketch is initialized with a maximum map size, maxMapSize, that specifies the maximum physical length of the internal hash map of the form (object item, int count). +The maximum map size is always a power of 2, defined through the variables lg_max_map_size.

+

The hash map starts at a very small size (8 entries) and grows as needed up to the specified maximum map size.

+

Excluding external space required for the item objects, the internal memory space usage of this sketch is 18 * mapSize bytes (assuming 8 bytes for each reference), +plus a small constant number of additional bytes. +The internal memory space usage of this sketch will never exceed 18 * maxMapSize bytes, plus a small constant number of additional bytes.

+

Maximum Capacity of the Sketch

+

The LOAD_FACTOR for the hash map is internally set at \(75\%\), which means at any time the map capacity of (item, count) pairs is mapCap = 0.75 * mapSize. +The maximum capacity of (item, count) pairs of the sketch is maxMapCap = 0.75 * maxMapSize.

+

Updating the sketch with ``(item, count)`` pairs

+

If the item is found in the hash map, the mapped count field (the “counter”) is incremented by the incoming count; otherwise, a new counter (item, count) pair is created. +If the number of tracked counters reaches the maximum capacity of the hash map, the sketch decrements all of the counters (by an approximately computed median) +and removes any non-positive counters.

+

Accuracy

+

If fewer than 0.75 * maxMapSize different items are inserted into the sketch, the estimated frequencies returned by the sketch will be exact.

+

The logic of the frequent items sketch is such that the stored counts and true counts are never too different. +More specifically, for any item, the sketch can return an estimate of the true frequency of item, along with upper and lower bounds on the frequency (that hold deterministically).

+

For this implementation and for a specific active item, it is guaranteed that the true frequency will be between the Upper Bound (UB) and the Lower Bound (LB) computed for that item. +Specifically, (UB- LB) W * epsilon, where \(W\) denotes the sum of all item counts, and \(epsilon = 3.5/M\), where \(epsilon = M\) is the maxMapSize.

+

This is a worst-case guarantee that applies to arbitrary inputs. +For inputs typically seen in practice, (UB-LB) is usually much smaller.

+

Background

+

This code implements a variant of what is commonly known as the “Misra-Gries algorithm”. +Variants of it were discovered and rediscovered and redesigned several times over the years:

+
    +
  • Finding repeated elements, Misra, Gries, 1982

  • +
  • Frequency estimation of Internet packet streams with limited space Demaine, Lopez-Ortiz, Munro, 2002

  • +
  • A simple algorithm for finding frequent elements in streams and bags Karp, Shenker, Papadimitriou, 2003

  • +
  • Efficient Computation of Frequent and Top-k Elements in Data Streams Metwally, Agrawal, Abbadi, 2006

  • +
+

For speed, we do employ some randomization that introduces a small probability that our proof of the worst-case bound might not apply to a given run. +However, we have ensured that this probability is extremely small. +For example, if the stream causes one table purge (rebuild), our proof of the worst-case bound applies with a probability of at least 1 - 1E-14. +If the stream causes 1E9 purges, our proof applies with a probability of at least 1 - 1E-5.

+

There are two flavors of Frequent Items Sketches, one with generic items (objects) and another specific to strings. +The string version is a legacy name from before the library supported generic objects and is retained +only for backwards compatibility.

+
+

Note

+

The frequent_items_sketch uses an input object’s __hash__ and __eq__ methods.

+
+
+

Note

+

Serializing and deserializing the frequent_items_sketch requires the use of a PyObjectSerDe.

+
+
+
+class frequent_items_error_type
+
+
+NO_FALSE_POSITIVES : Returns only true positives but may miss some heavy hitters.
+
+ +
+
+NO_FALSE_NEGATIVES : Does not miss any heavy hitters but may return false positives.
+
+ +
+ +
+
+class frequent_items_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe) _datasketches.frequent_items_sketch
+

Reads a bytes object using the provided serde and returns the corresponding frequent_strings_sketch.

+
+ +
+
+get_epsilon_for_lg_size(lg_max_map_size: int) float
+

Returns the epsilon value used to compute a priori error for a given log2(max_map_size)

+
+ +
+
+get_apriori_error(lg_max_map_size: int, estimated_total_weight: int) float
+

Returns the estimated a priori error given the max_map_size for the sketch and the estimated_total_stream_weight.

+
+ +

Non-static Methods:

+
+
+__init__(self, lg_max_k: int) None
+

Creates an instance of the sketch

+
+
Parameters:
+

lg_max_k (int) – base 2 logarithm of the maximum size of the internal hash map of the sketch. Maximum capacity is 0.75 of this value, which is the maximum number of distinct items the sketch can contain.

+
+
+
+ +
+
+property epsilon
+

The epsilon value used by the sketch to compute error

+
+ +
+
+get_estimate
+

Returns the estimate of the weight (frequency) of the given item. +Note: The true frequency of a item would be the sum of the counts as a result of the two update functions.

+
+ +
+
+get_frequent_items
+
+ +
+
+get_lower_bound
+

Returns the guaranteed lower bound weight (frequency) of the given item.

+
+ +
+
+get_serialized_size_bytes
+

Computes the size needed to serialize the current state of the sketch using the provided serde. This can be expensive since every item needs to be looked at.

+
+ +
+
+get_upper_bound
+

Returns the guaranteed upper bound weight (frequency) of the given item.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+merge
+

Merges the given sketch into this one

+
+ +
+
+property num_active_items
+

The number of active items in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object using the provided serde.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+property total_weight
+

The sum of the weights (frequencies) in the stream seen so far by the sketch

+
+ +
+
+update
+

Updates the sketch with the given string and, optionally, a weight

+
+ +
+ +
+
+class frequent_strings_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.frequent_strings_sketch
+

Reads a bytes object and returns the corresponding frequent_strings_sketch.

+
+ +
+
+get_epsilon_for_lg_size(lg_max_map_size: int) float
+

Returns the epsilon value used to compute a priori error for a given log2(max_map_size)

+
+ +
+
+get_apriori_error(lg_max_map_size: int, estimated_total_weight: int) float
+

Returns the estimated a priori error given the max_map_size for the sketch and the estimated_total_stream_weight.

+
+ +

Non-static Methods:

+
+
+__init__(self, lg_max_k: int) None
+

Creates an instance of the sketch

+
+
Parameters:
+

lg_max_k (int) – base 2 logarithm of the maximum size of the internal hash map of the sketch. Maximum capacity is 0.75 of this value, which is the maximum number of distinct items the sketch can contain.

+
+
+
+ +
+
+property epsilon
+

The epsilon value used by the sketch to compute error

+
+ +
+
+get_estimate
+

Returns the estimate of the weight (frequency) of the given item. +Note: The true frequency of a item would be the sum of the counts as a result of the two update functions.

+
+ +
+
+get_frequent_items
+
+ +
+
+get_lower_bound
+

Returns the guaranteed lower bound weight (frequency) of the given item.

+
+ +
+
+get_serialized_size_bytes
+

Computes the size needed to serialize the current state of the sketch. This can be expensive since every item needs to be looked at.

+
+ +
+
+get_upper_bound
+

Returns the guaranteed upper bound weight (frequency) of the given item.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+merge
+

Merges the given sketch into this one

+
+ +
+
+property num_active_items
+

The number of active items in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+property total_weight
+

The sum of the weights (frequencies) in the stream seen so far by the sketch

+
+ +
+
+update
+

Updates the sketch with the given string and, optionally, a weight

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.2/frequency/index.html b/docs/5.0.2/frequency/index.html new file mode 100644 index 00000000..99bd3d37 --- /dev/null +++ b/docs/5.0.2/frequency/index.html @@ -0,0 +1,145 @@ + + + + + + + Frequency Sketches — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Frequency Sketches

+

Frequency estimation involves determining how often an item has been seen in a stream. The library currently +offers two types of sketches for frequency estimation, one of which has two closely-related variants.

+
+
    +
  • frequent_items_sketch: Identifies the Top K or heavy hitters in a stream, those items whose weight is above a certain percentage of the entire stream. Does not necessarily provide an estimate for most items outside the heavy hitters.

  • +
  • frequent_strings_sketch: Like the items version but containing snly strings (an implementation from before the library handled generic objects).

  • +
  • count_min_sketch: Provides an estimate for any item, regardless of relative weight, but does not maintain a list of the heaviest items.

  • +
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.2/genindex.html b/docs/5.0.2/genindex.html new file mode 100644 index 00000000..6dbd7d3a --- /dev/null +++ b/docs/5.0.2/genindex.html @@ -0,0 +1,1384 @@ + + + + + + Index — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ + +

Index

+ +
+ _ + | A + | C + | D + | E + | F + | G + | H + | I + | J + | K + | L + | M + | N + | P + | Q + | R + | S + | T + | U + | V + +
+

_

+ + +
+ +

A

+ + +
+ +

C

+ + + +
+ +

D

+ + + +
+ +

E

+ + + +
+ +

F

+ + + +
+ +

G

+ + + +
+ +

H

+ + + +
+ +

I

+ + + +
+ +

J

+ + +
+ +

K

+ + + +
+ +

L

+ + + +
+ +

M

+ + + +
+ +

N

+ + + +
+ +

P

+ + + +
+ +

Q

+ + + +
+ +

R

+ + +
+ +

S

+ + + +
+ +

T

+ + + +
+ +

U

+ + + +
+ +

V

+ + + +
+ + + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.2/helper/index.html b/docs/5.0.2/helper/index.html new file mode 100644 index 00000000..d977f1ec --- /dev/null +++ b/docs/5.0.2/helper/index.html @@ -0,0 +1,154 @@ + + + + + + + Helper Classes — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Helper Classes

+

These classes are required for certain sketches or specific +functionality within sketches. +Some of them are abstract base classes, but in those cases there is at +least one reference example of a concrete class.

+
+
    +
  • serde is used when serializing and deserializing sketches.

  • +
  • jaccard is used to compute the Jaccard similarity between pairs of theta or tuple sketches.

  • +
  • tuple_policy is required to use a tuple_sketch by specifying how summaries are combined.

  • +
  • ks_test() performs a Kolmogorov-Smirnov test on absolute-error quantiles family sketches.

  • +
  • kernel_function is required when using a kernel_sketch for Kernel Density Estimation.

  • +
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.2/helper/jaccard.html b/docs/5.0.2/helper/jaccard.html new file mode 100644 index 00000000..b66dbf01 --- /dev/null +++ b/docs/5.0.2/helper/jaccard.html @@ -0,0 +1,212 @@ + + + + + + + Jaccard Similarity — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Jaccard Similarity

+

These objects provide measures related to the Jaccard similarity +of theta_sketch and tuple_sketch objects.

+

Note that there are separate classes to be used for theta and tuple sketches.

+
+
+class theta_jaccard_similarity
+

An object to help compute Jaccard similarity between theta sketches.

+
+
+jaccard(sketch_a: _datasketches.theta_sketch, sketch_b: _datasketches.theta_sketch, seed: int = 9001) list[float]
+

Returns a list with {lower_bound, estimate, upper_bound} of the Jaccard similarity between sketches

+
+ +
+
+exactly_equal(sketch_a: _datasketches.theta_sketch, sketch_b: _datasketches.theta_sketch, seed: int = 9001) bool
+

Returns True if sketch_a and sketch_b are equivalent, otherwise False

+
+ +
+
+similarity_test(actual: _datasketches.theta_sketch, expected: _datasketches.theta_sketch, threshold: float, seed: int = 9001) bool
+

Tests similarity of an actual sketch against an expected sketch. Computers the lower bound of the Jaccard index J_{LB} of the actual and expected sketches. If J_{LB} >= threshold, then the sketches are considered to be similar with a confidence of 97.7% and returns True, otherwise False.

+
+ +
+
+dissimilarity_test(actual: _datasketches.theta_sketch, expected: _datasketches.theta_sketch, threshold: float, seed: int = 9001) bool
+

Tests dissimilarity of an actual sketch against an expected sketch. Computers the lower bound of the Jaccard index J_{UB} of the actual and expected sketches. If J_{UB} <= threshold, then the sketches are considered to be dissimilar with a confidence of 97.7% and returns True, otherwise False.

+
+ +
+ +
+
+class tuple_jaccard_similarity
+

An object to help compute Jaccard similarity between tuple sketches.

+
+
+jaccard(sketch_a: _datasketches.tuple_sketch, sketch_b: _datasketches.tuple_sketch, seed: int = 9001) list[float]
+

Returns a list with {lower_bound, estimate, upper_bound} of the Jaccard similarity between sketches

+
+ +
+
+exactly_equal(sketch_a: _datasketches.tuple_sketch, sketch_b: _datasketches.tuple_sketch, seed: int = 9001) bool
+

Returns True if sketch_a and sketch_b are equivalent, otherwise False

+
+ +
+
+similarity_test(actual: _datasketches.tuple_sketch, expected: _datasketches.tuple_sketch, threshold: float, seed: int = 9001) bool
+

Tests similarity of an actual sketch against an expected sketch. Computes the lower bound of the Jaccard index J_{LB} of the actual and expected sketches. If J_{LB} >= threshold, then the sketches are considered to be similar with a confidence of 97.7% and returns True, otherwise False.

+
+ +
+
+dissimilarity_test(actual: _datasketches.tuple_sketch, expected: _datasketches.tuple_sketch, threshold: float, seed: int = 9001) bool
+

Tests dissimilarity of an actual sketch against an expected sketch. Computes the upper bound of the Jaccard index J_{UB} of the actual and expected sketches. If J_{UB} <= threshold, then the sketches are considered to be dissimilar with a confidence of 97.7% and returns True, otherwise False.

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.2/helper/kernel.html b/docs/5.0.2/helper/kernel.html new file mode 100644 index 00000000..a2a61177 --- /dev/null +++ b/docs/5.0.2/helper/kernel.html @@ -0,0 +1,184 @@ + + + + + + + Kernel Function — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Kernel Function

+

A kernel function is a specific type of +mathematical funciton that is particularly useful in certain machine learning and pattern recognition +contexts. The density_sketch performs approximate +kernel density estimation which, unsurprisingly, +relies on the use of such a kernel function.

+

The library provides an abstract base class KernelFunction and an example implementation of a +Gaussian (also known as a Radial Basis Function) kernel. Custom classes must override the base class +and provide a floating point value as a score indicating the similarity of two input vectors.

+
+
+class KernelFunction(*args, **kwargs)
+

A generic base class from which user-defined kernels must inherit.

+
+
+__call__(self, a: object, b: object) float
+

A method to evaluate a kernel with given inputs a and b.

+
+
Parameters:
+
    +
  • a (numpy array) – An input vector

  • +
  • b (numpy array) – An input vector

  • +
+
+
Returns:
+

A vector similarity score

+
+
Return type:
+

float

+
+
+
+ +
+ +
+
+class GaussianKernel(bandwidth: float = 1.0)
+

Bases: KernelFunction

+

Implements a basic Gaussian kernel

+
+
Parameters:
+

bandwidth (float) – The kernel bandwidth, default 1.0

+
+
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.2/helper/ks_test.html b/docs/5.0.2/helper/ks_test.html new file mode 100644 index 00000000..721be0a5 --- /dev/null +++ b/docs/5.0.2/helper/ks_test.html @@ -0,0 +1,210 @@ + + + + + + + Kolmogorov-Smirnov Test — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Kolmogorov-Smirnov Test

+

A Kolmogorov-Smirnov Test <https://en.wikipedia.org/wiki/Kolmogorov%E2%80%93Smirnov_test>`_ is +a test of equality of two distributions to determine if they are likely to have come from the same +underlying distribution. +The DataSketches library provides a modified form of the test that takes into account the error +in each underlying sketch in the analysis.

+

Currently, the test assumes both input sketches are of the same family and data type.

+
+
+ks_test(sk_1: _datasketches.kll_ints_sketch, sk_2: _datasketches.kll_ints_sketch, p: float) bool
+
+ks_test(sk_1: _datasketches.kll_floats_sketch, sk_2: _datasketches.kll_floats_sketch, p: float) bool
+
+ks_test(sk_1: _datasketches.kll_doubles_sketch, sk_2: _datasketches.kll_doubles_sketch, p: float) bool
+
+ks_test(sk_1: _datasketches.kll_items_sketch, sk_2: _datasketches.kll_items_sketch, p: float) bool
+
+ks_test(sk_1: _datasketches.quantiles_ints_sketch, sk_2: _datasketches.quantiles_ints_sketch, p: float) bool
+
+ks_test(sk_1: _datasketches.quantiles_floats_sketch, sk_2: _datasketches.quantiles_floats_sketch, p: float) bool
+
+ks_test(sk_1: _datasketches.quantiles_doubles_sketch, sk_2: _datasketches.quantiles_doubles_sketch, p: float) bool
+
+ks_test(sk_1: _datasketches.quantiles_items_sketch, sk_2: _datasketches.quantiles_items_sketch, p: float) bool
+

Overloaded function.

+
    +
  1. ks_test(sk_1: _datasketches.kll_ints_sketch, sk_2: _datasketches.kll_ints_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for kll_ints_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
    +
  1. ks_test(sk_1: _datasketches.kll_floats_sketch, sk_2: _datasketches.kll_floats_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for kll_floats_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
    +
  1. ks_test(sk_1: _datasketches.kll_doubles_sketch, sk_2: _datasketches.kll_doubles_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for kll_doubles_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
    +
  1. ks_test(sk_1: _datasketches.kll_items_sketch, sk_2: _datasketches.kll_items_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for kll_items_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
    +
  1. ks_test(sk_1: _datasketches.quantiles_ints_sketch, sk_2: _datasketches.quantiles_ints_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for quantiles_ints_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
    +
  1. ks_test(sk_1: _datasketches.quantiles_floats_sketch, sk_2: _datasketches.quantiles_floats_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for quantiles_floats_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +:Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
    +
  1. ks_test(sk_1: _datasketches.quantiles_doubles_sketch, sk_2: _datasketches.quantiles_doubles_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for quantiles_doubles_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
    +
  1. ks_test(sk_1: _datasketches.quantiles_items_sketch, sk_2: _datasketches.quantiles_items_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for quantiles_items_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.2/helper/serde.html b/docs/5.0.2/helper/serde.html new file mode 100644 index 00000000..a4ed73d0 --- /dev/null +++ b/docs/5.0.2/helper/serde.html @@ -0,0 +1,253 @@ + + + + + + + Serialize/Deserialize (SerDe) — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Serialize/Deserialize (SerDe)

+

A SerDe is a class used to serialize items sketches to a bytes object in binary. +Several example SerDes are provided as references.

+

The use of binary-compatible SerDes in different languages is critical for cross-language compatibility.

+

Each implementation must extend the PyObjectSerDe class and override all three of its methods.

+
+
+class PyObjectSerDe(*args, **kwargs)
+

An abstract base class for serde objects. All custom serdes must extend this class.

+
+
+get_size(self, item: object) int
+

Returns the size in bytes of an item

+
+
Parameters:
+

item (object) – The specified object

+
+
Returns:
+

The size of the item in bytes

+
+
Return type:
+

int

+
+
+
+ +
+
+to_bytes(self, item: object) bytes
+

Retuns a bytes object with a serialized version of an item

+
+
Parameters:
+

item (object) – The specified object

+
+
Returns:
+

A bytes object with the serialized object

+
+
Return type:
+

bytes

+
+
+
+ +
+
+from_bytes(self, data: bytes, offset: int) tuple
+

Reads a bytes object starting from the given offest and returns a tuple of the reconstructed object and the number of additional bytes read

+
+
Parameters:
+
    +
  • data (bytes) – A bytes object from which to deserialize

  • +
  • offset (int) – The offset, in bytes, at which to start reading

  • +
+
+
Returns:
+

A tuple with the reconstructed object and the number of bytes read

+
+
Return type:
+

tuple(object, int)

+
+
+
+ +
+ +

The provided SerDes are:

+
+
+class PyStringsSerDe(*args, **kwargs)
+

Bases: PyObjectSerDe

+

Implements a simple string-encoding scheme where a string is +written as <num_bytes> <string_contents>, with no null termination. +This format allows pre-allocating each string, at the cost of +additional storage. Using this format, the serialized string consumes +4 + len(item) bytes.

+
+ +
+
+class PyIntsSerDe(*args, **kwargs)
+

Bases: PyObjectSerDe

+

Implements an integer encoding scheme where each integer is written +as a 32-bit (4 byte) little-endian value.

+
+ +
+
+class PyLongsSerDe(*args, **kwargs)
+

Bases: PyObjectSerDe

+

Implements an integer encoding scheme where each integer is written +as a 64-bit (8 byte) little-endian value.

+
+ +
+
+class PyFloatsSerDe(*args, **kwargs)
+

Bases: PyObjectSerDe

+

Implements a floating point encoding scheme where each value is written +as a 32-bit floating point value.

+
+ +
+
+class PyDoublesSerDe(*args, **kwargs)
+

Implements a floating point encoding scheme where each value is written +as a 64-bit floating point value.

+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.2/helper/tuple_policy.html b/docs/5.0.2/helper/tuple_policy.html new file mode 100644 index 00000000..7aec98fb --- /dev/null +++ b/docs/5.0.2/helper/tuple_policy.html @@ -0,0 +1,230 @@ + + + + + + + Tuple Policy — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Tuple Policy

+

A Tuple Policy is needed when using a tuple_sketch in order to specify how the +summary values should be created, updated, combined, or intersected. A summary can consist of +any python object.

+

Each implementation must extend the abstract base class TuplePolicy.

+
+
+class TuplePolicy(*args, **kwargs)
+

An abstract base class for Tuple Policy objects. All custom policies must extend this class.

+
+
+create_summary(self) object
+

Creates a new Summary object

+
+
Returns:
+

a Summary object

+
+
Return type:
+

object

+
+
+
+ +
+
+update_summary(self, summary: object, update: object) object
+

Applies the relevant policy to update the provided summary with the data in update.

+
+
Parameters:
+
    +
  • summary (object) – An existing Summary

  • +
  • update (object) – An update to apply to the Summary

  • +
+
+
Returns:
+

The updated Summary

+
+
Return type:
+

object

+
+
+
+ +
+
+__call__(self, summary: object, update: object) object
+

Similar to update_summary but allows a different implementation for set operations (union and intersection)

+
+
Parameters:
+
    +
  • summary (object) – An existing Summary

  • +
  • update (object) – An update to apply to the Summary

  • +
+
+
Returns:
+

The updated Summary

+
+
Return type:
+

object

+
+
+
+ +
+ +
+
+class AccumulatorPolicy
+

Bases: TuplePolicy

+

Implements an accumulatory summary policy, where new values +are added to the existing value.

+
+ +
+
+class MinIntPolicy
+

Bases: TuplePolicy

+

Implements a MIN rule, where the smallest integer value is always kept.

+
+ +
+
+class MaxIntPolicy
+

Bases: TuplePolicy

+

Implements a MAX rule, where the largest integer value is always kept.

+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.2/index.html b/docs/5.0.2/index.html new file mode 100644 index 00000000..e2ba4b9d --- /dev/null +++ b/docs/5.0.2/index.html @@ -0,0 +1,215 @@ + + + + + + + Apache DataSketches — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Apache DataSketches

+

DataSketches are highly-efficient algorithms to analyze big data quickly.

+
+

Counting Distincts

+ +
+
+

Quantile Estimation

+ +
+
+

Frequency Sketches

+

This problem may also be known as heavy hitters or TopK

+ +
+
+

Vector Sketches

+ +
+
+

Random Sampling

+ +
+
+

Helper Classes

+ +
+

Note

+

This project is under active development.

+
+
+
+
+

Indices and tables

+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.2/objects.inv b/docs/5.0.2/objects.inv new file mode 100644 index 00000000..bd0053f4 Binary files /dev/null and b/docs/5.0.2/objects.inv differ diff --git a/docs/5.0.2/quantiles/index.html b/docs/5.0.2/quantiles/index.html new file mode 100644 index 00000000..184ed4dc --- /dev/null +++ b/docs/5.0.2/quantiles/index.html @@ -0,0 +1,154 @@ + + + + + + + Quantiles Sketches — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Quantiles Sketches

+

Quantile estimation is useful for understanding the distribution of data values in a stream. The sketches currently +in the library are designed to answer queries about the rank of an item in the stream of items. That is, when +applying a global ordering on all the items, what is the portion of items seen so far that are less than (alternatively, +less-than-or-equal-to) the given item. Using straightforward logic, they can also estimate the item at a given rank +in the stream.

+

These sketches may be used to compute approximate histograms, Probability Mass Functions (PMFs), or +Cumulative Distribution Functions (CDFs).

+

The library provides three types of quantiles sketches, each of which has generic items as well as versions +specific to a given numeric type (e.g. integer or floating point values). All three types provide error +bounds on rank estimation with proven probabilistic error distributions.

+
+
    +
  • KLL: Provides uniform rank estimation error over the entire range

  • +
  • REQ: Provides relative rank error estimates, which decreases approaching either the high or low end values.

  • +
  • Classic quantiles: Largely deprecated in favor of KLL, also provides uniform rank estimation error. Included largely for backwards compatibility with historic data.

  • +
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.2/quantiles/kll.html b/docs/5.0.2/quantiles/kll.html new file mode 100644 index 00000000..0dc2a14b --- /dev/null +++ b/docs/5.0.2/quantiles/kll.html @@ -0,0 +1,964 @@ + + + + + + + KLL Sketch — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

KLL Sketch

+

Implementation of a very compact quantiles sketch with lazy compaction scheme +and nearly optimal accuracy per retained item. +See Optimal Quantile Approximation in Streams.

+

This is a stochastic streaming sketch that enables near real-time analysis of the +approximate distribution of items from a very large stream in a single pass, requiring only +that the items are comparable. +The analysis is obtained using get_quantile() function or the +inverse functions get_rank(), get_pmf() (Probability Mass Function), and get_cdf() +(Cumulative Distribution Function).

+

As of May 2020, this implementation produces serialized sketches which are binary-compatible +with the equivalent Java implementation only when template parameter T = float +(32-bit single precision values).

+

Given an input stream of N items, the natural rank of any specific +item is defined as its index (1 to N) in inclusive mode +or (0 to N-1) in exclusive mode +in the hypothetical sorted stream of all N input items.

+

The normalized rank (rank) of any specific item is defined as its +natural rank divided by N. +Thus, the normalized rank is between zero and one. +In the documentation for this sketch natural rank is never used so any +reference to just rank should be interpreted to mean normalized rank.

+

This sketch is configured with a parameter k, which affects the size of the sketch +and its estimation error.

+

The estimation error is commonly called epsilon (or eps) and is a fraction +between zero and one. Larger values of k result in smaller values of epsilon. +Epsilon is always with respect to the rank and cannot be applied to the +corresponding items.

+

The relationship between the normalized rank and the corresponding items can be viewed +as a two-dimensional monotonic plot with the normalized rank on one axis and the +corresponding items on the other axis. If the y-axis is specified as the item-axis and +the x-axis as the normalized rank, then y = get_quantile(x) is a monotonically +increasing function.

+

The function get_quantile(rank) translates ranks into +corresponding quantiles. The functions get_rank(item), +get_cdf(…) (Cumulative Distribution Function), and get_pmf(…) +(Probability Mass Function) perform the opposite operation and translate items into ranks.

+

The get_pmf(…) function has about 13 to 47% worse rank error (depending +on k) than the other queries because the mass of each “bin” of the PMF has +“double-sided” error from the upper and lower edges of the bin as a result of a subtraction, +as the errors from the two edges can sometimes add.

+

The default k of 200 yields a “single-sided” epsilon of about 1.33% and a +“double-sided” (PMF) epsilon of about 1.65%.

+

A get_quantile(rank) query has the following guarantees: +- Let q = get_quantile(r) where r is the rank between zero and one. +- The quantile q will be an item from the input stream. +- Let true_rank be the true rank of q derived from the hypothetical sorted +stream of all N items. +- Let eps = get_normalized_rank_error(false). +- Then r - eps ≤ true_rank ≤ r + eps with a confidence of 99%. Note that the +error is on the rank, not the quantile.

+

A get_rank(item) query has the following guarantees: +- Let r = get_rank(i) where i is an item between the min and max items of +the input stream. +- Let true_rank be the true rank of i derived from the hypothetical sorted +stream of all N items. +- Let eps = get_normalized_rank_error(false). +- Then r - eps ≤ true_rank ≤ r + eps with a confidence of 99%.

+

A get_pmf() query has the following guarantees: +- Let {r1, r2, …, r(m+1)} = get_pmf(s1, s2, …, sm) where s1, s2 are +split points (items from the input domain) between the min and max items of +the input stream. +- Let mass_i = estimated mass between s_i and s_i+1. +- Let true_mass be the true mass between the items of s_i, +s_i+1 derived from the hypothetical sorted stream of all N items. +- Let eps = get_normalized_rank_error(true). +- then mass - eps ≤ true_mass ≤ mass + eps with a confidence of 99%. +- r(m+1) includes the mass of all points larger than s_m.

+

A get_cdf(…) query has the following guarantees; +- Let {r1, r2, …, r(m+1)} = get_cdf(s1, s2, …, sm) where s1, s2, … are +split points (items from the input domain) between the min and max items of +the input stream. +- Let mass_i = r_(i+1) - r_i. +- Let true_mass be the true mass between the true ranks of s_i, +s_i+1 derived from the hypothetical sorted stream of all N items. +- Let eps = get_normalized_rank_error(true). +- then mass - eps ≤ true_mass ≤ mass + eps with a confidence of 99%. +- 1 - r(m+1) includes the mass of all points larger than s_m.

+

From the above, it might seem like we could make some estimates to bound the +item returned from a call to get_quantile(). The sketch, however, does not +let us derive error bounds or confidences around items. Because errors are independent, we +can approximately bracket a value as shown below, but there are no error estimates available. +Additionally, the interval may be quite large for certain distributions. +- Let q = get_quantile(r), the estimated quantile of rank r. +- Let eps = get_normalized_rank_error(false). +- Let q_lo = estimated quantile of rank (r - eps). +- Let q_hi = estimated quantile of rank (r + eps). +- Then q_lo ≤ q ≤ q_hi, with 99% confidence.

+
+

Note

+

For the kll_items_sketch, objects must be comparable with __lt__.

+
+
+

Note

+

Serializing and deserializing a kll_items_sketch requires the use of a PyObjectSerDe.

+
+
+
+class kll_ints_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.kll_ints_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 200) None
+

Creates a KLL sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 200.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given normalized rank in a hypothetical sorted version of the input stream so far. +For kll_floats_sketch: if the sketch is empty this returns nan. For kll_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: int) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=int32]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class kll_floats_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.kll_floats_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 200) None
+

Creates a KLL sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 200.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given normalized rank in a hypothetical sorted version of the input stream so far. +For kll_floats_sketch: if the sketch is empty this returns nan. For kll_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: float) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=float32]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class kll_doubles_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.kll_doubles_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 200) None
+

Creates a KLL sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 200.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given normalized rank in a hypothetical sorted version of the input stream so far. +For kll_floats_sketch: if the sketch is empty this returns nan. For kll_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: float) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=float64]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class kll_items_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe) _datasketches.kll_items_sketch
+

Deserializes the sketch from a bytes object using the provided serde.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 200) None
+

Creates a KLL sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 200.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given normalized rank in a hypothetical sorted version of the input stream so far. +For kll_floats_sketch: if the sketch is empty this returns nan. For kll_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object using the provided serde.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Updates the sketch with the given value

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.2/quantiles/quantiles_depr.html b/docs/5.0.2/quantiles/quantiles_depr.html new file mode 100644 index 00000000..e63e9176 --- /dev/null +++ b/docs/5.0.2/quantiles/quantiles_depr.html @@ -0,0 +1,903 @@ + + + + + + + Quantiles Sketch (Deprecated) — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Quantiles Sketch (Deprecated)

+

This is a deprecated quantiles sketch that is included for cross-language compatibility. +Most new projects will favor the KLL sketch over this one, or the REQ sketch for higher accuracy +at the very edge of a distribution.

+

This is a stochastic streaming sketch that enables near-real time analysis of the +approximate distribution from a very large stream in a single pass. +The analysis is obtained using get_rank() and get_quantile() functions, +the Probability Mass Function from get_pmf()` and the Cumulative Distribution Function from get_cdf.

+

Consider a large stream of one million values such as packet sizes coming into a network node. +The natural rank of any specific size value is its index in the hypothetical sorted +array of values. +The normalized rank is the natural rank divided by the stream size, +in this case one million. +The value corresponding to the normalized rank of 0.5 represents the 50th percentile or median +value of the distribution, or get_quantile(0.5). +Similarly, the 95th percentile is obtained from get_quantile(0.95).

+

From the min and max values, for example, 1 and 1000 bytes, +you can obtain the PMF from get_pmf(100, 500, 900) that will result in an array of +4 fractional values such as {.4, .3, .2, .1}, which means that +40% of the values were < 100, +30% of the values were ≥ 100 and < 500, +20% of the values were ≥ 500 and < 900, and +10% of the values were ≥ 900. +A frequency histogram can be obtained by multiplying these fractions by get_n(), +which is the total count of values received. +The get_cdf()` works similarly, but produces the cumulative distribution instead.

+

As of November 2021, this implementation produces serialized sketches which are binary-compatible +with the equivalent Java implementation only when template parameter T = double +(64-bit double precision values).

+

The accuracy of this sketch is a function of the configured value k, which also affects +the overall size of the sketch. Accuracy of this quantile sketch is always with respect to +the normalized rank. A k of 128 produces a normalized, rank error of about 1.7%. +For example, the median item returned from get_quantile(0.5) will be between the actual items +from the hypothetically sorted array of input items at normalized ranks of 0.483 and 0.517, with +a confidence of about 99%.

+
+

Note

+

For the quantiles_items_sketch, objects must be comparable with __lt__.

+
+
+

Note

+

Serializing and deserializing a quantiles_items_sketch requires the use of a PyObjectSerDe.

+
+
+
+class quantiles_ints_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.quantiles_ints_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 128) None
+

Creates a classic quantiles sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 128.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given rank in a hypothetical sorted version of the input stream so far. +For quantiles_floats_sketch: if the sketch is empty this returns nan. For quantiles_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: int) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=int32]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class quantiles_floats_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.quantiles_floats_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 128) None
+

Creates a classic quantiles sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 128.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given rank in a hypothetical sorted version of the input stream so far. +For quantiles_floats_sketch: if the sketch is empty this returns nan. For quantiles_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: float) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=float32]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class quantiles_doubles_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.quantiles_doubles_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 128) None
+

Creates a classic quantiles sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 128.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given rank in a hypothetical sorted version of the input stream so far. +For quantiles_floats_sketch: if the sketch is empty this returns nan. For quantiles_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: float) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=float64]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class quantiles_items_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe) _datasketches.quantiles_items_sketch
+

Deserializes the sketch from a bytes object using the provided serde.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 128) None
+

Creates a classic quantiles sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 128.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given rank in a hypothetical sorted version of the input stream so far. +For quantiles_floats_sketch: if the sketch is empty this returns nan. For quantiles_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object using the provided serde.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Updates the sketch with the given value

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.2/quantiles/req.html b/docs/5.0.2/quantiles/req.html new file mode 100644 index 00000000..7ece205d --- /dev/null +++ b/docs/5.0.2/quantiles/req.html @@ -0,0 +1,754 @@ + + + + + + + Relative Error Quantiles (REQ) Sketch — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Relative Error Quantiles (REQ) Sketch

+

This is an implementation based on the paper “Relative Error Streaming Quantiles” by Graham Cormode, Zohar Karnin, Edo Liberty, Justin Thaler, Pavel Veselý, and loosely derived from a Python prototype written by Pavel Veselý.

+

This implementation differs from the algorithm described in the paper in the following:

+

The algorithm requires no upper bound on the stream length. +Instead, each relative-compactor counts the number of compaction operations performed so far (via variable state). +Initially, the relative-compactor starts with INIT_NUMBER_OF_SECTIONS. +Each time the number of compactions (variable state) exceeds 2^{numSections - 1}, we double numSections. +Note that after merging the sketch with another one variable state may not correspond to the number of compactions performed at a particular level, however, +since the state variable never exceeds the number of compactions, the guarantees of the sketch remain valid.

+

The size of each section (variable k and section_size in the code and parameter k in the paper) is +initialized with a number set by the user via variable k. +When the number of sections doubles, we decrease section_size by a factor of sqrt(2). +This is applied at each level separately. +Thus, when we double the number of sections, the nominal compactor size increases by a factor of approx. sqrt(2) (+/- rounding).

+

The merge operation here does not perform “special compactions”, which are used in the paper to allow for a tight mathematical analysis of the sketch. +This implementation provides a number of capabilities not discussed in the paper or provided in the Python prototype.

+

The Python prototype only implemented high accuracy for low ranks. This implementation provides the user with the ability to +choose either high rank accuracy or low rank accuracy at the time of sketch construction. +The Python prototype only implemented a comparison criterion of INCLUSIVE. +This implementation allows the user to use both the INCLUSIVE criterion and the EXCLUSIVE criterion. +This implementation provides extensive debug visibility into the operation of the sketch with two levels of detail output. +This is not only useful for debugging, but is a powerful tool to help users understand how the sketch works.

+
+

Note

+

For the req_items_sketch, objects must be comparable with __lt__.

+
+
+

Note

+

Serializing and deserializing a req_items_sketch requires the use of a PyObjectSerDe.

+
+
+
+class req_ints_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.req_ints_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_RSE(k: int, rank: float, is_hra: bool, n: int) float
+

Returns an a priori estimate of relative standard error (RSE, expressed as a number in [0,1]). Derived from Lemma 12 in http://arxiv.org/abs/2004.01668v2, but the constant factors have been modified based on empirical measurements, for a given value of parameter k. +Normalized rank must be a value between 0.0 and 1.0 (inclusive). If is_hra is True, uses high rank accuracy mode, else low rank accuracy. N is an estimate of the total number of points provided to the sketch.

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 12, is_hra: bool = True) None
+

Creates an REQ sketch instance with the given value of k.

+
+
Parameters:
+
    +
  • k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 12.

  • +
  • is_hra (bool, optional) – Specifies whether the skech has High Rank Accuracy (True) or Low Rank Accuracy. Default True.

  • +
+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, req_floats_sketch returns nan; req_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, req_floats_sketch returns nan; req_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given normalized rank in a hypothetical sorted version of the input stream so far. +For req_floats_sketch: if the sketch is empty this returns nan. For req_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+get_rank_lower_bound
+

Returns an approximate lower bound on the given normalized rank. +Normalized rank must be a value between 0.0 and 1.0 (inclusive); the number of standard deviations must be 1, 2, or 3.

+
+ +
+
+get_rank_upper_bound
+

Returns an approximate upper bound on the given normalized rank. +Normalized rank must be a value between 0.0 and 1.0 (inclusive); the number of standard deviations must be 1, 2, or 3.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+is_hra
+

Returns True if the sketch is in High Rank Accuracy mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: int) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=int32]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class req_floats_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.req_floats_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_RSE(k: int, rank: float, is_hra: bool, n: int) float
+

Returns an a priori estimate of relative standard error (RSE, expressed as a number in [0,1]). Derived from Lemma 12 in http://arxiv.org/abs/2004.01668v2, but the constant factors have been modified based on empirical measurements, for a given value of parameter k. +Normalized rank must be a value between 0.0 and 1.0 (inclusive). If is_hra is True, uses high rank accuracy mode, else low rank accuracy. N is an estimate of the total number of points provided to the sketch.

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 12, is_hra: bool = True) None
+

Creates an REQ sketch instance with the given value of k.

+
+
Parameters:
+
    +
  • k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 12.

  • +
  • is_hra (bool, optional) – Specifies whether the skech has High Rank Accuracy (True) or Low Rank Accuracy. Default True.

  • +
+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, req_floats_sketch returns nan; req_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, req_floats_sketch returns nan; req_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given normalized rank in a hypothetical sorted version of the input stream so far. +For req_floats_sketch: if the sketch is empty this returns nan. For req_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+get_rank_lower_bound
+

Returns an approximate lower bound on the given normalized rank. +Normalized rank must be a value between 0.0 and 1.0 (inclusive); the number of standard deviations must be 1, 2, or 3.

+
+ +
+
+get_rank_upper_bound
+

Returns an approximate upper bound on the given normalized rank. +Normalized rank must be a value between 0.0 and 1.0 (inclusive); the number of standard deviations must be 1, 2, or 3.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+is_hra
+

Returns True if the sketch is in High Rank Accuracy mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: float) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=float32]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class req_items_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe) _datasketches.req_items_sketch
+

Deserializes the sketch from a bytes object using the provided serde.

+
+ +
+
+get_RSE(k: int, rank: float, is_hra: bool, n: int) float
+

Returns an a priori estimate of relative standard error (RSE, expressed as a number in [0,1]). Derived from Lemma 12 in http://arxiv.org/abs/2004.01668v2, but the constant factors have been modified based on empirical measurements, for a given value of parameter k. +Normalized rank must be a value between 0.0 and 1.0 (inclusive). If is_hra is True, uses high rank accuracy mode, else low rank accuracy. N is an estimate of the total number of points provided to the sketch.

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 12, is_hra: bool = True) None
+

Creates an REQ sketch instance with the given value of k.

+
+
Parameters:
+
    +
  • k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 12.

  • +
  • is_hra (bool, optional) – Specifies whether the skech has High Rank Accuracy (True) or Low Rank Accuracy. Default True.

  • +
+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, req_floats_sketch returns nan; req_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, req_floats_sketch returns nan; req_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given normalized rank in a hypothetical sorted version of the input stream so far. +For req_floats_sketch: if the sketch is empty this returns nan. For req_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+get_rank_lower_bound
+

Returns an approximate lower bound on the given normalized rank. +Normalized rank must be a value between 0.0 and 1.0 (inclusive); the number of standard deviations must be 1, 2, or 3.

+
+ +
+
+get_rank_upper_bound
+

Returns an approximate upper bound on the given normalized rank. +Normalized rank must be a value between 0.0 and 1.0 (inclusive); the number of standard deviations must be 1, 2, or 3.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+is_hra
+

Returns True if the sketch is in High Rank Accuracy mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object using the provided serde.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Updates the sketch with the given value

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.2/sampling/ebpps.html b/docs/5.0.2/sampling/ebpps.html new file mode 100644 index 00000000..07b97185 --- /dev/null +++ b/docs/5.0.2/sampling/ebpps.html @@ -0,0 +1,238 @@ + + + + + + + Exact and Bounded, Probabilitiy Proportional to Size (EBPPS) Sampling — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Exact and Bounded, Probabilitiy Proportional to Size (EBPPS) Sampling

+

An EBPPS sketch produces a randome sample of data from a stream of items, ensuring that the probability +of including an item is always exactly equal to the item’s size. The size of an item is defined as its +weight relative to the total weight of all items seen so far by the sketch. In contrast to VarOpt sampling, +this sketch may return fewer than k items in order to keep the probability of including an item strictly +proportional to its size.

+

This sketch is based on: B. Hentschel, P. J. Haas, Y. Tian +“Exact PPS Sampling with Bounded Sample Size”, +Information Processing Letters, 2023.

+

EBPPS sampling is related to reservoir sampling, but handles unequal item weights. +Feeding the sketch items with a uniform weight value will produce a sample equivalent to reservoir sampling.

+
+

Note

+

Serializing and deserializing this sketch requires the use of a PyObjectSerDe.

+
+
+
+class ebpps_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe) _datasketches.ebpps_sketch
+

Reads a bytes object and returns the corresponding ebpps_sketch

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int) None
+

Creates a new EBPPS sketch instance

+
+
Parameters:
+

k (int) – Maximum number of samples in the sketch

+
+
+
+ +
+
+property c
+

The expected number of samples returned upon a call to get_result() or the creation of an iterator. The number is a floating point value, where the fractional portion represents the probability of including a “partial item” from the sample. The value C should be no larger than the sketch’s configured value of k, although numerical precision limitations mean it may exceed k by double precision floating point error margins in certain cases.

+
+ +
+
+get_serialized_size_bytes
+

Computes the size in bytes needed to serialize the current sketch

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+property k
+

The sketch’s maximum configured sample size

+
+ +
+
+merge
+

Merges the sketch with the given sketch

+
+ +
+
+property n
+

The total stream length

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object

+
+ +
+
+to_string
+

Produces a string summary of the sketch and optionally prints the items

+
+ +
+
+update
+

Updates the sketch with the given value and weight

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.2/sampling/index.html b/docs/5.0.2/sampling/index.html new file mode 100644 index 00000000..7cc2cb53 --- /dev/null +++ b/docs/5.0.2/sampling/index.html @@ -0,0 +1,147 @@ + + + + + + + Random Sampling Sketches — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Random Sampling Sketches

+

These sketches are used to randomly sample items. The length of the input +stream does not need to be known in advance.

+

Both VarOpt (Variance Optimal) and EBPPS (Exact and Bounded, +Probability Proportional to Size) sketches will include sample items based on +each item’s weight relative to the weight of the entire stream but +they differ in details:

+
+
    +
  • ebpps_sketch ensures that the probability of including an item is always exactly proportional to the item’s weight.

  • +
  • var_opt_sketch optimizes for applying a predicate to the resulting sample such that the variance of the subset sum after applying the predicate is minimized, even if the inclusion probability differs somewhat from being proportional to the item’s weight.

  • +
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.2/sampling/varopt.html b/docs/5.0.2/sampling/varopt.html new file mode 100644 index 00000000..1b3889f6 --- /dev/null +++ b/docs/5.0.2/sampling/varopt.html @@ -0,0 +1,300 @@ + + + + + + + Variance Optimal Sampling (VarOpt) — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Variance Optimal Sampling (VarOpt)

+

A VarOpt sketch samples data from a stream of items. The sketch is desinged for optimal (minimum) +variance when querying the sketch to estimate subset sums of items matching a provided predicate. +The sketch will produce a sample of size k (or smaller if fewer items have been presented), with +the probability of including an item roughly corresponding it the item’s weight relative to the total +weight of all items presented to the sketch.

+

VarOpt sampling is related to reservoir sampling, with improved error bounds for subset sum estimation. +Feeding the sketch items with a uniform weight value will produce a sample equivalent to reservoir sampling.

+
+

Note

+

Serializing and deserializing this sketch requires the use of a PyObjectSerDe.

+
+
+
+class var_opt_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe) _datasketches.var_opt_sketch
+

Reads a bytes object and returns the corresponding var opt sketch

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int) None
+

Creates a new Var Opt sketch instance

+
+
Parameters:
+

k (int) – Maximum number of samples in the sketch

+
+
+
+ +
+
+estimate_subset_sum
+

Applies a provided predicate to the sketch and returns the estimated total weight matching the predicate, as well as upper and lower bounds on the estimate and the total weight processed by the sketch

+
+ +
+
+get_serialized_size_bytes
+

Computes the size in bytes needed to serialize the current sketch

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+property k
+

Returns the sketch’s maximum configured sample size

+
+ +
+
+property n
+

Returns the total stream length

+
+ +
+
+property num_samples
+

Returns the number of samples currently in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object

+
+ +
+
+to_string
+

Produces a string summary of the sketch and optionally prints the items

+
+ +
+
+update
+

Updates the sketch with the given value and weight

+
+ +
+ +
+
+class var_opt_union(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe) _datasketches.var_opt_union
+

Constructs a var opt union from the given bytes using the provided serde

+
+ +

Non-static Methods:

+
+
+__init__(self, max_k: int) None
+
+ +
+
+get_result
+

Returns a sketch corresponding to the union result

+
+ +
+
+get_serialized_size_bytes
+

Computes the size in bytes needed to serialize the current union

+
+ +
+
+reset
+

Resets the union to the empty state

+
+ +
+
+serialize
+

Serializes the union into a bytes object with the provided serde

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Updates the union with the given sketch

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.2/search.html b/docs/5.0.2/search.html new file mode 100644 index 00000000..21031339 --- /dev/null +++ b/docs/5.0.2/search.html @@ -0,0 +1,136 @@ + + + + + + Search — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ + + + +
+ +
+ +
+
+ +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/docs/5.0.2/searchindex.js b/docs/5.0.2/searchindex.js new file mode 100644 index 00000000..5206d48d --- /dev/null +++ b/docs/5.0.2/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"alltitles": {"Apache DataSketches": [[14, "apache-datasketches"]], "Compressed Probabilistic Counting (CPC)": [[0, "compressed-probabilistic-counting-cpc"]], "CountMin Sketch": [[5, "countmin-sketch"]], "Counting Distincts": [[14, "counting-distincts"]], "Density Sketch": [[22, "density-sketch"]], "Distinct Counting": [[2, "distinct-counting"]], "Exact and Bounded, Probabilitiy Proportional to Size (EBPPS) Sampling": [[19, "exact-and-bounded-probabilitiy-proportional-to-size-ebpps-sampling"]], "Frequency Sketches": [[7, "frequency-sketches"], [14, "frequency-sketches"]], "Frequent Items": [[6, "frequent-items"]], "Helper Classes": [[8, "helper-classes"], [14, "helper-classes"]], "HyperLogLog (HLL)": [[1, "hyperloglog-hll"]], "Indices and tables": [[14, "indices-and-tables"]], "Jaccard Similarity": [[9, "jaccard-similarity"]], "KLL Sketch": [[16, "kll-sketch"]], "Kernel Function": [[10, "kernel-function"]], "Kolmogorov-Smirnov Test": [[11, "kolmogorov-smirnov-test"]], "Quantile Estimation": [[14, "quantile-estimation"]], "Quantiles Sketch (Deprecated)": [[17, "quantiles-sketch-deprecated"]], "Quantiles Sketches": [[15, "quantiles-sketches"]], "Random Sampling": [[14, "random-sampling"]], "Random Sampling Sketches": [[20, "random-sampling-sketches"]], "Relative Error Quantiles (REQ) Sketch": [[18, "relative-error-quantiles-req-sketch"]], "Serialize/Deserialize (SerDe)": [[12, "serialize-deserialize-serde"]], "Theta Sketch": [[3, "theta-sketch"]], "Tuple Policy": [[13, "tuple-policy"]], "Tuple Sketch": [[4, "tuple-sketch"]], "Variance Optimal Sampling (VarOpt)": [[21, "variance-optimal-sampling-varopt"]], "Vector Sketches": [[14, "vector-sketches"], [23, "vector-sketches"]]}, "docnames": ["distinct_counting/cpc", "distinct_counting/hyper_log_log", "distinct_counting/index", "distinct_counting/theta", "distinct_counting/tuple", "frequency/count_min_sketch", "frequency/frequent_items", "frequency/index", "helper/index", "helper/jaccard", "helper/kernel", "helper/ks_test", "helper/serde", "helper/tuple_policy", "index", "quantiles/index", "quantiles/kll", "quantiles/quantiles_depr", "quantiles/req", "sampling/ebpps", "sampling/index", "sampling/varopt", "vector/density_sketch", "vector/index"], "envversion": {"sphinx": 61, "sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2}, "filenames": ["distinct_counting/cpc.rst", "distinct_counting/hyper_log_log.rst", "distinct_counting/index.rst", "distinct_counting/theta.rst", "distinct_counting/tuple.rst", "frequency/count_min_sketch.rst", "frequency/frequent_items.rst", "frequency/index.rst", "helper/index.rst", "helper/jaccard.rst", "helper/kernel.rst", "helper/ks_test.rst", "helper/serde.rst", "helper/tuple_policy.rst", "index.rst", "quantiles/index.rst", "quantiles/kll.rst", "quantiles/quantiles_depr.rst", "quantiles/req.rst", "sampling/ebpps.rst", "sampling/index.rst", "sampling/varopt.rst", "vector/density_sketch.rst", "vector/index.rst"], "indexentries": {"__call__() (kernelfunction method)": [[10, "datasketches.KernelFunction.__call__", false]], "__call__() (tuplepolicy method)": [[13, "datasketches.TuplePolicy.__call__", false]], "__init__() (compact_theta_sketch method)": [[3, "datasketches.compact_theta_sketch.__init__", false]], "__init__() (compact_tuple_sketch method)": [[4, "datasketches.compact_tuple_sketch.__init__", false]], "__init__() (cpc_sketch method)": [[0, "datasketches.cpc_sketch.__init__", false]], "__init__() (cpc_union method)": [[0, "datasketches.cpc_union.__init__", false]], "__init__() (density_sketch method)": [[22, "datasketches.density_sketch.__init__", false]], "__init__() (ebpps_sketch method)": [[19, "datasketches.ebpps_sketch.__init__", false]], "__init__() (frequent_items_sketch method)": [[6, "datasketches.frequent_items_sketch.__init__", false]], "__init__() (frequent_strings_sketch method)": [[6, "datasketches.frequent_strings_sketch.__init__", false]], "__init__() (hll_sketch method)": [[1, "datasketches.hll_sketch.__init__", false]], "__init__() (hll_union method)": [[1, "datasketches.hll_union.__init__", false]], "__init__() (kll_doubles_sketch method)": [[16, "datasketches.kll_doubles_sketch.__init__", false]], "__init__() (kll_floats_sketch method)": [[16, "datasketches.kll_floats_sketch.__init__", false]], "__init__() (kll_ints_sketch method)": [[16, "datasketches.kll_ints_sketch.__init__", false]], "__init__() (kll_items_sketch method)": [[16, "datasketches.kll_items_sketch.__init__", false]], "__init__() (quantiles_doubles_sketch method)": [[17, "datasketches.quantiles_doubles_sketch.__init__", false]], "__init__() (quantiles_floats_sketch method)": [[17, "datasketches.quantiles_floats_sketch.__init__", false]], "__init__() (quantiles_ints_sketch method)": [[17, "datasketches.quantiles_ints_sketch.__init__", false]], "__init__() (quantiles_items_sketch method)": [[17, "datasketches.quantiles_items_sketch.__init__", false]], "__init__() (req_floats_sketch method)": [[18, "datasketches.req_floats_sketch.__init__", false]], "__init__() (req_ints_sketch method)": [[18, "datasketches.req_ints_sketch.__init__", false]], "__init__() (req_items_sketch method)": [[18, "datasketches.req_items_sketch.__init__", false]], "__init__() (theta_a_not_b method)": [[3, "datasketches.theta_a_not_b.__init__", false]], "__init__() (theta_intersection method)": [[3, "datasketches.theta_intersection.__init__", false]], "__init__() (theta_union method)": [[3, "datasketches.theta_union.__init__", false]], "__init__() (tuple_a_not_b method)": [[4, "datasketches.tuple_a_not_b.__init__", false]], "__init__() (tuple_intersection method)": [[4, "datasketches.tuple_intersection.__init__", false]], "__init__() (tuple_union method)": [[4, "datasketches.tuple_union.__init__", false]], "__init__() (update_theta_sketch method)": [[3, "datasketches.update_theta_sketch.__init__", false]], "__init__() (update_tuple_sketch method)": [[4, "datasketches.update_tuple_sketch.__init__", false]], "__init__() (var_opt_sketch method)": [[21, "datasketches.var_opt_sketch.__init__", false]], "__init__() (var_opt_union method)": [[21, "datasketches.var_opt_union.__init__", false]], "accumulatorpolicy (class in datasketches)": [[13, "datasketches.AccumulatorPolicy", false]], "c (ebpps_sketch property)": [[19, "datasketches.ebpps_sketch.c", false]], "compact (update_theta_sketch attribute)": [[3, "datasketches.update_theta_sketch.compact", false]], "compact (update_tuple_sketch attribute)": [[4, "datasketches.update_tuple_sketch.compact", false]], "compact_theta_sketch (class in datasketches)": [[3, "datasketches.compact_theta_sketch", false]], "compact_tuple_sketch (class in datasketches)": [[4, "datasketches.compact_tuple_sketch", false]], "compute (theta_a_not_b attribute)": [[3, "datasketches.theta_a_not_b.compute", false]], "compute (tuple_a_not_b attribute)": [[4, "datasketches.tuple_a_not_b.compute", false]], "count_min_sketch (class in _datasketches)": [[5, "datasketches.count_min_sketch", false]], "cpc_sketch (class in _datasketches)": [[0, "datasketches.cpc_sketch", false]], "cpc_union (class in _datasketches)": [[0, "datasketches.cpc_union", false]], "create_summary() (tuplepolicy method)": [[13, "datasketches.TuplePolicy.create_summary", false]], "default_seed (tuple_sketch attribute)": [[4, "datasketches.tuple_sketch.DEFAULT_SEED", false]], "density_sketch (class in datasketches)": [[22, "datasketches.density_sketch", false]], "deserialize() (compact_theta_sketch method)": [[3, "datasketches.compact_theta_sketch.deserialize", false]], "deserialize() (compact_tuple_sketch method)": [[4, "datasketches.compact_tuple_sketch.deserialize", false]], "deserialize() (count_min_sketch method)": [[5, "datasketches.count_min_sketch.deserialize", false]], "deserialize() (cpc_sketch method)": [[0, "datasketches.cpc_sketch.deserialize", false]], "deserialize() (density_sketch method)": [[22, "datasketches.density_sketch.deserialize", false]], "deserialize() (ebpps_sketch method)": [[19, "datasketches.ebpps_sketch.deserialize", false]], "deserialize() (frequent_items_sketch method)": [[6, "datasketches.frequent_items_sketch.deserialize", false]], "deserialize() (frequent_strings_sketch method)": [[6, "datasketches.frequent_strings_sketch.deserialize", false]], "deserialize() (hll_sketch method)": [[1, "datasketches.hll_sketch.deserialize", false]], "deserialize() (kll_doubles_sketch method)": [[16, "datasketches.kll_doubles_sketch.deserialize", false]], "deserialize() (kll_floats_sketch method)": [[16, "datasketches.kll_floats_sketch.deserialize", false]], "deserialize() (kll_ints_sketch method)": [[16, "datasketches.kll_ints_sketch.deserialize", false]], "deserialize() (kll_items_sketch method)": [[16, "datasketches.kll_items_sketch.deserialize", false]], "deserialize() (quantiles_doubles_sketch method)": [[17, "datasketches.quantiles_doubles_sketch.deserialize", false]], "deserialize() (quantiles_floats_sketch method)": [[17, "datasketches.quantiles_floats_sketch.deserialize", false]], "deserialize() (quantiles_ints_sketch method)": [[17, "datasketches.quantiles_ints_sketch.deserialize", false]], "deserialize() (quantiles_items_sketch method)": [[17, "datasketches.quantiles_items_sketch.deserialize", false]], "deserialize() (req_floats_sketch method)": [[18, "datasketches.req_floats_sketch.deserialize", false]], "deserialize() (req_ints_sketch method)": [[18, "datasketches.req_ints_sketch.deserialize", false]], "deserialize() (req_items_sketch method)": [[18, "datasketches.req_items_sketch.deserialize", false]], "deserialize() (var_opt_sketch method)": [[21, "datasketches.var_opt_sketch.deserialize", false]], "deserialize() (var_opt_union method)": [[21, "datasketches.var_opt_union.deserialize", false]], "dim (density_sketch property)": [[22, "datasketches.density_sketch.dim", false]], "dissimilarity_test() (theta_jaccard_similarity method)": [[9, "datasketches.theta_jaccard_similarity.dissimilarity_test", false]], "dissimilarity_test() (tuple_jaccard_similarity method)": [[9, "datasketches.tuple_jaccard_similarity.dissimilarity_test", false]], "ebpps_sketch (class in datasketches)": [[19, "datasketches.ebpps_sketch", false]], "epsilon (frequent_items_sketch property)": [[6, "datasketches.frequent_items_sketch.epsilon", false]], "epsilon (frequent_strings_sketch property)": [[6, "datasketches.frequent_strings_sketch.epsilon", false]], "estimate_subset_sum (var_opt_sketch attribute)": [[21, "datasketches.var_opt_sketch.estimate_subset_sum", false]], "exactly_equal() (theta_jaccard_similarity method)": [[9, "datasketches.theta_jaccard_similarity.exactly_equal", false]], "exactly_equal() (tuple_jaccard_similarity method)": [[9, "datasketches.tuple_jaccard_similarity.exactly_equal", false]], "frequent_items_error_type (class in datasketches)": [[6, "datasketches.frequent_items_error_type", false]], "frequent_items_sketch (class in datasketches)": [[6, "datasketches.frequent_items_sketch", false]], "frequent_strings_sketch (class in datasketches)": [[6, "datasketches.frequent_strings_sketch", false]], "from_bytes() (pyobjectserde method)": [[12, "datasketches.PyObjectSerDe.from_bytes", false]], "gaussiankernel (class in datasketches)": [[10, "datasketches.GaussianKernel", false]], "get_apriori_error() (frequent_items_sketch method)": [[6, "datasketches.frequent_items_sketch.get_apriori_error", false]], "get_apriori_error() (frequent_strings_sketch method)": [[6, "datasketches.frequent_strings_sketch.get_apriori_error", false]], "get_cdf (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.get_cdf", false]], "get_cdf (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.get_cdf", false]], "get_cdf (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.get_cdf", false]], "get_cdf (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.get_cdf", false]], "get_cdf (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.get_cdf", false]], "get_cdf (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.get_cdf", false]], "get_cdf (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.get_cdf", false]], "get_cdf (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.get_cdf", false]], "get_cdf (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.get_cdf", false]], "get_cdf (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.get_cdf", false]], "get_cdf (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.get_cdf", false]], "get_compact_serialization_bytes (hll_sketch attribute)": [[1, "datasketches.hll_sketch.get_compact_serialization_bytes", false]], "get_epsilon_for_lg_size() (frequent_items_sketch method)": [[6, "datasketches.frequent_items_sketch.get_epsilon_for_lg_size", false]], "get_epsilon_for_lg_size() (frequent_strings_sketch method)": [[6, "datasketches.frequent_strings_sketch.get_epsilon_for_lg_size", false]], "get_estimate (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.get_estimate", false]], "get_estimate (cpc_sketch attribute)": [[0, "datasketches.cpc_sketch.get_estimate", false]], "get_estimate (density_sketch attribute)": [[22, "datasketches.density_sketch.get_estimate", false]], "get_estimate (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.get_estimate", false]], "get_estimate (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.get_estimate", false]], "get_estimate (hll_sketch attribute)": [[1, "datasketches.hll_sketch.get_estimate", false]], "get_estimate (hll_union attribute)": [[1, "datasketches.hll_union.get_estimate", false]], "get_estimate (theta_sketch attribute)": [[3, "datasketches.theta_sketch.get_estimate", false]], "get_estimate (tuple_sketch attribute)": [[4, "datasketches.tuple_sketch.get_estimate", false]], "get_frequent_items (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.get_frequent_items", false]], "get_frequent_items (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.get_frequent_items", false]], "get_lower_bound (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.get_lower_bound", false]], "get_lower_bound (cpc_sketch attribute)": [[0, "datasketches.cpc_sketch.get_lower_bound", false]], "get_lower_bound (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.get_lower_bound", false]], "get_lower_bound (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.get_lower_bound", false]], "get_lower_bound (hll_sketch attribute)": [[1, "datasketches.hll_sketch.get_lower_bound", false]], "get_lower_bound (hll_union attribute)": [[1, "datasketches.hll_union.get_lower_bound", false]], "get_lower_bound (theta_sketch attribute)": [[3, "datasketches.theta_sketch.get_lower_bound", false]], "get_lower_bound (tuple_sketch attribute)": [[4, "datasketches.tuple_sketch.get_lower_bound", false]], "get_max_updatable_serialization_bytes() (hll_sketch method)": [[1, "datasketches.hll_sketch.get_max_updatable_serialization_bytes", false]], "get_max_value (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.get_max_value", false]], "get_max_value (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.get_max_value", false]], "get_max_value (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.get_max_value", false]], "get_max_value (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.get_max_value", false]], "get_max_value (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.get_max_value", false]], "get_max_value (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.get_max_value", false]], "get_max_value (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.get_max_value", false]], "get_max_value (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.get_max_value", false]], "get_max_value (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.get_max_value", false]], "get_max_value (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.get_max_value", false]], "get_max_value (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.get_max_value", false]], "get_min_value (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.get_min_value", false]], "get_min_value (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.get_min_value", false]], "get_min_value (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.get_min_value", false]], "get_min_value (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.get_min_value", false]], "get_min_value (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.get_min_value", false]], "get_min_value (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.get_min_value", false]], "get_min_value (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.get_min_value", false]], "get_min_value (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.get_min_value", false]], "get_min_value (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.get_min_value", false]], "get_min_value (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.get_min_value", false]], "get_min_value (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.get_min_value", false]], "get_normalized_rank_error() (kll_doubles_sketch method)": [[16, "datasketches.kll_doubles_sketch.get_normalized_rank_error", false]], "get_normalized_rank_error() (kll_floats_sketch method)": [[16, "datasketches.kll_floats_sketch.get_normalized_rank_error", false]], "get_normalized_rank_error() (kll_ints_sketch method)": [[16, "datasketches.kll_ints_sketch.get_normalized_rank_error", false]], "get_normalized_rank_error() (kll_items_sketch method)": [[16, "datasketches.kll_items_sketch.get_normalized_rank_error", false]], "get_normalized_rank_error() (quantiles_doubles_sketch method)": [[17, "datasketches.quantiles_doubles_sketch.get_normalized_rank_error", false]], "get_normalized_rank_error() (quantiles_floats_sketch method)": [[17, "datasketches.quantiles_floats_sketch.get_normalized_rank_error", false]], "get_normalized_rank_error() (quantiles_ints_sketch method)": [[17, "datasketches.quantiles_ints_sketch.get_normalized_rank_error", false]], "get_normalized_rank_error() (quantiles_items_sketch method)": [[17, "datasketches.quantiles_items_sketch.get_normalized_rank_error", false]], "get_pmf (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.get_pmf", false]], "get_pmf (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.get_pmf", false]], "get_pmf (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.get_pmf", false]], "get_pmf (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.get_pmf", false]], "get_pmf (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.get_pmf", false]], "get_pmf (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.get_pmf", false]], "get_pmf (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.get_pmf", false]], "get_pmf (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.get_pmf", false]], "get_pmf (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.get_pmf", false]], "get_pmf (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.get_pmf", false]], "get_pmf (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.get_pmf", false]], "get_quantile (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.get_quantile", false]], "get_quantile (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.get_quantile", false]], "get_quantile (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.get_quantile", false]], "get_quantile (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.get_quantile", false]], "get_quantile (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.get_quantile", false]], "get_quantile (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.get_quantile", false]], "get_quantile (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.get_quantile", false]], "get_quantile (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.get_quantile", false]], "get_quantile (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.get_quantile", false]], "get_quantile (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.get_quantile", false]], "get_quantile (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.get_quantile", false]], "get_quantiles (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.get_quantiles", false]], "get_quantiles (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.get_quantiles", false]], "get_quantiles (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.get_quantiles", false]], "get_quantiles (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.get_quantiles", false]], "get_quantiles (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.get_quantiles", false]], "get_quantiles (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.get_quantiles", false]], "get_quantiles (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.get_quantiles", false]], "get_quantiles (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.get_quantiles", false]], "get_quantiles (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.get_quantiles", false]], "get_quantiles (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.get_quantiles", false]], "get_quantiles (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.get_quantiles", false]], "get_rank (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.get_rank", false]], "get_rank (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.get_rank", false]], "get_rank (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.get_rank", false]], "get_rank (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.get_rank", false]], "get_rank (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.get_rank", false]], "get_rank (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.get_rank", false]], "get_rank (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.get_rank", false]], "get_rank (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.get_rank", false]], "get_rank (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.get_rank", false]], "get_rank (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.get_rank", false]], "get_rank (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.get_rank", false]], "get_rank_lower_bound (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.get_rank_lower_bound", false]], "get_rank_lower_bound (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.get_rank_lower_bound", false]], "get_rank_lower_bound (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.get_rank_lower_bound", false]], "get_rank_upper_bound (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.get_rank_upper_bound", false]], "get_rank_upper_bound (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.get_rank_upper_bound", false]], "get_rank_upper_bound (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.get_rank_upper_bound", false]], "get_rel_err() (hll_sketch method)": [[1, "datasketches.hll_sketch.get_rel_err", false]], "get_rel_err() (hll_union method)": [[1, "datasketches.hll_union.get_rel_err", false]], "get_relative_error (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.get_relative_error", false]], "get_result (cpc_union attribute)": [[0, "datasketches.cpc_union.get_result", false]], "get_result (hll_union attribute)": [[1, "datasketches.hll_union.get_result", false]], "get_result (theta_intersection attribute)": [[3, "datasketches.theta_intersection.get_result", false]], "get_result (theta_union attribute)": [[3, "datasketches.theta_union.get_result", false]], "get_result (tuple_intersection attribute)": [[4, "datasketches.tuple_intersection.get_result", false]], "get_result (tuple_union attribute)": [[4, "datasketches.tuple_union.get_result", false]], "get_result (var_opt_union attribute)": [[21, "datasketches.var_opt_union.get_result", false]], "get_rse() (req_floats_sketch method)": [[18, "datasketches.req_floats_sketch.get_RSE", false]], "get_rse() (req_ints_sketch method)": [[18, "datasketches.req_ints_sketch.get_RSE", false]], "get_rse() (req_items_sketch method)": [[18, "datasketches.req_items_sketch.get_RSE", false]], "get_seed_hash (theta_sketch attribute)": [[3, "datasketches.theta_sketch.get_seed_hash", false]], "get_seed_hash (tuple_sketch attribute)": [[4, "datasketches.tuple_sketch.get_seed_hash", false]], "get_serialized_size_bytes (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.get_serialized_size_bytes", false]], "get_serialized_size_bytes (ebpps_sketch attribute)": [[19, "datasketches.ebpps_sketch.get_serialized_size_bytes", false]], "get_serialized_size_bytes (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.get_serialized_size_bytes", false]], "get_serialized_size_bytes (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.get_serialized_size_bytes", false]], "get_serialized_size_bytes (var_opt_sketch attribute)": [[21, "datasketches.var_opt_sketch.get_serialized_size_bytes", false]], "get_serialized_size_bytes (var_opt_union attribute)": [[21, "datasketches.var_opt_union.get_serialized_size_bytes", false]], "get_size() (pyobjectserde method)": [[12, "datasketches.PyObjectSerDe.get_size", false]], "get_updatable_serialization_bytes (hll_sketch attribute)": [[1, "datasketches.hll_sketch.get_updatable_serialization_bytes", false]], "get_upper_bound (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.get_upper_bound", false]], "get_upper_bound (cpc_sketch attribute)": [[0, "datasketches.cpc_sketch.get_upper_bound", false]], "get_upper_bound (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.get_upper_bound", false]], "get_upper_bound (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.get_upper_bound", false]], "get_upper_bound (hll_sketch attribute)": [[1, "datasketches.hll_sketch.get_upper_bound", false]], "get_upper_bound (hll_union attribute)": [[1, "datasketches.hll_union.get_upper_bound", false]], "get_upper_bound (theta_sketch attribute)": [[3, "datasketches.theta_sketch.get_upper_bound", false]], "get_upper_bound (tuple_sketch attribute)": [[4, "datasketches.tuple_sketch.get_upper_bound", false]], "has_result (theta_intersection attribute)": [[3, "datasketches.theta_intersection.has_result", false]], "has_result (tuple_intersection attribute)": [[4, "datasketches.tuple_intersection.has_result", false]], "hll_4 (tgt_hll_type attribute)": [[1, "datasketches.tgt_hll_type.HLL_4", false]], "hll_6 (tgt_hll_type attribute)": [[1, "datasketches.tgt_hll_type.HLL_6", false]], "hll_8 (tgt_hll_type attribute)": [[1, "datasketches.tgt_hll_type.HLL_8", false]], "hll_sketch (class in _datasketches)": [[1, "datasketches.hll_sketch", false]], "hll_union (class in _datasketches)": [[1, "datasketches.hll_union", false]], "is_compact (hll_sketch attribute)": [[1, "datasketches.hll_sketch.is_compact", false]], "is_empty (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.is_empty", false]], "is_empty (cpc_sketch attribute)": [[0, "datasketches.cpc_sketch.is_empty", false]], "is_empty (density_sketch attribute)": [[22, "datasketches.density_sketch.is_empty", false]], "is_empty (ebpps_sketch attribute)": [[19, "datasketches.ebpps_sketch.is_empty", false]], "is_empty (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.is_empty", false]], "is_empty (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.is_empty", false]], "is_empty (hll_sketch attribute)": [[1, "datasketches.hll_sketch.is_empty", false]], "is_empty (hll_union attribute)": [[1, "datasketches.hll_union.is_empty", false]], "is_empty (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.is_empty", false]], "is_empty (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.is_empty", false]], "is_empty (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.is_empty", false]], "is_empty (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.is_empty", false]], "is_empty (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.is_empty", false]], "is_empty (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.is_empty", false]], "is_empty (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.is_empty", false]], "is_empty (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.is_empty", false]], "is_empty (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.is_empty", false]], "is_empty (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.is_empty", false]], "is_empty (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.is_empty", false]], "is_empty (theta_sketch attribute)": [[3, "datasketches.theta_sketch.is_empty", false]], "is_empty (tuple_sketch attribute)": [[4, "datasketches.tuple_sketch.is_empty", false]], "is_empty (var_opt_sketch attribute)": [[21, "datasketches.var_opt_sketch.is_empty", false]], "is_estimation_mode (density_sketch attribute)": [[22, "datasketches.density_sketch.is_estimation_mode", false]], "is_estimation_mode (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.is_estimation_mode", false]], "is_estimation_mode (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.is_estimation_mode", false]], "is_estimation_mode (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.is_estimation_mode", false]], "is_estimation_mode (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.is_estimation_mode", false]], "is_estimation_mode (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.is_estimation_mode", false]], "is_estimation_mode (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.is_estimation_mode", false]], "is_estimation_mode (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.is_estimation_mode", false]], "is_estimation_mode (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.is_estimation_mode", false]], "is_estimation_mode (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.is_estimation_mode", false]], "is_estimation_mode (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.is_estimation_mode", false]], "is_estimation_mode (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.is_estimation_mode", false]], "is_estimation_mode (theta_sketch attribute)": [[3, "datasketches.theta_sketch.is_estimation_mode", false]], "is_estimation_mode (tuple_sketch attribute)": [[4, "datasketches.tuple_sketch.is_estimation_mode", false]], "is_hra (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.is_hra", false]], "is_hra (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.is_hra", false]], "is_hra (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.is_hra", false]], "is_ordered (theta_sketch attribute)": [[3, "datasketches.theta_sketch.is_ordered", false]], "is_ordered (tuple_sketch attribute)": [[4, "datasketches.tuple_sketch.is_ordered", false]], "jaccard() (theta_jaccard_similarity method)": [[9, "datasketches.theta_jaccard_similarity.jaccard", false]], "jaccard() (tuple_jaccard_similarity method)": [[9, "datasketches.tuple_jaccard_similarity.jaccard", false]], "k (density_sketch property)": [[22, "datasketches.density_sketch.k", false]], "k (ebpps_sketch property)": [[19, "datasketches.ebpps_sketch.k", false]], "k (kll_doubles_sketch property)": [[16, "datasketches.kll_doubles_sketch.k", false]], "k (kll_floats_sketch property)": [[16, "datasketches.kll_floats_sketch.k", false]], "k (kll_ints_sketch property)": [[16, "datasketches.kll_ints_sketch.k", false]], "k (kll_items_sketch property)": [[16, "datasketches.kll_items_sketch.k", false]], "k (quantiles_doubles_sketch property)": [[17, "datasketches.quantiles_doubles_sketch.k", false]], "k (quantiles_floats_sketch property)": [[17, "datasketches.quantiles_floats_sketch.k", false]], "k (quantiles_ints_sketch property)": [[17, "datasketches.quantiles_ints_sketch.k", false]], "k (quantiles_items_sketch property)": [[17, "datasketches.quantiles_items_sketch.k", false]], "k (req_floats_sketch property)": [[18, "datasketches.req_floats_sketch.k", false]], "k (req_ints_sketch property)": [[18, "datasketches.req_ints_sketch.k", false]], "k (req_items_sketch property)": [[18, "datasketches.req_items_sketch.k", false]], "k (var_opt_sketch property)": [[21, "datasketches.var_opt_sketch.k", false]], "kernelfunction (class in datasketches)": [[10, "datasketches.KernelFunction", false]], "kll_doubles_sketch (class in datasketches)": [[16, "datasketches.kll_doubles_sketch", false]], "kll_floats_sketch (class in datasketches)": [[16, "datasketches.kll_floats_sketch", false]], "kll_ints_sketch (class in datasketches)": [[16, "datasketches.kll_ints_sketch", false]], "kll_items_sketch (class in datasketches)": [[16, "datasketches.kll_items_sketch", false]], "ks_test() (in module datasketches)": [[11, "datasketches.ks_test", false]], "lg_config_k (hll_sketch property)": [[1, "datasketches.hll_sketch.lg_config_k", false]], "lg_config_k (hll_union property)": [[1, "datasketches.hll_union.lg_config_k", false]], "lg_k (cpc_sketch property)": [[0, "datasketches.cpc_sketch.lg_k", false]], "maxintpolicy (class in datasketches)": [[13, "datasketches.MaxIntPolicy", false]], "merge (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.merge", false]], "merge (density_sketch attribute)": [[22, "datasketches.density_sketch.merge", false]], "merge (ebpps_sketch attribute)": [[19, "datasketches.ebpps_sketch.merge", false]], "merge (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.merge", false]], "merge (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.merge", false]], "merge (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.merge", false]], "merge (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.merge", false]], "merge (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.merge", false]], "merge (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.merge", false]], "merge (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.merge", false]], "merge (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.merge", false]], "merge (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.merge", false]], "merge (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.merge", false]], "merge (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.merge", false]], "merge (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.merge", false]], "merge (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.merge", false]], "minintpolicy (class in datasketches)": [[13, "datasketches.MinIntPolicy", false]], "n (density_sketch property)": [[22, "datasketches.density_sketch.n", false]], "n (ebpps_sketch property)": [[19, "datasketches.ebpps_sketch.n", false]], "n (kll_doubles_sketch property)": [[16, "datasketches.kll_doubles_sketch.n", false]], "n (kll_floats_sketch property)": [[16, "datasketches.kll_floats_sketch.n", false]], "n (kll_ints_sketch property)": [[16, "datasketches.kll_ints_sketch.n", false]], "n (kll_items_sketch property)": [[16, "datasketches.kll_items_sketch.n", false]], "n (quantiles_doubles_sketch property)": [[17, "datasketches.quantiles_doubles_sketch.n", false]], "n (quantiles_floats_sketch property)": [[17, "datasketches.quantiles_floats_sketch.n", false]], "n (quantiles_ints_sketch property)": [[17, "datasketches.quantiles_ints_sketch.n", false]], "n (quantiles_items_sketch property)": [[17, "datasketches.quantiles_items_sketch.n", false]], "n (req_floats_sketch property)": [[18, "datasketches.req_floats_sketch.n", false]], "n (req_ints_sketch property)": [[18, "datasketches.req_ints_sketch.n", false]], "n (req_items_sketch property)": [[18, "datasketches.req_items_sketch.n", false]], "n (var_opt_sketch property)": [[21, "datasketches.var_opt_sketch.n", false]], "no_false_negatives (frequent_items_error_type attribute)": [[6, "datasketches.frequent_items_error_type.NO_FALSE_NEGATIVES", false]], "no_false_positives (frequent_items_error_type attribute)": [[6, "datasketches.frequent_items_error_type.NO_FALSE_POSITIVES", false]], "normalized_rank_error (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.normalized_rank_error", false]], "normalized_rank_error (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.normalized_rank_error", false]], "normalized_rank_error (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.normalized_rank_error", false]], "normalized_rank_error (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.normalized_rank_error", false]], "normalized_rank_error (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.normalized_rank_error", false]], "normalized_rank_error (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.normalized_rank_error", false]], "normalized_rank_error (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.normalized_rank_error", false]], "normalized_rank_error (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.normalized_rank_error", false]], "num_active_items (frequent_items_sketch property)": [[6, "datasketches.frequent_items_sketch.num_active_items", false]], "num_active_items (frequent_strings_sketch property)": [[6, "datasketches.frequent_strings_sketch.num_active_items", false]], "num_buckets (count_min_sketch property)": [[5, "datasketches.count_min_sketch.num_buckets", false]], "num_hashes (count_min_sketch property)": [[5, "datasketches.count_min_sketch.num_hashes", false]], "num_retained (density_sketch property)": [[22, "datasketches.density_sketch.num_retained", false]], "num_retained (kll_doubles_sketch property)": [[16, "datasketches.kll_doubles_sketch.num_retained", false]], "num_retained (kll_floats_sketch property)": [[16, "datasketches.kll_floats_sketch.num_retained", false]], "num_retained (kll_ints_sketch property)": [[16, "datasketches.kll_ints_sketch.num_retained", false]], "num_retained (kll_items_sketch property)": [[16, "datasketches.kll_items_sketch.num_retained", false]], "num_retained (quantiles_doubles_sketch property)": [[17, "datasketches.quantiles_doubles_sketch.num_retained", false]], "num_retained (quantiles_floats_sketch property)": [[17, "datasketches.quantiles_floats_sketch.num_retained", false]], "num_retained (quantiles_ints_sketch property)": [[17, "datasketches.quantiles_ints_sketch.num_retained", false]], "num_retained (quantiles_items_sketch property)": [[17, "datasketches.quantiles_items_sketch.num_retained", false]], "num_retained (req_floats_sketch property)": [[18, "datasketches.req_floats_sketch.num_retained", false]], "num_retained (req_ints_sketch property)": [[18, "datasketches.req_ints_sketch.num_retained", false]], "num_retained (req_items_sketch property)": [[18, "datasketches.req_items_sketch.num_retained", false]], "num_retained (theta_sketch property)": [[3, "datasketches.theta_sketch.num_retained", false]], "num_retained (tuple_sketch property)": [[4, "datasketches.tuple_sketch.num_retained", false]], "num_samples (var_opt_sketch property)": [[21, "datasketches.var_opt_sketch.num_samples", false]], "pydoublesserde (class in datasketches)": [[12, "datasketches.PyDoublesSerDe", false]], "pyfloatsserde (class in datasketches)": [[12, "datasketches.PyFloatsSerDe", false]], "pyintsserde (class in datasketches)": [[12, "datasketches.PyIntsSerDe", false]], "pylongsserde (class in datasketches)": [[12, "datasketches.PyLongsSerDe", false]], "pyobjectserde (class in datasketches)": [[12, "datasketches.PyObjectSerDe", false]], "pystringsserde (class in datasketches)": [[12, "datasketches.PyStringsSerDe", false]], "quantiles_doubles_sketch (class in datasketches)": [[17, "datasketches.quantiles_doubles_sketch", false]], "quantiles_floats_sketch (class in datasketches)": [[17, "datasketches.quantiles_floats_sketch", false]], "quantiles_ints_sketch (class in datasketches)": [[17, "datasketches.quantiles_ints_sketch", false]], "quantiles_items_sketch (class in datasketches)": [[17, "datasketches.quantiles_items_sketch", false]], "req_floats_sketch (class in datasketches)": [[18, "datasketches.req_floats_sketch", false]], "req_ints_sketch (class in datasketches)": [[18, "datasketches.req_ints_sketch", false]], "req_items_sketch (class in datasketches)": [[18, "datasketches.req_items_sketch", false]], "reset (hll_sketch attribute)": [[1, "datasketches.hll_sketch.reset", false]], "reset (hll_union attribute)": [[1, "datasketches.hll_union.reset", false]], "reset (tuple_union attribute)": [[4, "datasketches.tuple_union.reset", false]], "reset (update_theta_sketch attribute)": [[3, "datasketches.update_theta_sketch.reset", false]], "reset (update_tuple_sketch attribute)": [[4, "datasketches.update_tuple_sketch.reset", false]], "reset (var_opt_union attribute)": [[21, "datasketches.var_opt_union.reset", false]], "seed (count_min_sketch property)": [[5, "datasketches.count_min_sketch.seed", false]], "serialize (compact_theta_sketch attribute)": [[3, "datasketches.compact_theta_sketch.serialize", false]], "serialize (compact_tuple_sketch attribute)": [[4, "datasketches.compact_tuple_sketch.serialize", false]], "serialize (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.serialize", false]], "serialize (cpc_sketch attribute)": [[0, "datasketches.cpc_sketch.serialize", false]], "serialize (density_sketch attribute)": [[22, "datasketches.density_sketch.serialize", false]], "serialize (ebpps_sketch attribute)": [[19, "datasketches.ebpps_sketch.serialize", false]], "serialize (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.serialize", false]], "serialize (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.serialize", false]], "serialize (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.serialize", false]], "serialize (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.serialize", false]], "serialize (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.serialize", false]], "serialize (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.serialize", false]], "serialize (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.serialize", false]], "serialize (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.serialize", false]], "serialize (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.serialize", false]], "serialize (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.serialize", false]], "serialize (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.serialize", false]], "serialize (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.serialize", false]], "serialize (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.serialize", false]], "serialize (var_opt_sketch attribute)": [[21, "datasketches.var_opt_sketch.serialize", false]], "serialize (var_opt_union attribute)": [[21, "datasketches.var_opt_union.serialize", false]], "serialize_compact (hll_sketch attribute)": [[1, "datasketches.hll_sketch.serialize_compact", false]], "serialize_updatable (hll_sketch attribute)": [[1, "datasketches.hll_sketch.serialize_updatable", false]], "similarity_test() (theta_jaccard_similarity method)": [[9, "datasketches.theta_jaccard_similarity.similarity_test", false]], "similarity_test() (tuple_jaccard_similarity method)": [[9, "datasketches.tuple_jaccard_similarity.similarity_test", false]], "suggest_num_buckets() (count_min_sketch method)": [[5, "datasketches.count_min_sketch.suggest_num_buckets", false]], "suggest_num_hashes() (count_min_sketch method)": [[5, "datasketches.count_min_sketch.suggest_num_hashes", false]], "tgt_hll_type (class in _datasketches)": [[1, "datasketches.tgt_hll_type", false]], "tgt_type (hll_sketch property)": [[1, "datasketches.hll_sketch.tgt_type", false]], "theta (theta_sketch property)": [[3, "datasketches.theta_sketch.theta", false]], "theta (tuple_sketch property)": [[4, "datasketches.tuple_sketch.theta", false]], "theta64 (theta_sketch property)": [[3, "datasketches.theta_sketch.theta64", false]], "theta64 (tuple_sketch property)": [[4, "datasketches.tuple_sketch.theta64", false]], "theta_a_not_b (class in datasketches)": [[3, "datasketches.theta_a_not_b", false]], "theta_intersection (class in datasketches)": [[3, "datasketches.theta_intersection", false]], "theta_jaccard_similarity (class in datasketches)": [[9, "datasketches.theta_jaccard_similarity", false]], "theta_sketch (class in datasketches)": [[3, "datasketches.theta_sketch", false]], "theta_union (class in datasketches)": [[3, "datasketches.theta_union", false]], "to_bytes() (pyobjectserde method)": [[12, "datasketches.PyObjectSerDe.to_bytes", false]], "to_string (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.to_string", false]], "to_string (cpc_sketch attribute)": [[0, "datasketches.cpc_sketch.to_string", false]], "to_string (density_sketch attribute)": [[22, "datasketches.density_sketch.to_string", false]], "to_string (ebpps_sketch attribute)": [[19, "datasketches.ebpps_sketch.to_string", false]], "to_string (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.to_string", false]], "to_string (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.to_string", false]], "to_string (hll_sketch attribute)": [[1, "datasketches.hll_sketch.to_string", false]], "to_string (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.to_string", false]], "to_string (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.to_string", false]], "to_string (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.to_string", false]], "to_string (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.to_string", false]], "to_string (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.to_string", false]], "to_string (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.to_string", false]], "to_string (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.to_string", false]], "to_string (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.to_string", false]], "to_string (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.to_string", false]], "to_string (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.to_string", false]], "to_string (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.to_string", false]], "to_string (theta_sketch attribute)": [[3, "datasketches.theta_sketch.to_string", false]], "to_string (tuple_sketch attribute)": [[4, "datasketches.tuple_sketch.to_string", false]], "to_string (var_opt_sketch attribute)": [[21, "datasketches.var_opt_sketch.to_string", false]], "to_string (var_opt_union attribute)": [[21, "datasketches.var_opt_union.to_string", false]], "total_weight (count_min_sketch property)": [[5, "datasketches.count_min_sketch.total_weight", false]], "total_weight (frequent_items_sketch property)": [[6, "datasketches.frequent_items_sketch.total_weight", false]], "total_weight (frequent_strings_sketch property)": [[6, "datasketches.frequent_strings_sketch.total_weight", false]], "trim (update_theta_sketch attribute)": [[3, "datasketches.update_theta_sketch.trim", false]], "trim (update_tuple_sketch attribute)": [[4, "datasketches.update_tuple_sketch.trim", false]], "tuple_a_not_b (class in datasketches)": [[4, "datasketches.tuple_a_not_b", false]], "tuple_intersection (class in datasketches)": [[4, "datasketches.tuple_intersection", false]], "tuple_jaccard_similarity (class in datasketches)": [[9, "datasketches.tuple_jaccard_similarity", false]], "tuple_sketch (class in datasketches)": [[4, "datasketches.tuple_sketch", false]], "tuple_union (class in datasketches)": [[4, "datasketches.tuple_union", false]], "tuplepolicy (class in datasketches)": [[13, "datasketches.TuplePolicy", false]], "update (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.update", false]], "update (cpc_sketch attribute)": [[0, "datasketches.cpc_sketch.update", false]], "update (cpc_union attribute)": [[0, "datasketches.cpc_union.update", false]], "update (density_sketch attribute)": [[22, "datasketches.density_sketch.update", false]], "update (ebpps_sketch attribute)": [[19, "datasketches.ebpps_sketch.update", false]], "update (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.update", false]], "update (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.update", false]], "update (hll_sketch attribute)": [[1, "datasketches.hll_sketch.update", false]], "update (hll_union attribute)": [[1, "datasketches.hll_union.update", false]], "update (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.update", false]], "update (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.update", false]], "update (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.update", false]], "update (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.update", false]], "update (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.update", false]], "update (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.update", false]], "update (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.update", false]], "update (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.update", false]], "update (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.update", false]], "update (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.update", false]], "update (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.update", false]], "update (theta_intersection attribute)": [[3, "datasketches.theta_intersection.update", false]], "update (theta_union attribute)": [[3, "datasketches.theta_union.update", false]], "update (tuple_intersection attribute)": [[4, "datasketches.tuple_intersection.update", false]], "update (tuple_union attribute)": [[4, "datasketches.tuple_union.update", false]], "update (update_theta_sketch attribute)": [[3, "datasketches.update_theta_sketch.update", false]], "update (update_tuple_sketch attribute)": [[4, "datasketches.update_tuple_sketch.update", false]], "update (var_opt_sketch attribute)": [[21, "datasketches.var_opt_sketch.update", false]], "update (var_opt_union attribute)": [[21, "datasketches.var_opt_union.update", false]], "update_summary() (tuplepolicy method)": [[13, "datasketches.TuplePolicy.update_summary", false]], "update_theta_sketch (class in datasketches)": [[3, "datasketches.update_theta_sketch", false]], "update_tuple_sketch (class in datasketches)": [[4, "datasketches.update_tuple_sketch", false]], "var_opt_sketch (class in datasketches)": [[21, "datasketches.var_opt_sketch", false]], "var_opt_union (class in datasketches)": [[21, "datasketches.var_opt_union", false]]}, "objects": {"_datasketches": [[5, 0, 1, "datasketches.count_min_sketch", "count_min_sketch"], [0, 0, 1, "datasketches.cpc_sketch", "cpc_sketch"], [0, 0, 1, "datasketches.cpc_union", "cpc_union"], [1, 0, 1, "datasketches.hll_sketch", "hll_sketch"], [1, 0, 1, "datasketches.hll_union", "hll_union"], [1, 0, 1, "datasketches.tgt_hll_type", "tgt_hll_type"]], "_datasketches.count_min_sketch": [[5, 1, 1, "datasketches.count_min_sketch.deserialize", "deserialize"], [5, 2, 1, "datasketches.count_min_sketch.get_estimate", "get_estimate"], [5, 2, 1, "datasketches.count_min_sketch.get_lower_bound", "get_lower_bound"], [5, 2, 1, "datasketches.count_min_sketch.get_relative_error", "get_relative_error"], [5, 2, 1, "datasketches.count_min_sketch.get_serialized_size_bytes", "get_serialized_size_bytes"], [5, 2, 1, "datasketches.count_min_sketch.get_upper_bound", "get_upper_bound"], [5, 2, 1, "datasketches.count_min_sketch.is_empty", "is_empty"], [5, 2, 1, "datasketches.count_min_sketch.merge", "merge"], [5, 3, 1, "datasketches.count_min_sketch.num_buckets", "num_buckets"], [5, 3, 1, "datasketches.count_min_sketch.num_hashes", "num_hashes"], [5, 3, 1, "datasketches.count_min_sketch.seed", "seed"], [5, 2, 1, "datasketches.count_min_sketch.serialize", "serialize"], [5, 1, 1, "datasketches.count_min_sketch.suggest_num_buckets", "suggest_num_buckets"], [5, 1, 1, "datasketches.count_min_sketch.suggest_num_hashes", "suggest_num_hashes"], [5, 2, 1, "datasketches.count_min_sketch.to_string", "to_string"], [5, 3, 1, "datasketches.count_min_sketch.total_weight", "total_weight"], [5, 2, 1, "datasketches.count_min_sketch.update", "update"]], "_datasketches.cpc_sketch": [[0, 1, 1, "datasketches.cpc_sketch.__init__", "__init__"], [0, 1, 1, "datasketches.cpc_sketch.deserialize", "deserialize"], [0, 2, 1, "datasketches.cpc_sketch.get_estimate", "get_estimate"], [0, 2, 1, "datasketches.cpc_sketch.get_lower_bound", "get_lower_bound"], [0, 2, 1, "datasketches.cpc_sketch.get_upper_bound", "get_upper_bound"], [0, 2, 1, "datasketches.cpc_sketch.is_empty", "is_empty"], [0, 3, 1, "datasketches.cpc_sketch.lg_k", "lg_k"], [0, 2, 1, "datasketches.cpc_sketch.serialize", "serialize"], [0, 2, 1, "datasketches.cpc_sketch.to_string", "to_string"], [0, 2, 1, "datasketches.cpc_sketch.update", "update"]], "_datasketches.cpc_union": [[0, 1, 1, "datasketches.cpc_union.__init__", "__init__"], [0, 2, 1, "datasketches.cpc_union.get_result", "get_result"], [0, 2, 1, "datasketches.cpc_union.update", "update"]], "_datasketches.hll_sketch": [[1, 1, 1, "datasketches.hll_sketch.__init__", "__init__"], [1, 1, 1, "datasketches.hll_sketch.deserialize", "deserialize"], [1, 2, 1, "datasketches.hll_sketch.get_compact_serialization_bytes", "get_compact_serialization_bytes"], [1, 2, 1, "datasketches.hll_sketch.get_estimate", "get_estimate"], [1, 2, 1, "datasketches.hll_sketch.get_lower_bound", "get_lower_bound"], [1, 1, 1, "datasketches.hll_sketch.get_max_updatable_serialization_bytes", "get_max_updatable_serialization_bytes"], [1, 1, 1, "datasketches.hll_sketch.get_rel_err", "get_rel_err"], [1, 2, 1, "datasketches.hll_sketch.get_updatable_serialization_bytes", "get_updatable_serialization_bytes"], [1, 2, 1, "datasketches.hll_sketch.get_upper_bound", "get_upper_bound"], [1, 2, 1, "datasketches.hll_sketch.is_compact", "is_compact"], [1, 2, 1, "datasketches.hll_sketch.is_empty", "is_empty"], [1, 3, 1, "datasketches.hll_sketch.lg_config_k", "lg_config_k"], [1, 2, 1, "datasketches.hll_sketch.reset", "reset"], [1, 2, 1, "datasketches.hll_sketch.serialize_compact", "serialize_compact"], [1, 2, 1, "datasketches.hll_sketch.serialize_updatable", "serialize_updatable"], [1, 3, 1, "datasketches.hll_sketch.tgt_type", "tgt_type"], [1, 2, 1, "datasketches.hll_sketch.to_string", "to_string"], [1, 2, 1, "datasketches.hll_sketch.update", "update"]], "_datasketches.hll_union": [[1, 1, 1, "datasketches.hll_union.__init__", "__init__"], [1, 2, 1, "datasketches.hll_union.get_estimate", "get_estimate"], [1, 2, 1, "datasketches.hll_union.get_lower_bound", "get_lower_bound"], [1, 1, 1, "datasketches.hll_union.get_rel_err", "get_rel_err"], [1, 2, 1, "datasketches.hll_union.get_result", "get_result"], [1, 2, 1, "datasketches.hll_union.get_upper_bound", "get_upper_bound"], [1, 2, 1, "datasketches.hll_union.is_empty", "is_empty"], [1, 3, 1, "datasketches.hll_union.lg_config_k", "lg_config_k"], [1, 2, 1, "datasketches.hll_union.reset", "reset"], [1, 2, 1, "datasketches.hll_union.update", "update"]], "_datasketches.tgt_hll_type": [[1, 2, 1, "datasketches.tgt_hll_type.HLL_4", "HLL_4"], [1, 2, 1, "datasketches.tgt_hll_type.HLL_6", "HLL_6"], [1, 2, 1, "datasketches.tgt_hll_type.HLL_8", "HLL_8"]], "datasketches": [[13, 0, 1, "", "AccumulatorPolicy"], [10, 0, 1, "", "GaussianKernel"], [10, 0, 1, "", "KernelFunction"], [13, 0, 1, "", "MaxIntPolicy"], [13, 0, 1, "", "MinIntPolicy"], [12, 0, 1, "", "PyDoublesSerDe"], [12, 0, 1, "", "PyFloatsSerDe"], [12, 0, 1, "", "PyIntsSerDe"], [12, 0, 1, "", "PyLongsSerDe"], [12, 0, 1, "", "PyObjectSerDe"], [12, 0, 1, "", "PyStringsSerDe"], [13, 0, 1, "", "TuplePolicy"], [3, 0, 1, "", "compact_theta_sketch"], [4, 0, 1, "", "compact_tuple_sketch"], [22, 0, 1, "", "density_sketch"], [19, 0, 1, "", "ebpps_sketch"], [6, 0, 1, "", "frequent_items_error_type"], [6, 0, 1, "", "frequent_items_sketch"], [6, 0, 1, "", "frequent_strings_sketch"], [16, 0, 1, "", "kll_doubles_sketch"], [16, 0, 1, "", "kll_floats_sketch"], [16, 0, 1, "", "kll_ints_sketch"], [16, 0, 1, "", "kll_items_sketch"], [11, 4, 1, "", "ks_test"], [17, 0, 1, "", "quantiles_doubles_sketch"], [17, 0, 1, "", "quantiles_floats_sketch"], [17, 0, 1, "", "quantiles_ints_sketch"], [17, 0, 1, "", "quantiles_items_sketch"], [18, 0, 1, "", "req_floats_sketch"], [18, 0, 1, "", "req_ints_sketch"], [18, 0, 1, "", "req_items_sketch"], [3, 0, 1, "", "theta_a_not_b"], [3, 0, 1, "", "theta_intersection"], [9, 0, 1, "", "theta_jaccard_similarity"], [3, 0, 1, "", "theta_sketch"], [3, 0, 1, "", "theta_union"], [4, 0, 1, "", "tuple_a_not_b"], [4, 0, 1, "", "tuple_intersection"], [9, 0, 1, "", "tuple_jaccard_similarity"], [4, 0, 1, "", "tuple_sketch"], [4, 0, 1, "", "tuple_union"], [3, 0, 1, "", "update_theta_sketch"], [4, 0, 1, "", "update_tuple_sketch"], [21, 0, 1, "", "var_opt_sketch"], [21, 0, 1, "", "var_opt_union"]], "datasketches.KernelFunction": [[10, 1, 1, "", "__call__"]], "datasketches.PyObjectSerDe": [[12, 1, 1, "", "from_bytes"], [12, 1, 1, "", "get_size"], [12, 1, 1, "", "to_bytes"]], "datasketches.TuplePolicy": [[13, 1, 1, "", "__call__"], [13, 1, 1, "", "create_summary"], [13, 1, 1, "", "update_summary"]], "datasketches.compact_theta_sketch": [[3, 1, 1, "", "__init__"], [3, 1, 1, "", "deserialize"], [3, 2, 1, "", "serialize"]], "datasketches.compact_tuple_sketch": [[4, 1, 1, "", "__init__"], [4, 1, 1, "", "deserialize"], [4, 2, 1, "", "serialize"]], "datasketches.density_sketch": [[22, 1, 1, "", "__init__"], [22, 1, 1, "", "deserialize"], [22, 3, 1, "", "dim"], [22, 2, 1, "", "get_estimate"], [22, 2, 1, "", "is_empty"], [22, 2, 1, "", "is_estimation_mode"], [22, 3, 1, "", "k"], [22, 2, 1, "", "merge"], [22, 3, 1, "", "n"], [22, 3, 1, "", "num_retained"], [22, 2, 1, "", "serialize"], [22, 2, 1, "", "to_string"], [22, 2, 1, "", "update"]], "datasketches.ebpps_sketch": [[19, 1, 1, "", "__init__"], [19, 3, 1, "", "c"], [19, 1, 1, "", "deserialize"], [19, 2, 1, "", "get_serialized_size_bytes"], [19, 2, 1, "", "is_empty"], [19, 3, 1, "", "k"], [19, 2, 1, "", "merge"], [19, 3, 1, "", "n"], [19, 2, 1, "", "serialize"], [19, 2, 1, "", "to_string"], [19, 2, 1, "", "update"]], "datasketches.frequent_items_error_type": [[6, 2, 1, "", "NO_FALSE_NEGATIVES"], [6, 2, 1, "", "NO_FALSE_POSITIVES"]], "datasketches.frequent_items_sketch": [[6, 1, 1, "", "__init__"], [6, 1, 1, "", "deserialize"], [6, 3, 1, "", "epsilon"], [6, 1, 1, "", "get_apriori_error"], [6, 1, 1, "", "get_epsilon_for_lg_size"], [6, 2, 1, "", "get_estimate"], [6, 2, 1, "", "get_frequent_items"], [6, 2, 1, "", "get_lower_bound"], [6, 2, 1, "", "get_serialized_size_bytes"], [6, 2, 1, "", "get_upper_bound"], [6, 2, 1, "", "is_empty"], [6, 2, 1, "", "merge"], [6, 3, 1, "", "num_active_items"], [6, 2, 1, "", "serialize"], [6, 2, 1, "", "to_string"], [6, 3, 1, "", "total_weight"], [6, 2, 1, "", "update"]], "datasketches.frequent_strings_sketch": [[6, 1, 1, "", "__init__"], [6, 1, 1, "", "deserialize"], [6, 3, 1, "", "epsilon"], [6, 1, 1, "", "get_apriori_error"], [6, 1, 1, "", "get_epsilon_for_lg_size"], [6, 2, 1, "", "get_estimate"], [6, 2, 1, "", "get_frequent_items"], [6, 2, 1, "", "get_lower_bound"], [6, 2, 1, "", "get_serialized_size_bytes"], [6, 2, 1, "", "get_upper_bound"], [6, 2, 1, "", "is_empty"], [6, 2, 1, "", "merge"], [6, 3, 1, "", "num_active_items"], [6, 2, 1, "", "serialize"], [6, 2, 1, "", "to_string"], [6, 3, 1, "", "total_weight"], [6, 2, 1, "", "update"]], "datasketches.kll_doubles_sketch": [[16, 1, 1, "", "__init__"], [16, 1, 1, "", "deserialize"], [16, 2, 1, "", "get_cdf"], [16, 2, 1, "", "get_max_value"], [16, 2, 1, "", "get_min_value"], [16, 1, 1, "", "get_normalized_rank_error"], [16, 2, 1, "", "get_pmf"], [16, 2, 1, "", "get_quantile"], [16, 2, 1, "", "get_quantiles"], [16, 2, 1, "", "get_rank"], [16, 2, 1, "", "is_empty"], [16, 2, 1, "", "is_estimation_mode"], [16, 3, 1, "", "k"], [16, 2, 1, "", "merge"], [16, 3, 1, "", "n"], [16, 2, 1, "", "normalized_rank_error"], [16, 3, 1, "", "num_retained"], [16, 2, 1, "", "serialize"], [16, 2, 1, "", "to_string"], [16, 2, 1, "", "update"]], "datasketches.kll_floats_sketch": [[16, 1, 1, "", "__init__"], [16, 1, 1, "", "deserialize"], [16, 2, 1, "", "get_cdf"], [16, 2, 1, "", "get_max_value"], [16, 2, 1, "", "get_min_value"], [16, 1, 1, "", "get_normalized_rank_error"], [16, 2, 1, "", "get_pmf"], [16, 2, 1, "", "get_quantile"], [16, 2, 1, "", "get_quantiles"], [16, 2, 1, "", "get_rank"], [16, 2, 1, "", "is_empty"], [16, 2, 1, "", "is_estimation_mode"], [16, 3, 1, "", "k"], [16, 2, 1, "", "merge"], [16, 3, 1, "", "n"], [16, 2, 1, "", "normalized_rank_error"], [16, 3, 1, "", "num_retained"], [16, 2, 1, "", "serialize"], [16, 2, 1, "", "to_string"], [16, 2, 1, "", "update"]], "datasketches.kll_ints_sketch": [[16, 1, 1, "", "__init__"], [16, 1, 1, "", "deserialize"], [16, 2, 1, "", "get_cdf"], [16, 2, 1, "", "get_max_value"], [16, 2, 1, "", "get_min_value"], [16, 1, 1, "", "get_normalized_rank_error"], [16, 2, 1, "", "get_pmf"], [16, 2, 1, "", "get_quantile"], [16, 2, 1, "", "get_quantiles"], [16, 2, 1, "", "get_rank"], [16, 2, 1, "", "is_empty"], [16, 2, 1, "", "is_estimation_mode"], [16, 3, 1, "", "k"], [16, 2, 1, "", "merge"], [16, 3, 1, "", "n"], [16, 2, 1, "", "normalized_rank_error"], [16, 3, 1, "", "num_retained"], [16, 2, 1, "", "serialize"], [16, 2, 1, "", "to_string"], [16, 2, 1, "", "update"]], "datasketches.kll_items_sketch": [[16, 1, 1, "", "__init__"], [16, 1, 1, "", "deserialize"], [16, 2, 1, "", "get_cdf"], [16, 2, 1, "", "get_max_value"], [16, 2, 1, "", "get_min_value"], [16, 1, 1, "", "get_normalized_rank_error"], [16, 2, 1, "", "get_pmf"], [16, 2, 1, "", "get_quantile"], [16, 2, 1, "", "get_quantiles"], [16, 2, 1, "", "get_rank"], [16, 2, 1, "", "is_empty"], [16, 2, 1, "", "is_estimation_mode"], [16, 3, 1, "", "k"], [16, 2, 1, "", "merge"], [16, 3, 1, "", "n"], [16, 2, 1, "", "normalized_rank_error"], [16, 3, 1, "", "num_retained"], [16, 2, 1, "", "serialize"], [16, 2, 1, "", "to_string"], [16, 2, 1, "", "update"]], "datasketches.quantiles_doubles_sketch": [[17, 1, 1, "", "__init__"], [17, 1, 1, "", "deserialize"], [17, 2, 1, "", "get_cdf"], [17, 2, 1, "", "get_max_value"], [17, 2, 1, "", "get_min_value"], [17, 1, 1, "", "get_normalized_rank_error"], [17, 2, 1, "", "get_pmf"], [17, 2, 1, "", "get_quantile"], [17, 2, 1, "", "get_quantiles"], [17, 2, 1, "", "get_rank"], [17, 2, 1, "", "is_empty"], [17, 2, 1, "", "is_estimation_mode"], [17, 3, 1, "", "k"], [17, 2, 1, "", "merge"], [17, 3, 1, "", "n"], [17, 2, 1, "", "normalized_rank_error"], [17, 3, 1, "", "num_retained"], [17, 2, 1, "", "serialize"], [17, 2, 1, "", "to_string"], [17, 2, 1, "", "update"]], "datasketches.quantiles_floats_sketch": [[17, 1, 1, "", "__init__"], [17, 1, 1, "", "deserialize"], [17, 2, 1, "", "get_cdf"], [17, 2, 1, "", "get_max_value"], [17, 2, 1, "", "get_min_value"], [17, 1, 1, "", "get_normalized_rank_error"], [17, 2, 1, "", "get_pmf"], [17, 2, 1, "", "get_quantile"], [17, 2, 1, "", "get_quantiles"], [17, 2, 1, "", "get_rank"], [17, 2, 1, "", "is_empty"], [17, 2, 1, "", "is_estimation_mode"], [17, 3, 1, "", "k"], [17, 2, 1, "", "merge"], [17, 3, 1, "", "n"], [17, 2, 1, "", "normalized_rank_error"], [17, 3, 1, "", "num_retained"], [17, 2, 1, "", "serialize"], [17, 2, 1, "", "to_string"], [17, 2, 1, "", "update"]], "datasketches.quantiles_ints_sketch": [[17, 1, 1, "", "__init__"], [17, 1, 1, "", "deserialize"], [17, 2, 1, "", "get_cdf"], [17, 2, 1, "", "get_max_value"], [17, 2, 1, "", "get_min_value"], [17, 1, 1, "", "get_normalized_rank_error"], [17, 2, 1, "", "get_pmf"], [17, 2, 1, "", "get_quantile"], [17, 2, 1, "", "get_quantiles"], [17, 2, 1, "", "get_rank"], [17, 2, 1, "", "is_empty"], [17, 2, 1, "", "is_estimation_mode"], [17, 3, 1, "", "k"], [17, 2, 1, "", "merge"], [17, 3, 1, "", "n"], [17, 2, 1, "", "normalized_rank_error"], [17, 3, 1, "", "num_retained"], [17, 2, 1, "", "serialize"], [17, 2, 1, "", "to_string"], [17, 2, 1, "", "update"]], "datasketches.quantiles_items_sketch": [[17, 1, 1, "", "__init__"], [17, 1, 1, "", "deserialize"], [17, 2, 1, "", "get_cdf"], [17, 2, 1, "", "get_max_value"], [17, 2, 1, "", "get_min_value"], [17, 1, 1, "", "get_normalized_rank_error"], [17, 2, 1, "", "get_pmf"], [17, 2, 1, "", "get_quantile"], [17, 2, 1, "", "get_quantiles"], [17, 2, 1, "", "get_rank"], [17, 2, 1, "", "is_empty"], [17, 2, 1, "", "is_estimation_mode"], [17, 3, 1, "", "k"], [17, 2, 1, "", "merge"], [17, 3, 1, "", "n"], [17, 2, 1, "", "normalized_rank_error"], [17, 3, 1, "", "num_retained"], [17, 2, 1, "", "serialize"], [17, 2, 1, "", "to_string"], [17, 2, 1, "", "update"]], "datasketches.req_floats_sketch": [[18, 1, 1, "", "__init__"], [18, 1, 1, "", "deserialize"], [18, 1, 1, "", "get_RSE"], [18, 2, 1, "", "get_cdf"], [18, 2, 1, "", "get_max_value"], [18, 2, 1, "", "get_min_value"], [18, 2, 1, "", "get_pmf"], [18, 2, 1, "", "get_quantile"], [18, 2, 1, "", "get_quantiles"], [18, 2, 1, "", "get_rank"], [18, 2, 1, "", "get_rank_lower_bound"], [18, 2, 1, "", "get_rank_upper_bound"], [18, 2, 1, "", "is_empty"], [18, 2, 1, "", "is_estimation_mode"], [18, 2, 1, "", "is_hra"], [18, 3, 1, "", "k"], [18, 2, 1, "", "merge"], [18, 3, 1, "", "n"], [18, 3, 1, "", "num_retained"], [18, 2, 1, "", "serialize"], [18, 2, 1, "", "to_string"], [18, 2, 1, "", "update"]], "datasketches.req_ints_sketch": [[18, 1, 1, "", "__init__"], [18, 1, 1, "", "deserialize"], [18, 1, 1, "", "get_RSE"], [18, 2, 1, "", "get_cdf"], [18, 2, 1, "", "get_max_value"], [18, 2, 1, "", "get_min_value"], [18, 2, 1, "", "get_pmf"], [18, 2, 1, "", "get_quantile"], [18, 2, 1, "", "get_quantiles"], [18, 2, 1, "", "get_rank"], [18, 2, 1, "", "get_rank_lower_bound"], [18, 2, 1, "", "get_rank_upper_bound"], [18, 2, 1, "", "is_empty"], [18, 2, 1, "", "is_estimation_mode"], [18, 2, 1, "", "is_hra"], [18, 3, 1, "", "k"], [18, 2, 1, "", "merge"], [18, 3, 1, "", "n"], [18, 3, 1, "", "num_retained"], [18, 2, 1, "", "serialize"], [18, 2, 1, "", "to_string"], [18, 2, 1, "", "update"]], "datasketches.req_items_sketch": [[18, 1, 1, "", "__init__"], [18, 1, 1, "", "deserialize"], [18, 1, 1, "", "get_RSE"], [18, 2, 1, "", "get_cdf"], [18, 2, 1, "", "get_max_value"], [18, 2, 1, "", "get_min_value"], [18, 2, 1, "", "get_pmf"], [18, 2, 1, "", "get_quantile"], [18, 2, 1, "", "get_quantiles"], [18, 2, 1, "", "get_rank"], [18, 2, 1, "", "get_rank_lower_bound"], [18, 2, 1, "", "get_rank_upper_bound"], [18, 2, 1, "", "is_empty"], [18, 2, 1, "", "is_estimation_mode"], [18, 2, 1, "", "is_hra"], [18, 3, 1, "", "k"], [18, 2, 1, "", "merge"], [18, 3, 1, "", "n"], [18, 3, 1, "", "num_retained"], [18, 2, 1, "", "serialize"], [18, 2, 1, "", "to_string"], [18, 2, 1, "", "update"]], "datasketches.theta_a_not_b": [[3, 1, 1, "", "__init__"], [3, 2, 1, "", "compute"]], "datasketches.theta_intersection": [[3, 1, 1, "", "__init__"], [3, 2, 1, "", "get_result"], [3, 2, 1, "", "has_result"], [3, 2, 1, "", "update"]], "datasketches.theta_jaccard_similarity": [[9, 1, 1, "", "dissimilarity_test"], [9, 1, 1, "", "exactly_equal"], [9, 1, 1, "", "jaccard"], [9, 1, 1, "", "similarity_test"]], "datasketches.theta_sketch": [[3, 2, 1, "", "get_estimate"], [3, 2, 1, "", "get_lower_bound"], [3, 2, 1, "", "get_seed_hash"], [3, 2, 1, "", "get_upper_bound"], [3, 2, 1, "", "is_empty"], [3, 2, 1, "", "is_estimation_mode"], [3, 2, 1, "", "is_ordered"], [3, 3, 1, "", "num_retained"], [3, 3, 1, "", "theta"], [3, 3, 1, "", "theta64"], [3, 2, 1, "", "to_string"]], "datasketches.theta_union": [[3, 1, 1, "", "__init__"], [3, 2, 1, "", "get_result"], [3, 2, 1, "", "update"]], "datasketches.tuple_a_not_b": [[4, 1, 1, "", "__init__"], [4, 2, 1, "", "compute"]], "datasketches.tuple_intersection": [[4, 1, 1, "", "__init__"], [4, 2, 1, "", "get_result"], [4, 2, 1, "", "has_result"], [4, 2, 1, "", "update"]], "datasketches.tuple_jaccard_similarity": [[9, 1, 1, "", "dissimilarity_test"], [9, 1, 1, "", "exactly_equal"], [9, 1, 1, "", "jaccard"], [9, 1, 1, "", "similarity_test"]], "datasketches.tuple_sketch": [[4, 2, 1, "", "DEFAULT_SEED"], [4, 2, 1, "", "get_estimate"], [4, 2, 1, "", "get_lower_bound"], [4, 2, 1, "", "get_seed_hash"], [4, 2, 1, "", "get_upper_bound"], [4, 2, 1, "", "is_empty"], [4, 2, 1, "", "is_estimation_mode"], [4, 2, 1, "", "is_ordered"], [4, 3, 1, "", "num_retained"], [4, 3, 1, "", "theta"], [4, 3, 1, "", "theta64"], [4, 2, 1, "", "to_string"]], "datasketches.tuple_union": [[4, 1, 1, "", "__init__"], [4, 2, 1, "", "get_result"], [4, 2, 1, "", "reset"], [4, 2, 1, "", "update"]], "datasketches.update_theta_sketch": [[3, 1, 1, "", "__init__"], [3, 2, 1, "", "compact"], [3, 2, 1, "", "reset"], [3, 2, 1, "", "trim"], [3, 2, 1, "", "update"]], "datasketches.update_tuple_sketch": [[4, 1, 1, "", "__init__"], [4, 2, 1, "", "compact"], [4, 2, 1, "", "reset"], [4, 2, 1, "", "trim"], [4, 2, 1, "", "update"]], "datasketches.var_opt_sketch": [[21, 1, 1, "", "__init__"], [21, 1, 1, "", "deserialize"], [21, 2, 1, "", "estimate_subset_sum"], [21, 2, 1, "", "get_serialized_size_bytes"], [21, 2, 1, "", "is_empty"], [21, 3, 1, "", "k"], [21, 3, 1, "", "n"], [21, 3, 1, "", "num_samples"], [21, 2, 1, "", "serialize"], [21, 2, 1, "", "to_string"], [21, 2, 1, "", "update"]], "datasketches.var_opt_union": [[21, 1, 1, "", "__init__"], [21, 1, 1, "", "deserialize"], [21, 2, 1, "", "get_result"], [21, 2, 1, "", "get_serialized_size_bytes"], [21, 2, 1, "", "reset"], [21, 2, 1, "", "serialize"], [21, 2, 1, "", "to_string"], [21, 2, 1, "", "update"]]}, "objnames": {"0": ["py", "class", "Python class"], "1": ["py", "method", "Python method"], "2": ["py", "attribute", "Python attribute"], "3": ["py", "property", "Python property"], "4": ["py", "function", "Python function"]}, "objtypes": {"0": "py:class", "1": "py:method", "2": "py:attribute", "3": "py:property", "4": "py:function"}, "terms": {"": [1, 6, 19, 20, 21], "0": [3, 4, 5, 6, 10, 16, 17, 18], "01668v2": 18, "05": 5, "1": [0, 1, 3, 4, 5, 6, 10, 16, 17, 18], "10": [1, 17], "100": 17, "1000": 17, "11": 0, "12": [3, 4, 18], "128": 17, "13": 16, "14": 6, "16": 1, "18": 6, "1982": 6, "1985": 2, "1e": 6, "1e9": 6, "2": [0, 1, 3, 4, 6, 17, 18], "20": 17, "200": 16, "2002": 6, "2003": 6, "2004": 18, "2006": 6, "2020": 16, "2021": 17, "2023": 19, "21": 1, "3": [0, 1, 3, 4, 6, 17, 18], "30": 17, "32": [12, 16], "33": 16, "4": [1, 12, 17], "40": 17, "47": 16, "483": 17, "5": [5, 6, 17], "500": 17, "50th": 17, "517": 17, "6": 1, "64": [0, 3, 4, 5, 12, 17], "65": 16, "7": [1, 9, 17], "75": 6, "8": [1, 6, 12], "80": 11, "900": 17, "9001": [0, 3, 4, 9], "93smirnov_test": 11, "95": [5, 17], "95th": 17, "97": 9, "99": [16, 17], "A": [1, 3, 4, 6, 10, 11, 12, 13, 16, 17, 21], "As": [0, 16, 17], "For": [0, 1, 5, 6, 16, 17, 18, 23], "If": [1, 6, 9, 16, 17, 18], "In": [0, 1, 16, 19], "It": [3, 16, 17, 18], "One": 2, "That": 15, "The": [0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 22], "Then": 16, "There": [3, 6], "These": [1, 8, 9, 15, 20, 23], "With": [16, 17, 18], "_": 11, "__call__": [10, 13], "__eq__": 6, "__hash__": 6, "__init__": [0, 1, 3, 4, 6, 16, 17, 18, 19, 21, 22], "__lt__": [16, 17, 18], "_datasketch": [0, 1, 3, 4, 5, 6, 9, 11, 16, 17, 18, 19, 21, 22], "ab": 18, "abbadi": 6, "abil": 18, "about": [1, 15, 16, 17], "abov": [7, 16], "absolut": 8, "abstract": [3, 4, 8, 10, 12, 13], "accept": 23, "account": 11, "accumulatori": 13, "accumulatorpolici": 13, "accuraci": [0, 1, 2, 3, 5, 6, 16, 17, 18], "achiev": 5, "activ": [6, 14], "actual": [9, 17], "ad": 13, "add": 16, "addit": [0, 2, 6, 12], "addition": 16, "advanc": 20, "affect": [16, 17], "after": [18, 20], "against": [0, 9], "agraw": 6, "algorithm": [0, 1, 2, 3, 6, 14, 18], "all": [1, 3, 6, 12, 13, 15, 16, 17, 19, 21], "alloc": 12, "allow": [0, 4, 12, 13, 18], "along": 6, "also": [0, 3, 10, 14, 15, 17], "altern": 15, "although": [1, 19], "alwai": [6, 13, 16, 17, 19, 20], "an": [0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 12, 13, 15, 16, 17, 18, 19, 20, 21, 22], "analog": [16, 17, 18], "analysi": [4, 11, 16, 17, 18], "analyz": 14, "ani": [3, 4, 5, 6, 7, 13, 16, 17], "anoth": [0, 6, 18], "answer": 15, "appl": 0, "appli": [2, 3, 4, 6, 13, 15, 16, 18, 20, 21], "applic": 2, "approach": 15, "approx": [5, 18], "approxim": [0, 1, 3, 4, 5, 6, 10, 15, 16, 17, 18, 22], "ar": [0, 1, 3, 4, 5, 6, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 20, 23], "arbitrari": [4, 6], "arg": [0, 1, 3, 4, 5, 6, 10, 12, 13, 16, 17, 18, 19, 21, 22], "arg0": 3, "arg1": 3, "around": 16, "arrai": [6, 10, 16, 17, 18], "art": 2, "arxiv": 18, "as_pmf": [16, 17], "associ": [4, 6, 16, 17, 18], "assum": [6, 11], "avail": 16, "avoid": 3, "axi": 16, "b": [3, 4, 10, 19], "back": 0, "background": 6, "backward": [6, 15], "bag": 6, "bandwidth": 10, "base": [0, 1, 2, 3, 4, 5, 6, 8, 10, 12, 13, 18, 19, 20, 22], "basi": 10, "basic": [3, 4, 10], "becaus": 16, "been": [7, 16, 17, 18, 21], "befor": [6, 7], "behavior": 1, "being": 20, "below": 16, "best": [16, 17], "better": [1, 2, 3], "between": [1, 3, 4, 6, 8, 9, 16, 17, 18, 22], "beyond": 3, "big": 14, "bin": [0, 16], "binari": [12, 16, 17], "bit": [0, 1, 3, 4, 5, 12, 16, 17], "blob": 22, "bool": [1, 3, 4, 9, 11, 16, 17, 18], "both": [11, 18, 20], "bound": [0, 1, 3, 4, 5, 6, 9, 14, 15, 16, 18, 20, 21], "bracket": 16, "bucket": [1, 5], "build": 22, "byte": [0, 1, 3, 4, 5, 6, 12, 16, 17, 18, 19, 21, 22], "c": [0, 19], "call": [16, 19], "came": 2, "can": [0, 1, 3, 4, 6, 11, 13, 15, 16, 17, 18], "cannot": 16, "capabl": [0, 6, 18], "capac": 6, "cardin": [0, 3], "case": [1, 6, 8, 17, 19], "caus": 6, "cdf": [15, 16, 17, 18], "certain": [7, 8, 10, 16, 19], "choic": 1, "choos": 18, "class": [0, 1, 3, 4, 5, 6, 9, 10, 12, 13, 16, 17, 18, 19, 21, 22], "classic": [15, 17], "close": 7, "cm": 5, "code": [6, 18], "collect": 1, "com": 22, "combin": [8, 13], "come": [11, 17], "commonli": [6, 16], "compact": [1, 3, 4, 16, 18], "compact_theta_sketch": 3, "compact_tuple_sketch": 4, "compactor": 18, "compar": [0, 16, 17, 18], "comparison": [0, 18], "compat": [6, 12, 15, 16, 17], "complic": 4, "compress": [1, 2, 14], "comput": [3, 4, 6, 8, 9, 15, 19, 21, 22], "concept": 2, "concret": 8, "confid": [5, 9, 16, 17], "configur": [0, 1, 5, 16, 17, 18, 19, 21, 22], "consecut": [16, 17, 18], "consid": [9, 17], "consist": 13, "constant": [1, 6, 16, 17, 18], "construct": [1, 18, 21], "consum": [1, 12], "contain": [3, 6, 7], "context": 10, "contrast": [5, 19], "control": [16, 17, 18, 22], "coreset": 22, "cormod": [5, 18], "correspond": [0, 1, 3, 4, 5, 6, 16, 17, 18, 19, 21, 22], "cost": [1, 12], "could": [16, 17, 18], "count": [1, 3, 4, 6, 17, 18], "count_min_sketch": [5, 7], "counter": 6, "countmin": [7, 14], "coupon": 1, "cpc": [1, 2, 14], "cpc_sketch": [0, 2], "cpc_union": 0, "creat": [0, 3, 4, 6, 13, 16, 17, 18, 19, 21, 22], "create_summari": 13, "creation": 19, "criterion": 18, "critic": 12, "cross": [12, 17], "cumul": [15, 16, 17, 18], "current": [1, 3, 4, 5, 6, 7, 11, 15, 19, 21], "custom": [4, 10, 12, 13], "data": [2, 6, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 22], "datasketch": [2, 11], "datum": [0, 1, 3, 4], "debug": 18, "decreas": [15, 18], "decrement": 6, "dedic": [3, 4], "default": [1, 3, 4, 10, 16, 17, 18], "default_se": 4, "defin": [3, 4, 6, 10, 16, 19], "definit": [16, 17, 18], "delta": 5, "demain": 6, "denot": [5, 6], "densiti": [8, 10, 14, 23], "density_sketch": [10, 22, 23], "depend": [5, 16], "deprec": [14, 15], "deriv": [3, 16, 17, 18], "describ": [0, 5, 18], "deseri": [0, 1, 3, 4, 5, 6, 8, 14, 16, 17, 18, 19, 21, 22], "design": [15, 23], "desing": 21, "detail": [18, 20], "determin": [7, 11], "determinist": 6, "develop": [0, 14], "deviat": [0, 1, 3, 4, 18], "differ": [0, 1, 2, 3, 6, 12, 13, 18, 20], "dim": 22, "dimac": 5, "dimens": [0, 22], "dimension": 16, "discov": 6, "discrep": 22, "discuss": 18, "disjoint": [16, 17, 18], "dissimilar": 9, "dissimilarity_test": 9, "distanc": 22, "distinct": [0, 1, 3, 4, 6], "distribut": [1, 11, 15, 16, 17, 18], "divid": [16, 17, 18], "do": 6, "document": 16, "doe": [0, 5, 6, 7, 16, 18, 20], "domain": 16, "doubl": [16, 17, 18, 19], "dtype": [16, 17, 18], "dure": 1, "e": 15, "e2": 11, "each": [1, 2, 4, 6, 11, 12, 13, 15, 16, 17, 18, 20], "earliest": 2, "easili": [3, 4], "ebpp": [14, 20], "ebpps_sketch": [19, 20], "edg": [16, 17], "edo": [18, 22], "edoliberti": 22, "edu": 5, "effect": [3, 4], "effici": [0, 3, 6, 14], "either": [6, 15, 16, 17, 18], "element": [2, 6], "els": 18, "empir": [0, 16, 17, 18], "emploi": 6, "empti": [0, 1, 3, 4, 6, 16, 17, 18, 19, 21, 22], "en": 11, "enabl": [16, 17], "encod": 12, "end": 15, "endian": 12, "enough": 1, "ensur": [6, 19, 20], "entir": [7, 15, 20], "entri": [1, 3, 4, 6], "entropi": 0, "ep": 16, "epsilon": [6, 16], "equal": [11, 15, 16, 17, 18, 19], "equival": [9, 16, 17, 19, 21], "error": [1, 3, 5, 6, 8, 11, 14, 15, 16, 17, 19, 21, 22], "estim": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 16, 17, 18, 21, 22, 23], "estimate_subset_sum": 21, "estimated_total_stream_weight": 6, "estimated_total_weight": 6, "evalu": 10, "even": [0, 20], "everi": [3, 4, 5, 6], "exact": [6, 14, 20], "exactli": [19, 20], "exactly_equ": 9, "exampl": [4, 5, 6, 8, 10, 12, 17], "exce": [6, 18, 19], "except": [1, 16, 17, 18], "excess": [3, 4], "exclud": 6, "exclus": [16, 17, 18], "exist": [3, 4, 13], "expect": [9, 19], "expens": 6, "express": 18, "extend": [12, 13], "extens": [4, 18], "extern": 6, "extrem": [0, 6], "f688c8161a25582457b0a09deb4630a81406293b": 22, "f_x": 5, "factor": 18, "failur": 5, "fals": [0, 1, 3, 4, 5, 6, 9, 11, 16, 17, 18, 19, 21, 22], "famili": [1, 8, 11], "far": [6, 15, 16, 17, 18, 19], "fast": 0, "favor": [15, 17], "fed": 1, "feed": [19, 21], "few": 4, "fewer": [6, 19, 21], "field": 6, "find": 6, "fit": [16, 17], "fix": 4, "flag": [16, 17], "flajolet": [1, 2], "flavor": [1, 6], "float": [0, 1, 3, 4, 5, 6, 9, 10, 11, 12, 15, 16, 17, 18, 19], "float32": [16, 17, 18], "float64": [16, 17], "fm85": 0, "follow": [6, 16, 18, 22], "footprint": 2, "form": [3, 4, 6, 11], "format": 12, "found": 6, "fraction": [3, 4, 16, 17, 19], "framework": 3, "frequenc": [5, 6, 17], "frequent": [5, 7, 14], "frequent_items_error_typ": 6, "frequent_items_sketch": [6, 7], "frequent_strings_sketch": [6, 7], "from": [2, 3, 4, 6, 7, 10, 11, 12, 16, 17, 18, 19, 20, 21, 22], "from_byt": 12, "full": [1, 5], "funciton": 10, "function": [0, 1, 3, 4, 5, 6, 8, 11, 14, 15, 16, 17, 18], "futur": 0, "g": 15, "gaussian": 10, "gaussiankernel": 10, "gde": 22, "gener": [6, 7, 10, 15, 16, 17, 18], "get": [16, 17], "get_apriori_error": 6, "get_cdf": [16, 17, 18], "get_compact_serialization_byt": 1, "get_epsilon_for_lg_s": 6, "get_estim": [0, 1, 3, 4, 5, 6, 22], "get_frequent_item": 6, "get_lower_bound": [0, 1, 3, 4, 5, 6], "get_max_updatable_serialization_byt": 1, "get_max_valu": [16, 17, 18], "get_min_valu": [16, 17, 18], "get_n": 17, "get_normalized_rank_error": [16, 17, 18], "get_pmf": [16, 17, 18], "get_quantil": [16, 17, 18], "get_rank": [16, 17, 18], "get_rank_lower_bound": 18, "get_rank_upper_bound": 18, "get_rel_err": 1, "get_relative_error": 5, "get_result": [0, 1, 3, 4, 19, 21], "get_rs": 18, "get_seed_hash": [3, 4], "get_serialized_size_byt": [5, 6, 19, 21], "get_siz": 12, "get_updatable_serialization_byt": 1, "get_upper_bound": [0, 1, 3, 4, 5, 6], "github": 22, "given": [0, 1, 3, 4, 5, 6, 10, 11, 12, 15, 16, 17, 18, 19, 21, 22], "global": [6, 15], "good": [2, 3], "graham": [5, 18], "gri": 6, "grow": 6, "guarante": [5, 6, 16, 17, 18], "ha": [1, 3, 4, 5, 7, 15, 16, 17, 18], "haa": 19, "handl": [3, 7, 19], "has_result": [3, 4], "hash": [0, 3, 4, 5, 6], "hat": 5, "have": [1, 6, 11, 16, 17, 18, 21], "heavi": [5, 6, 7, 14], "heaviest": 7, "help": [9, 18], "hentschel": 19, "here": 18, "hi": 0, "high": [0, 1, 15, 18], "higher": [1, 17], "highest": 1, "highli": 14, "hip": 0, "histogram": [15, 17], "histor": [0, 15], "hitter": [5, 6, 7, 14], "hll": [0, 2, 14], "hll_4": 1, "hll_6": 1, "hll_8": 1, "hll_sketch": [1, 2], "hll_union": 1, "hold": [1, 6], "how": [4, 7, 8, 13, 18], "howev": [6, 16, 18], "http": [5, 11, 18, 22], "hyper": 2, "hyperloglog": [0, 2, 3, 14], "hypothesi": 11, "hypothet": [16, 17, 18], "i": [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22], "icon": 0, "identifi": 7, "imag": 5, "implement": [0, 1, 4, 6, 7, 10, 12, 13, 16, 17, 18, 22], "improv": [1, 21], "includ": [15, 16, 17, 18, 19, 20, 21], "inclus": [1, 16, 17, 18, 20], "incom": [3, 4, 6], "increas": [16, 17, 18], "increment": 6, "independ": 16, "index": [9, 14, 16, 17], "indic": [1, 10], "inform": 19, "inherit": 10, "init_number_of_sect": 18, "initi": [1, 3, 4, 6, 18], "input": [0, 1, 3, 4, 6, 10, 11, 16, 17, 18, 20, 22, 23], "insert": [3, 5, 6], "inspir": 22, "instanc": [6, 16, 17, 18, 19, 21, 22], "instead": [17, 18], "insuffici": 11, "int": [0, 1, 3, 4, 5, 6, 9, 12, 16, 17, 18, 19, 21, 22], "int32": [16, 17, 18], "integ": [0, 5, 6, 12, 13, 15], "integr": [1, 3, 4], "intern": 6, "internet": 6, "interpret": 16, "intersect": [2, 3, 4, 13], "interv": [16, 17, 18], "introduc": 6, "invers": [0, 16], "involv": 7, "is_compact": 1, "is_empti": [0, 1, 3, 4, 5, 6, 16, 17, 18, 19, 21, 22], "is_estimation_mod": [3, 4, 16, 17, 18, 22], "is_hra": 18, "is_ord": [3, 4], "item": [1, 3, 4, 5, 7, 12, 14, 15, 16, 17, 18, 19, 20, 21, 22], "iter": 19, "its": [0, 12, 16, 17, 19], "itself": 6, "j": 19, "j_": 9, "jaccard": [3, 4, 8, 14], "java": [16, 17], "just": 16, "justin": 18, "k": [0, 1, 2, 3, 4, 6, 7, 16, 17, 18, 19, 21, 22], "kappa": 0, "karnin": [18, 22], "karnin19a": 22, "karp": 6, "keep": [1, 4, 19], "kei": [2, 4], "kept": 13, "kernel": [8, 14, 22, 23], "kernel_funct": 8, "kernel_sketch": 8, "kernelfunct": [10, 22], "kevin": 0, "kll": [14, 15, 17], "kll_doubles_sketch": [11, 16], "kll_floats_sketch": [11, 16], "kll_ints_sketch": [11, 16], "kll_items_sketch": [11, 16], "known": [0, 2, 6, 10, 14, 20], "kolmogorov": [8, 14], "ks_test": [8, 11], "kwarg": [0, 1, 3, 4, 5, 6, 10, 12, 13, 16, 17, 18, 19, 21, 22], "lang": 0, "languag": [12, 17], "larg": [1, 15, 16, 17], "larger": [2, 16, 19], "largest": 13, "last": [16, 17, 18], "lazi": 16, "lb": [6, 9], "le": 5, "learn": [10, 22], "least": [6, 8], "left": [16, 17, 18], "legaci": 6, "lemma": 18, "len": 12, "length": [6, 16, 17, 18, 19, 20, 21, 22], "less": [15, 16, 17, 18], "let": 16, "letter": 19, "level": [5, 18], "leverag": 1, "lg_config_k": 1, "lg_k": [0, 1, 3, 4], "lg_max_k": [1, 6], "lg_max_map_s": 6, "liberti": [18, 22], "librari": [2, 4, 6, 7, 10, 11, 15, 23], "like": [1, 7, 11, 16], "limit": [6, 19], "line": [16, 17, 18], "list": [5, 7, 9], "littl": 12, "load_factor": 6, "log": [1, 2], "log2": [1, 6], "logarithm": [0, 3, 4, 6], "logic": [6, 15], "longer": 2, "look": 6, "loos": 18, "lopez": 6, "low": [15, 18], "lower": [0, 1, 3, 4, 5, 6, 9, 16, 18, 21], "lower_bound": 9, "m": [6, 16, 17, 18], "machin": [10, 22], "mai": [5, 6, 14, 15, 16, 18, 19], "maintain": [3, 7], "make": 16, "mani": 3, "map": 6, "mapcap": 6, "mapsiz": 6, "margin": 19, "martin": 2, "mass": [15, 16, 17, 18], "mass_i": 16, "match": [0, 3, 4, 21], "mathemat": [10, 18], "max": [13, 16, 17, 18], "max_k": 21, "max_map_s": 6, "maximum": [1, 3, 4, 5, 6, 16, 17, 18, 19, 21], "maxintpolici": 13, "maxmapcap": 6, "maxmaps": 6, "mean": [4, 6, 16, 17, 19], "measur": [3, 4, 9, 16, 17, 18], "median": [6, 17], "member": [3, 6], "memori": [1, 2, 6], "merg": [0, 1, 4, 5, 6, 16, 17, 18, 19, 22], "method": [0, 1, 3, 4, 5, 6, 10, 12, 16, 17, 18, 19, 21, 22], "metwal": 6, "might": [6, 16], "million": 17, "min": [13, 16, 17, 18], "minim": 20, "minimum": [2, 3, 16, 17, 18, 21], "minintpolici": 13, "misra": 6, "miss": 6, "mlr": 22, "mode": [1, 3, 4, 16, 17, 18, 22], "modifi": [11, 18], "modul": 14, "monoton": [16, 17, 18], "more": [0, 6], "most": [7, 17], "much": [1, 6], "multipli": 17, "multiset": 6, "munro": 6, "must": [1, 3, 4, 10, 12, 13, 16, 17, 18], "muthukrishnan": 5, "n": [1, 16, 17, 18, 19, 21, 22], "name": 6, "nan": [16, 17, 18], "natur": [16, 17], "ndarrai": [16, 17, 18], "nearli": [0, 16], "necessari": [16, 17, 18], "necessarili": 7, "need": [3, 5, 6, 13, 19, 20, 21], "network": 17, "never": [5, 6, 16, 18], "new": [0, 1, 6, 13, 17, 19, 21, 22], "newli": 0, "no_false_neg": 6, "no_false_posit": 6, "node": 17, "nomin": [3, 4, 18], "non": [0, 1, 3, 4, 5, 6, 16, 17, 18, 19, 21, 22], "none": [0, 1, 3, 4, 5, 6, 16, 17, 18, 19, 21, 22], "normal": [16, 17, 18], "normalized_rank_error": [16, 17], "note": [6, 9, 11, 16, 18], "novemb": 17, "now": 23, "null": [11, 12], "num_active_item": 6, "num_bucket": 5, "num_byt": 12, "num_hash": 5, "num_retain": [3, 4, 16, 17, 18, 22], "num_sampl": 21, "num_std_dev": 1, "number": [0, 1, 2, 3, 4, 5, 6, 12, 16, 17, 18, 19, 21, 22], "numer": [15, 19], "numpi": 10, "numsect": 18, "object": [0, 1, 3, 4, 5, 6, 7, 9, 10, 12, 13, 16, 17, 18, 19, 21, 22], "obtain": [5, 16, 17, 18], "occurr": 5, "off": [1, 2, 16, 17, 18], "offer": [1, 2, 7], "offest": 12, "offset": 12, "often": 7, "one": [2, 5, 6, 7, 8, 16, 17, 18, 22], "onli": [1, 6, 16, 17, 18, 23], "oper": [0, 2, 3, 4, 13, 16, 18], "opposit": 16, "opt": 21, "optim": [0, 14, 16, 20], "option": [0, 3, 4, 6, 16, 17, 18, 19, 21], "order": [3, 4, 5, 13, 15, 19], "org": [11, 18], "ortiz": 6, "other": [3, 4, 5, 16, 17], "otherwis": [0, 1, 3, 4, 5, 6, 9, 11, 16, 17, 18, 19, 21, 22], "our": 6, "output": 18, "outsid": 7, "over": [6, 15, 17], "overal": 17, "overestim": 5, "overload": [0, 1, 3, 4, 5, 11, 16, 17, 18], "overrid": [10, 12], "p": [3, 4, 11, 19], "packag": 3, "packet": [6, 17], "page": 14, "pair": [6, 8, 11], "papadimitri": 6, "paper": [0, 3, 5, 18, 22], "paramet": [0, 1, 3, 4, 5, 6, 10, 12, 13, 16, 17, 18, 19, 21, 22], "partial": 19, "particular": 18, "particularli": 10, "pass": [16, 17], "pattern": 10, "pavel": 18, "pdf": [5, 22], "per": [1, 16], "percentag": 7, "percentil": [16, 17], "perform": [0, 1, 2, 3, 4, 8, 10, 11, 16, 18], "permiss": 5, "phillip": 1, "physic": 6, "plot": 16, "plu": 6, "pmf": [15, 16, 17, 18], "point": [0, 1, 3, 4, 10, 12, 15, 16, 17, 18, 19, 22], "polici": [4, 8, 14], "portion": [15, 19], "posit": 6, "possibl": 0, "power": [6, 18], "pp": 19, "practic": [3, 6], "pre": 12, "precis": [16, 17, 19], "predic": [20, 21], "present": 21, "press": 22, "print": [19, 21], "priori": [1, 6, 18], "probabilist": [1, 2, 5, 14, 15, 16, 17, 18], "probabilitii": [14, 20], "probabl": [0, 5, 6, 15, 16, 17, 18, 19, 20, 21], "problem": 14, "proceed": 22, "process": [19, 21], "produc": [0, 1, 3, 4, 5, 6, 16, 17, 18, 19, 21, 22], "project": [14, 17], "proof": 6, "properti": [0, 1, 2, 3, 4, 5, 6, 16, 17, 18, 19, 21, 22], "proport": [14, 20], "prototyp": 18, "proven": 15, "provid": [0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 15, 16, 17, 18, 21, 22, 23], "pub": 5, "purg": 6, "py": 22, "pydoublesserd": 12, "pyfloatsserd": 12, "pyintsserd": 12, "pylongsserd": 12, "pyobjectserd": [4, 6, 12, 16, 17, 18, 19, 21], "pystringsserd": 12, "python": [13, 18], "q": 16, "q_hi": 16, "q_lo": 16, "qualifi": 6, "quantil": [8, 16, 22], "quantiles_doubles_sketch": [11, 17], "quantiles_floats_sketch": [11, 17], "quantiles_ints_sketch": [11, 17], "quantiles_items_sketch": [11, 17], "queri": [5, 15, 16, 17, 21], "quickli": 14, "quit": [0, 4, 16], "r": 16, "r1": 16, "r2": 16, "r_": 16, "r_i": 16, "radial": 10, "random": [6, 19], "randomli": 20, "rang": 15, "rank": [15, 16, 17, 18], "rate": [3, 4], "reach": [1, 6], "read": [0, 1, 3, 4, 5, 6, 12, 19, 21, 22], "real": [16, 17, 18], "reason": 1, "rebuild": 6, "receiv": [1, 17], "recognit": 10, "recommend": 1, "reconstruct": 12, "redesign": 6, "rediscov": 6, "refer": [6, 8, 12, 16], "reflect": 11, "regardless": 7, "reject": 11, "rel": [1, 5, 7, 14, 15, 19, 20, 21], "relat": [7, 9, 19, 21], "relationship": 16, "relative_error": 5, "relev": 13, "reli": 10, "remain": 18, "remov": [3, 4, 6], "repeat": 6, "repres": [1, 17, 19], "req": [14, 15, 17], "req_floats_sketch": 18, "req_ints_sketch": 18, "req_items_sketch": 18, "requir": [4, 5, 6, 8, 16, 17, 18, 19, 21, 22], "reservoir": [19, 21], "reset": [1, 3, 4, 21], "respect": [16, 17], "result": [0, 3, 4, 6, 16, 17, 18, 20, 21], "retain": [3, 4, 6, 16, 17, 18, 22], "retun": 12, "return": [0, 1, 3, 4, 5, 6, 9, 10, 11, 12, 13, 16, 17, 18, 19, 21, 22], "right": [4, 16, 17, 18], "roughli": [0, 21], "round": 18, "row": 1, "rse": 18, "rule": 13, "run": 6, "runtimeerror": [16, 17, 18], "rutger": 5, "s1": 16, "s2": 16, "s_i": 16, "s_m": 16, "same": [1, 3, 11], "sampl": [3, 4, 16, 17, 18, 22], "satisfi": 5, "scheme": [12, 16], "score": 10, "search": 14, "section": 18, "section_s": 18, "secur": 0, "see": 16, "seed": [0, 3, 4, 5, 9], "seem": 16, "seen": [5, 6, 7, 15, 19], "self": [0, 1, 3, 4, 5, 6, 10, 12, 13, 16, 17, 18, 19, 21, 22], "semin": 2, "separ": [3, 9, 16, 17, 18], "serd": [4, 6, 8, 14, 16, 17, 18, 19, 21], "serial": [0, 1, 3, 4, 5, 6, 8, 14, 16, 17, 18, 19, 21, 22], "serialize_compact": 1, "serialize_updat": 1, "set": [2, 3, 4, 6, 13, 16, 17, 18, 22], "sever": [2, 3, 4, 6, 12], "shenker": 6, "should": [13, 16, 19], "shown": 16, "side": [16, 17], "significantli": 1, "similar": [2, 3, 4, 8, 10, 13, 14], "similarity_test": 9, "similarli": 17, "simpl": [2, 3, 6, 12], "simultan": 0, "sinc": [6, 18], "singl": [16, 17], "size": [1, 3, 4, 5, 6, 11, 12, 14, 16, 17, 18, 20, 21, 22], "sk_1": 11, "sk_2": 11, "skech": 18, "sketch": [0, 1, 2, 6, 8, 9, 11, 12, 19, 21], "sketch_a": 9, "sketch_b": 9, "slot": 1, "sm": 16, "small": [1, 6, 11], "smaller": [0, 1, 6, 16, 21], "smallest": 13, "smirnov": [8, 14], "snly": 7, "so": [0, 6, 15, 16, 17, 18, 19], "solut": 2, "some": [6, 8, 16], "sometim": 16, "somewhat": [2, 20], "sort": [3, 4, 16, 17, 18], "sourc": [3, 4], "sourch": 4, "space": [0, 1, 2, 3, 6], "special": 18, "specif": [6, 8, 10, 15, 16, 17], "specifi": [0, 1, 5, 6, 8, 12, 13, 16, 18], "speed": [0, 6], "split": [16, 17, 18], "split_point": [16, 17, 18], "sqrt": 18, "standard": [0, 1, 3, 4, 18], "start": [1, 6, 12, 18], "start_full_s": 1, "start_max_s": 1, "state": [1, 2, 3, 4, 6, 18, 21], "static": [0, 1, 3, 4, 5, 6, 16, 17, 18, 19, 21, 22], "stochast": [16, 17], "storag": [1, 12], "store": [2, 3, 6], "str": [0, 1, 3, 4, 5], "straightforward": 15, "stream": [0, 1, 3, 4, 5, 6, 7, 15, 16, 17, 18, 19, 20, 21, 22], "strictli": 19, "string": [0, 1, 3, 4, 5, 6, 7, 12, 16, 17, 18, 19, 21, 22], "string_cont": 12, "subset": [20, 21], "subtract": 16, "suggest": 5, "suggest_num_bucket": 5, "suggest_num_hash": 5, "sum": [6, 16, 17, 18, 20, 21], "summari": [0, 1, 3, 4, 5, 6, 8, 13, 16, 17, 18, 19, 21, 22], "support": [2, 6], "surviv": 0, "t": [16, 17], "tabl": [1, 6], "take": 11, "target": 1, "target_hll_typ": 1, "task": 2, "templat": [16, 17], "term": 1, "termin": 12, "test": [8, 9, 14], "tgt_hll_type": 1, "tgt_type": 1, "thaler": 18, "than": [0, 1, 2, 3, 6, 15, 16, 17, 18, 19], "thei": [4, 11, 15, 20], "them": 8, "theta": [1, 2, 4, 8, 9, 14], "theta64": [3, 4], "theta_a_not_b": 3, "theta_intersect": 3, "theta_jaccard_similar": [3, 9], "theta_sketch": [2, 3, 4, 9], "theta_union": 3, "thi": [0, 1, 4, 5, 6, 11, 12, 13, 14, 16, 17, 18, 19, 21, 22], "those": [7, 8], "thousand": [16, 17], "three": [1, 12, 15], "threshold": 9, "through": [3, 4, 6], "throw": [16, 17, 18], "thu": [16, 18], "tian": 19, "tight": 18, "time": [1, 6, 16, 17, 18], "to_byt": 12, "to_str": [0, 1, 3, 4, 5, 6, 16, 17, 18, 19, 21, 22], "too": [6, 11], "tool": 18, "top": [6, 7], "topk": 14, "total": [5, 17, 18, 19, 21], "total_weight": [5, 6], "track": 6, "trade": [1, 2, 16, 17, 18], "tradeoff": 0, "translat": 16, "trial": [16, 17], "trim": [3, 4], "true": [0, 1, 3, 4, 5, 6, 9, 11, 16, 17, 18, 19, 21, 22], "true_mass": 16, "true_rank": 16, "tupl": [2, 3, 8, 9, 12, 14], "tuple_a_not_b": [3, 4], "tuple_intersect": 4, "tuple_jaccard_similar": [4, 9], "tuple_polici": 8, "tuple_sketch": [2, 4, 8, 9, 13], "tuple_union": 4, "tuplepolici": [4, 13], "two": [0, 6, 7, 10, 11, 16, 18, 22], "type": [1, 2, 6, 7, 10, 11, 12, 13, 15], "typic": 6, "u": 16, "ub": [6, 9], "under": 14, "underestim": 5, "underli": 11, "understand": [15, 18], "unequ": 19, "uniform": [15, 19, 21], "union": [0, 1, 3, 4, 13, 21], "uniqu": [0, 1, 2, 16, 17, 18], "unsurprisingli": 10, "up": [1, 6], "updat": [0, 1, 3, 4, 5, 6, 13, 16, 17, 18, 19, 21, 22], "update_summari": 13, "update_theta_sketch": 3, "update_tuple_sketch": 4, "upon": 19, "upper": [0, 1, 3, 4, 5, 6, 9, 16, 18, 21], "upper_bound": [1, 9], "us": [1, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 22], "usag": 6, "user": [0, 10, 18], "usual": 6, "v99": 22, "valid": [3, 4, 18], "valu": [0, 1, 2, 3, 4, 5, 6, 10, 11, 12, 13, 15, 16, 17, 18, 19, 21], "var": 21, "var_opt_sketch": [20, 21], "var_opt_union": 21, "variabl": [6, 18], "varianc": [14, 20], "variant": [3, 6, 7], "varopt": [14, 19, 20], "vector": [10, 16, 17, 18, 22], "veri": [4, 6, 16, 17], "version": [1, 6, 7, 12, 15, 16, 17, 18], "vesel\u00fd": 18, "via": 18, "view": 16, "visibl": 18, "w": 6, "warmup": 1, "we": [6, 11, 16, 18], "weight": [5, 6, 7, 16, 17, 18, 19, 20, 21], "well": [0, 2, 15, 21], "were": [2, 6, 16, 17], "what": [6, 15], "when": [0, 1, 3, 4, 5, 8, 13, 15, 16, 17, 18, 21], "where": [1, 6, 12, 13, 16, 19], "whether": [1, 3, 4, 18], "which": [2, 3, 4, 5, 6, 7, 10, 12, 15, 16, 17, 18], "while": [2, 3], "whose": 7, "wiki": 11, "wikipedia": 11, "win": 0, "within": [5, 8], "work": [2, 17, 18], "wors": 16, "worst": 6, "would": 6, "written": [12, 18], "x": [5, 16], "y": [16, 19], "year": 6, "yield": 16, "you": 17, "zero": 16, "zohar": [18, 22]}, "titles": ["Compressed Probabilistic Counting (CPC)", "HyperLogLog (HLL)", "Distinct Counting", "Theta Sketch", "Tuple Sketch", "CountMin Sketch", "Frequent Items", "Frequency Sketches", "Helper Classes", "Jaccard Similarity", "Kernel Function", "Kolmogorov-Smirnov Test", "Serialize/Deserialize (SerDe)", "Tuple Policy", "Apache DataSketches", "Quantiles Sketches", "KLL Sketch", "Quantiles Sketch (Deprecated)", "Relative Error Quantiles (REQ) Sketch", "Exact and Bounded, Probabilitiy Proportional to Size (EBPPS) Sampling", "Random Sampling Sketches", "Variance Optimal Sampling (VarOpt)", "Density Sketch", "Vector Sketches"], "titleterms": {"apach": 14, "bound": 19, "class": [8, 14], "compress": 0, "count": [0, 2, 14], "countmin": 5, "cpc": 0, "datasketch": 14, "densiti": 22, "deprec": 17, "deseri": 12, "distinct": [2, 14], "ebpp": 19, "error": 18, "estim": 14, "exact": 19, "frequenc": [7, 14], "frequent": 6, "function": 10, "helper": [8, 14], "hll": 1, "hyperloglog": 1, "indic": 14, "item": 6, "jaccard": 9, "kernel": 10, "kll": 16, "kolmogorov": 11, "optim": 21, "polici": 13, "probabilist": 0, "probabilitii": 19, "proport": 19, "quantil": [14, 15, 17, 18], "random": [14, 20], "rel": 18, "req": 18, "sampl": [14, 19, 20, 21], "serd": 12, "serial": 12, "similar": 9, "size": 19, "sketch": [3, 4, 5, 7, 14, 15, 16, 17, 18, 20, 22, 23], "smirnov": 11, "tabl": 14, "test": 11, "theta": 3, "tupl": [4, 13], "varianc": 21, "varopt": 21, "vector": [14, 23]}}) \ No newline at end of file diff --git a/docs/5.0.2/vector/density_sketch.html b/docs/5.0.2/vector/density_sketch.html new file mode 100644 index 00000000..51b650b1 --- /dev/null +++ b/docs/5.0.2/vector/density_sketch.html @@ -0,0 +1,248 @@ + + + + + + + Density Sketch — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Density Sketch

+

Builds a coreset from the given set of input points. +Provides density estimate at a given point.

+

Based on the following paper: Zohar Karnin, Edo Liberty +“Discrepancy, Coresets, and Sketches in Machine Learning” +https://proceedings.mlr.press/v99/karnin19a/karnin19a.pdf

+

Inspired by the following implementation: https://github.com/edoliberty/streaming-quantiles/blob/f688c8161a25582457b0a09deb4630a81406293b/gde.py

+

Requires the use of a KernelFunction to compute the distance between two vectors.

+
+
+class density_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, kernel: _datasketches.KernelFunction) _datasketches.density_sketch
+

Reads a bytes object and returns the corresponding density_sketch

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int, dim: int, kernel: _datasketches.KernelFunction) None
+

Creates a new density sketch

+
+
Parameters:
+
    +
  • k (int) – controls the size and error of the sketch

  • +
  • dim (int) – dimension of the input data

  • +
  • kernel (KernelFunction) – instance of a kernel

  • +
+
+
+
+ +
+
+property dim
+

The configured parameter dim

+
+ +
+
+get_estimate
+

Returns an approximate density at the given point

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Updates the sketch with the given vector

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.0.2/vector/index.html b/docs/5.0.2/vector/index.html new file mode 100644 index 00000000..808fefda --- /dev/null +++ b/docs/5.0.2/vector/index.html @@ -0,0 +1,135 @@ + + + + + + + Vector Sketches — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Vector Sketches

+

These sketches are designed to accept vector inputs. For now, the library provides only the +density_sketch for Kernel Density Estimation.

+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.0/.buildinfo b/docs/5.1.0/.buildinfo new file mode 100644 index 00000000..47b90a0a --- /dev/null +++ b/docs/5.1.0/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. +config: d77903253d7c793246700a3d942e402e +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/docs/5.1.0/_sources/distinct_counting/cpc.rst.txt b/docs/5.1.0/_sources/distinct_counting/cpc.rst.txt new file mode 100644 index 00000000..6a28d387 --- /dev/null +++ b/docs/5.1.0/_sources/distinct_counting/cpc.rst.txt @@ -0,0 +1,32 @@ +Compressed Probabilistic Counting (CPC) +--------------------------------------- +High performance C++ implementation of Compressed Probabilistic Counting (CPC) Sketch. +This is a unique-counting sketch that implements the Compressed Probabilistic Counting (CPC, a.k.a FM85) algorithms developed by Kevin Lang in his paper +`Back to the Future: an Even More Nearly Optimal Cardinality Estimation Algorithm `_. +This sketch is extremely space-efficient when serialized. +In an apples-to-apples empirical comparison against compressed HyperLogLog sketches, this new algorithm simultaneously wins on the two dimensions of the space/accuracy tradeoff and produces sketches that are smaller than the entropy of HLL, so no possible implementation of compressed HLL can match its space efficiency for a given accuracy. As described in the paper this sketch implements a newly developed ICON estimator algorithm that survives unioning operations, another well-known estimator, the Historical Inverse Probability (HIP) estimator does not. +The update speed performance of this sketch is quite fast and is comparable to the speed of HLL. +The unioning (merging) capability of this sketch also allows for merging of sketches with different configurations of K. +For additional security this sketch can be configured with a user-specified hash seed. + + +.. autoclass:: _datasketches.cpc_sketch + :members: + :undoc-members: + :exclude-members: deserialize + + .. rubric:: Static Methods: + + .. automethod:: deserialize + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + + +.. autoclass:: _datasketches.cpc_union + :members: + :undoc-members: + :exclude-members: deserialize + + .. automethod:: __init__ diff --git a/docs/5.1.0/_sources/distinct_counting/hyper_log_log.rst.txt b/docs/5.1.0/_sources/distinct_counting/hyper_log_log.rst.txt new file mode 100644 index 00000000..287209b0 --- /dev/null +++ b/docs/5.1.0/_sources/distinct_counting/hyper_log_log.rst.txt @@ -0,0 +1,55 @@ +HyperLogLog (HLL) +----------------- +This is a high performance implementation of Phillipe Flajolet's HLL sketch but with significantly improved error behavior. + +If the ONLY use case for sketching is counting uniques and merging, the HLL sketch is a reasonable choice, although the highest performing in terms of accuracy for storage space consumed is CPC (Compressed Probabilistic Counting). For large enough counts, this HLL version (with HLL_4) can be 2 to 16 times smaller than the Theta sketch family for the same accuracy. + +This implementation offers three different types of HLL sketch, each with different trade-offs with accuracy, space and performance. +These types are specified with the target_hll_type parameter. + +In terms of accuracy, all three types, for the same lg_config_k, have the same error distribution as a function of ``n``, the number of unique values fed to the sketch. +The configuration parameter ``lg_config_k`` is the log-base-2 of ``k``, where ``k`` is the number of buckets or slots for the sketch. + +During warmup, when the sketch has only received a small number of unique items (up to about 10% of ``k``), this implementation leverages a new class of estimator algorithms with significantly better accuracy. + + +.. autoclass:: _datasketches.tgt_hll_type + + .. autoattribute:: HLL_4 + :annotation: : 4 bits per entry + + .. autoattribute:: HLL_6 + :annotation: : 6 bits per entry + + .. autoattribute:: HLL_8 + :annotation: : 8 bits per entry + + +.. autoclass:: _datasketches.hll_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_max_updatable_serialization_bytes, get_rel_err + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_max_updatable_serialization_bytes + .. automethod:: get_rel_err + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: _datasketches.hll_union + :members: + :undoc-members: + :exclude-members: get_rel_err + + .. rubric:: Static Methods: + + .. automethod:: get_rel_err + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + \ No newline at end of file diff --git a/docs/5.1.0/_sources/distinct_counting/index.rst.txt b/docs/5.1.0/_sources/distinct_counting/index.rst.txt new file mode 100644 index 00000000..f4038815 --- /dev/null +++ b/docs/5.1.0/_sources/distinct_counting/index.rst.txt @@ -0,0 +1,24 @@ +Distinct Counting +================= + +.. currentmodule:: datasketches + +Distinct counting is one of the earliest tasks to which sketches were applied. The concept is simple: +Provide an estimate of the number of unique elements in a set of data. One of the earliest solutions came +from Flajolet and Martin in 1985 with their seminal work +`Probabilistic counting Algorithms for Data Base Applications `_. + +The DataSketches library offers several types of distinct counting sketches, each with different properties. + + * :class:`hll_sketch`: Hyper Log Log, a well-known sketch for distinct counting but no longer state-of-the-art. + * :class:`cpc_sketch`: Provides a better accuracy-space trade-off than HLL, but with a somewhat larger footprint while in-memory. + * :class:`theta_sketch`: Theta sketch, a type of k-minimum value sketch, which provide good performance with intersection and set difference operations. + * :class:`tuple_sketch`: Tuple sketch, which is similar to a theta sketch but supports additional data stored with each key. + +.. toctree:: + :maxdepth: 1 + + hyper_log_log + cpc + theta + tuple \ No newline at end of file diff --git a/docs/5.1.0/_sources/distinct_counting/theta.rst.txt b/docs/5.1.0/_sources/distinct_counting/theta.rst.txt new file mode 100644 index 00000000..94951f96 --- /dev/null +++ b/docs/5.1.0/_sources/distinct_counting/theta.rst.txt @@ -0,0 +1,65 @@ +Theta Sketch +------------ + +.. currentmodule:: datasketches + +Theta sketches are used for distinct counting. + +The theta package contains the basic sketch classes that are members of the `Theta Sketch Framework `_. +There is a separate Tuple package for many of the sketches that are derived from the same algorithms defined in the Theta Sketch Framework paper. + +The *Theta Sketch* sketch is a space-efficient method for estimating cardinalities of sets. +It can also easily handle set operations (such as union, intersection, difference) while maintaining good accuracy. +Theta sketch is a practical variant of the K-Minimum Values sketch which avoids the need to sort the stored +hash values on every insertion to the sketch. +It has better error properties than the HyperLogLog sketch for set operations beyond the simple union. + +Set operations (union, intersection, A-not-B) are performed through the use of dedicated objects. + +Several `Jaccard similarity `_ +measures can be computed between theta sketches with the :class:`theta_jaccard_similarity` class. + +.. autoclass:: theta_sketch + :members: + :undoc-members: + +.. autoclass:: update_theta_sketch + :members: + :undoc-members: + + .. automethod:: __init__ + + +.. autoclass:: compact_theta_sketch + :members: + :undoc-members: + :exclude-members: deserialize + + .. rubric:: Static Methods: + + .. automethod:: deserialize + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + + +.. autoclass:: theta_union + :members: + :undoc-members: + + .. automethod:: __init__ + + +.. autoclass:: theta_intersection + :members: + :undoc-members: + + .. automethod:: __init__ + + +.. autoclass:: theta_a_not_b + :members: + :undoc-members: + + .. automethod:: __init__ diff --git a/docs/5.1.0/_sources/distinct_counting/tuple.rst.txt b/docs/5.1.0/_sources/distinct_counting/tuple.rst.txt new file mode 100644 index 00000000..e4a369f2 --- /dev/null +++ b/docs/5.1.0/_sources/distinct_counting/tuple.rst.txt @@ -0,0 +1,64 @@ +Tuple Sketch +------------ + +.. currentmodule:: datasketches + +Tuple sketches are an extension of Theta sketches, meaning they provide estimate of distinct counts, that +allow the keeping of arbitrary summaries associated with each retained key +(for example, a count for every key). The use of a :class:`tuple_sketch` requires a :class:`TuplePolicy` which +defines how summaries are created, updated, merged, or intersected. The library provides a few basic +examples of :class:`TuplePolicy` implementations, but the right custom summary and policy can allow very +complicated analysis to be performed quite easily. + +Set operations (union, intersection, A-not-B) are performed through the use of dedicated objects. + +Several `Jaccard similarity `_ +measures can be computed between theta sketches with the :class:`tuple_jaccard_similarity` class. + +.. note:: + Serializing and deserializing this sketch requires the use of a :class:`PyObjectSerDe`. + +.. autoclass:: tuple_sketch + :members: + :undoc-members: + +.. autoclass:: update_tuple_sketch + :members: + :undoc-members: + + .. automethod:: __init__ + + +.. autoclass:: compact_tuple_sketch + :members: + :undoc-members: + :exclude-members: deserialize + + .. rubric:: Static Methods: + + .. automethod:: deserialize + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + + +.. autoclass:: tuple_union + :members: + :undoc-members: + + .. automethod:: __init__ + + +.. autoclass:: tuple_intersection + :members: + :undoc-members: + + .. automethod:: __init__ + + +.. autoclass:: tuple_a_not_b + :members: + :undoc-members: + + .. automethod:: __init__ diff --git a/docs/5.1.0/_sources/frequency/count_min_sketch.rst.txt b/docs/5.1.0/_sources/frequency/count_min_sketch.rst.txt new file mode 100644 index 00000000..b53b02e4 --- /dev/null +++ b/docs/5.1.0/_sources/frequency/count_min_sketch.rst.txt @@ -0,0 +1,27 @@ +CountMin Sketch +--------------- + +The CountMin sketch, as described in Cormode and Muthukrishnan in +http://dimacs.rutgers.edu/~graham/pubs/papers/cm-full.pdf, +is used for approximate Frequency Estimation. +For an item :math:`x` with frequency :math:`f_x`, the sketch provides an estimate, :math:`\hat{f_x}`, +such that :math:`f_x \approx \hat{f_x}.` +The sketch guarantees that :math:`f_x \le \hat{f_x}` and provides a probabilistic upper bound which is dependent on the size parameters. +The sketch provides an estimate of the occurrence frequency for any queried item but, in contrast +to the Frequent Items Sketch, this sketch does not provide a list of +heavy hitters. + +.. currentmodule:: _datasketches + +.. autoclass:: count_min_sketch + :members: + :undoc-members: + :exclude-members: deserialize, suggest_num_buckets, suggest_num_hashes + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: suggest_num_buckets + .. automethod:: suggest_num_hashes + + .. rubric:: Non-static Methods: diff --git a/docs/5.1.0/_sources/frequency/frequent_items.rst.txt b/docs/5.1.0/_sources/frequency/frequent_items.rst.txt new file mode 100644 index 00000000..76d81f58 --- /dev/null +++ b/docs/5.1.0/_sources/frequency/frequent_items.rst.txt @@ -0,0 +1,120 @@ +Frequent Items +-------------- + +.. currentmodule:: datasketches + +This sketch is useful for tracking approximate frequencies of items (``object`` or ``string``) with optional associated +integer counts that are members of a multiset of such items. +The true frequency of an item is defined to be the sum of associated counts. + +This implementation provides the following capabilities: + +* Estimate the *frequency* of an item. +* Return *upper* and *lower bounds* of any item, such that the true frequency is always between the upper and lower bounds. +* Return a global *maximum error* that holds for all items in the stream. +* Return an array of frequent items that qualify either a *NO_FALSE_POSITIVES* or a *NO_FALSE_NEGATIVES* error type. +* *Merge* itself with another sketch object created from this class. +* *Serialize/Deserialize* to/from a byte array. + +**Space Usage** + +The sketch is initialized with a maximum map size, ``maxMapSize``, that specifies the maximum physical length of the internal hash map of the form ``(object item, int count)``. +The maximum map size is always a power of 2, defined through the variables ``lg_max_map_size``. + +The hash map starts at a very small size (8 entries) and grows as needed up to the specified maximum map size. + +Excluding external space required for the item objects, the internal memory space usage of this sketch is ``18 * mapSize`` bytes (assuming 8 bytes for each reference), +plus a small constant number of additional bytes. +The internal memory space usage of this sketch will never exceed ``18 * maxMapSize`` bytes, plus a small constant number of additional bytes. + +**Maximum Capacity of the Sketch** + +The ``LOAD_FACTOR`` for the hash map is internally set at :math:`75\%`, which means at any time the map capacity of ``(item, count)`` pairs is ``mapCap = 0.75 * mapSize``. +The maximum capacity of ``(item, count)`` pairs of the sketch is ``maxMapCap = 0.75 * maxMapSize``. + +**Updating the sketch with ``(item, count)`` pairs** + +If the item is found in the hash map, the mapped count field (the "counter") is incremented by the incoming count; otherwise, a new counter ``(item, count)`` pair is created. +If the number of tracked counters reaches the maximum capacity of the hash map, the sketch decrements all of the counters (by an approximately computed median) +and removes any non-positive counters. + +**Accuracy** + +If fewer than ``0.75 * maxMapSize`` different items are inserted into the sketch, the estimated frequencies returned by the sketch will be exact. + +The logic of the frequent items sketch is such that the stored counts and true counts are never too different. +More specifically, for any item, the sketch can return an estimate of the true frequency of item, along with upper and lower bounds on the frequency (that hold deterministically). + +For this implementation and for a specific active item, it is guaranteed that the true frequency will be between the Upper Bound (UB) and the Lower Bound (LB) computed for that item. +Specifically, ``(UB- LB) ≤ W * epsilon``, where :math:`W` denotes the sum of all item counts, and :math:`epsilon = 3.5/M`, where :math:`epsilon = M` is the maxMapSize. + +This is a worst-case guarantee that applies to arbitrary inputs. +For inputs typically seen in practice, ``(UB-LB)`` is usually much smaller. + +**Background** + +This code implements a variant of what is commonly known as the "Misra-Gries algorithm". +Variants of it were discovered and rediscovered and redesigned several times over the years: + +* *Finding repeated elements*, Misra, Gries, 1982 +* *Frequency estimation of Internet packet streams with limited space* Demaine, Lopez-Ortiz, Munro, 2002 +* *A simple algorithm for finding frequent elements in streams and bags* Karp, Shenker, Papadimitriou, 2003 +* *Efficient Computation of Frequent and Top-k Elements in Data Streams* Metwally, Agrawal, Abbadi, 2006 + + +For speed, we do employ some randomization that introduces a small probability that our proof of the worst-case bound might not apply to a given run. +However, we have ensured that this probability is extremely small. +For example, if the stream causes one table purge (rebuild), our proof of the worst-case bound applies with a probability of at least `1 - 1E-14`. +If the stream causes ``1E9`` purges, our proof applies with a probability of at least ``1 - 1E-5``. + +There are two flavors of Frequent Items Sketches, one with generic items (objects) and another specific to strings. +The string version is a legacy name from before the library supported generic objects and is retained +only for backwards compatibility. + +.. note:: + The :class:`frequent_items_sketch` uses an input object's ``__hash__`` and ``__eq__`` methods. + +.. note:: + Serializing and deserializing the :class:`frequent_items_sketch` requires the use of a :class:`PyObjectSerDe`. + +.. autoclass:: frequent_items_error_type + + .. autoattribute:: NO_FALSE_POSITIVES + :annotation: : Returns only true positives but may miss some heavy hitters. + + .. autoattribute:: NO_FALSE_NEGATIVES + :annotation: : Does not miss any heavy hitters but may return false positives. + + +.. autoclass:: frequent_items_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_epsilon_for_lg_size, get_apriori_error + :member-order: groupwise + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_epsilon_for_lg_size + .. automethod:: get_apriori_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + + +.. autoclass:: frequent_strings_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_epsilon_for_lg_size, get_apriori_error + :member-order: groupwise + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_epsilon_for_lg_size + .. automethod:: get_apriori_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ diff --git a/docs/5.1.0/_sources/frequency/index.rst.txt b/docs/5.1.0/_sources/frequency/index.rst.txt new file mode 100644 index 00000000..3cd3dfa5 --- /dev/null +++ b/docs/5.1.0/_sources/frequency/index.rst.txt @@ -0,0 +1,15 @@ +Frequency Sketches +================== + +Frequency estimation involves determining how often an item has been seen in a stream. The library currently +offers two types of sketches for frequency estimation, one of which has two closely-related variants. + + * :class:`frequent_items_sketch`: Identifies the *Top K* or *heavy hitters* in a stream, those items whose weight is above a certain percentage of the entire stream. Does not necessarily provide an estimate for most items outside the heavy hitters. + * :class:`frequent_strings_sketch`: Like the items version but containing snly strings (an implementation from before the library handled generic objects). + * :class:`count_min_sketch`: Provides an estimate for any item, regardless of relative weight, but does not maintain a list of the heaviest items. + +.. toctree:: + :maxdepth: 1 + + frequent_items + count_min_sketch \ No newline at end of file diff --git a/docs/5.1.0/_sources/helper/index.rst.txt b/docs/5.1.0/_sources/helper/index.rst.txt new file mode 100644 index 00000000..182b8e85 --- /dev/null +++ b/docs/5.1.0/_sources/helper/index.rst.txt @@ -0,0 +1,24 @@ +Helper Classes +============== + +.. currentmodule:: dataksetches + +These classes are required for certain sketches or specific +functionality within sketches. +Some of them are abstract base classes, but in those cases there is at +least one reference example of a concrete class. + + * :class:`serde` is used when serializing and deserializing sketches. + * :class:`jaccard` is used to compute the Jaccard similarity between pairs of theta or tuple sketches. + * :class:`tuple_policy` is required to use a :class:`tuple_sketch` by specifying how summaries are combined. + * :func:`ks_test` performs a Kolmogorov-Smirnov test on absolute-error quantiles family sketches. + * :class:`kernel_function` is required when using a :class:`kernel_sketch` for Kernel Density Estimation. + +.. toctree:: + :maxdepth: 1 + + serde + jaccard + tuple_policy + ks_test + kernel diff --git a/docs/5.1.0/_sources/helper/jaccard.rst.txt b/docs/5.1.0/_sources/helper/jaccard.rst.txt new file mode 100644 index 00000000..d3b9bfa3 --- /dev/null +++ b/docs/5.1.0/_sources/helper/jaccard.rst.txt @@ -0,0 +1,23 @@ +Jaccard Similarity +################## + +.. currentmodule:: datasketches + +These objects provide measures related to the `Jaccard similarity `_ +of :class:`theta_sketch` and :class:`tuple_sketch` objects. + +Note that there are separate classes to be used for theta and tuple sketches. + +.. autoclass:: theta_jaccard_similarity + + .. automethod:: jaccard + .. automethod:: exactly_equal + .. automethod:: similarity_test + .. automethod:: dissimilarity_test + +.. autoclass:: tuple_jaccard_similarity + + .. automethod:: jaccard + .. automethod:: exactly_equal + .. automethod:: similarity_test + .. automethod:: dissimilarity_test diff --git a/docs/5.1.0/_sources/helper/kernel.rst.txt b/docs/5.1.0/_sources/helper/kernel.rst.txt new file mode 100644 index 00000000..bdc2c729 --- /dev/null +++ b/docs/5.1.0/_sources/helper/kernel.rst.txt @@ -0,0 +1,21 @@ +Kernel Function +############### + +.. currentmodule:: datasketches + +A `kernel function `_ is a specific type of +mathematical funciton that is particularly useful in certain machine learning and pattern recognition +contexts. The :class:`density_sketch` performs approximate +`kernel density estimation `_ which, unsurprisingly, +relies on the use of such a kernel function. + +The library provides an abstract base class :class:`KernelFunction` and an example implementation of a +Gaussian (also known as a Radial Basis Function) kernel. Custom classes must override the base class +and provide a floating point value as a score indicating the similarity of two input vectors. + +.. autoclass:: KernelFunction + + .. automethod:: __call__ + +.. autoclass:: GaussianKernel + :show-inheritance: \ No newline at end of file diff --git a/docs/5.1.0/_sources/helper/ks_test.rst.txt b/docs/5.1.0/_sources/helper/ks_test.rst.txt new file mode 100644 index 00000000..c9bc19b0 --- /dev/null +++ b/docs/5.1.0/_sources/helper/ks_test.rst.txt @@ -0,0 +1,14 @@ +Kolmogorov-Smirnov Test +####################### + +.. currentmodule:: datasketches + +A `Kolmogorov-Smirnov Test `_` is +a test of equality of two distributions to determine if they are likely to have come from the same +underlying distribution. +The DataSketches library provides a modified form of the test that takes into account the error +in each underlying sketch in the analysis. + +Currently, the test assumes both input sketches are of the same family and data type. + +.. autofunction:: ks_test diff --git a/docs/5.1.0/_sources/helper/serde.rst.txt b/docs/5.1.0/_sources/helper/serde.rst.txt new file mode 100644 index 00000000..ccac1d84 --- /dev/null +++ b/docs/5.1.0/_sources/helper/serde.rst.txt @@ -0,0 +1,34 @@ +Serialize/Deserialize (SerDe) +############################# + +.. currentmodule:: datasketches + +A SerDe is a class used to serialize items sketches to a :class:`bytes` object in binary. +Several example SerDes are provided as references. + +The use of binary-compatible SerDes in different languages is critical for cross-language compatibility. + +Each implementation must extend the :class:`PyObjectSerDe` class and override all three of its methods. + +.. autoclass:: PyObjectSerDe + + .. automethod:: get_size + .. automethod:: to_bytes + .. automethod:: from_bytes + + +The provided SerDes are: + +.. autoclass:: PyStringsSerDe + :show-inheritance: + +.. autoclass:: PyIntsSerDe + :show-inheritance: + +.. autoclass:: PyLongsSerDe + :show-inheritance: + +.. autoclass:: PyFloatsSerDe + :show-inheritance: + +.. autoclass:: PyDoublesSerDe diff --git a/docs/5.1.0/_sources/helper/tuple_policy.rst.txt b/docs/5.1.0/_sources/helper/tuple_policy.rst.txt new file mode 100644 index 00000000..3f5781f2 --- /dev/null +++ b/docs/5.1.0/_sources/helper/tuple_policy.rst.txt @@ -0,0 +1,25 @@ +Tuple Policy +############ + +.. currentmodule:: datasketches + +A Tuple Policy is needed when using a :class:`tuple_sketch` in order to specify how the +summary values should be created, updated, combined, or intersected. A summary can consist of +any python object. + +Each implementation must extend the abstract base class :class:`TuplePolicy`. + +.. autoclass:: TuplePolicy + + .. automethod:: create_summary + .. automethod:: update_summary + .. automethod:: __call__ + +.. autoclass:: AccumulatorPolicy + :show-inheritance: + +.. autoclass:: MinIntPolicy + :show-inheritance: + +.. autoclass:: MaxIntPolicy + :show-inheritance: diff --git a/docs/5.1.0/_sources/index.rst.txt b/docs/5.1.0/_sources/index.rst.txt new file mode 100644 index 00000000..b683e1fd --- /dev/null +++ b/docs/5.1.0/_sources/index.rst.txt @@ -0,0 +1,73 @@ +.. datasketches documentation master file, created by + sphinx-quickstart on Tue Jul 25 11:04:59 2023. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Apache DataSketches +================================================= + +**DataSketches** are highly-efficient algorithms to analyze big data quickly. + + +Counting Distincts +################## +.. + maxdepth: 1 means only the heading is printed in the contents +.. toctree:: + :maxdepth: 2 + + distinct_counting/index + +Quantile Estimation +################### + +.. toctree:: + :maxdepth: 2 + + quantiles/index + +Frequency Sketches +################## +This problem may also be known as **heavy hitters** or **TopK** + +.. toctree:: + :maxdepth: 2 + + frequency/index + +Vector Sketches +############### + +.. toctree:: + :maxdepth: 2 + + vector/index + + +Random Sampling +############### + +.. toctree:: + :maxdepth: 2 + + sampling/index + +Helper Classes +############## + +.. toctree:: + :maxdepth: 2 + + helper/index + + +.. note:: + + This project is under active development. + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/docs/5.1.0/_sources/quantiles/index.rst.txt b/docs/5.1.0/_sources/quantiles/index.rst.txt new file mode 100644 index 00000000..b1928f67 --- /dev/null +++ b/docs/5.1.0/_sources/quantiles/index.rst.txt @@ -0,0 +1,26 @@ +Quantiles Sketches +================== + +Quantile estimation is useful for understanding the distribution of data values in a stream. The sketches currently +in the library are designed to answer queries about the `rank` of an item in the stream of items. That is, when +applying a global ordering on all the items, what is the portion of items seen so far that are less than (alternatively, +less-than-or-equal-to) the given item. Using straightforward logic, they can also estimate the item at a given rank +in the stream. + +These sketches may be used to compute approximate histograms, Probability Mass Functions (PMFs), or +Cumulative Distribution Functions (CDFs). + +The library provides three types of quantiles sketches, each of which has generic items as well as versions +specific to a given numeric type (e.g. integer or floating point values). All three types provide error +bounds on rank estimation with proven probabilistic error distributions. + + * KLL: Provides uniform rank estimation error over the entire range + * REQ: Provides relative rank error estimates, which decreases approaching either the high or low end values. + * Classic quantiles: Largely deprecated in favor of KLL, also provides uniform rank estimation error. Included largely for backwards compatibility with historic data. + +.. toctree:: + :maxdepth: 1 + + kll + req + quantiles_depr \ No newline at end of file diff --git a/docs/5.1.0/_sources/quantiles/kll.rst.txt b/docs/5.1.0/_sources/quantiles/kll.rst.txt new file mode 100644 index 00000000..0e54b443 --- /dev/null +++ b/docs/5.1.0/_sources/quantiles/kll.rst.txt @@ -0,0 +1,171 @@ +KLL Sketch +---------- + +.. currentmodule:: datasketches + +Implementation of a very compact quantiles sketch with lazy compaction scheme +and nearly optimal accuracy per retained item. +See `Optimal Quantile Approximation in Streams`. + +This is a stochastic streaming sketch that enables near real-time analysis of the +approximate distribution of items from a very large stream in a single pass, requiring only +that the items are comparable. +The analysis is obtained using `get_quantile()` function or the +inverse functions `get_rank()`, `get_pmf()` (Probability Mass Function), and `get_cdf()` +(Cumulative Distribution Function). + +As of May 2020, this implementation produces serialized sketches which are binary-compatible +with the equivalent Java implementation only when template parameter `T = float` +(32-bit single precision values). + +Given an input stream of `N` items, the `natural rank` of any specific +item is defined as its index `(1 to N)` in inclusive mode +or `(0 to N-1)` in exclusive mode +in the hypothetical sorted stream of all `N` input items. + +The `normalized rank` (`rank`) of any specific item is defined as its +`natural rank` divided by `N`. +Thus, the `normalized rank` is between zero and one. +In the documentation for this sketch `natural rank` is never used so any +reference to just `rank` should be interpreted to mean `normalized rank`. + +This sketch is configured with a parameter `k`, which affects the size of the sketch +and its estimation error. + +The estimation error is commonly called `epsilon` (or `eps`) and is a fraction +between zero and one. Larger values of `k` result in smaller values of `epsilon`. +Epsilon is always with respect to the rank and cannot be applied to the +corresponding items. + +The relationship between the `normalized rank` and the corresponding items can be viewed +as a two-dimensional monotonic plot with the `normalized rank` on one axis and the +corresponding items on the other axis. If the y-axis is specified as the item-axis and +the x-axis as the `normalized rank`, then `y = get_quantile(x)` is a monotonically +increasing function. + +The function `get_quantile(rank)` translates ranks into +corresponding quantiles. The functions `get_rank(item)`, +`get_cdf(...)` (Cumulative Distribution Function), and `get_pmf(...)` +(Probability Mass Function) perform the opposite operation and translate items into ranks. + +The `get_pmf(...)` function has about 13 to 47% worse rank error (depending +on `k`) than the other queries because the mass of each "bin" of the PMF has +"double-sided" error from the upper and lower edges of the bin as a result of a subtraction, +as the errors from the two edges can sometimes add. + +The default `k` of 200 yields a "single-sided" `epsilon` of about 1.33% and a +"double-sided" (PMF) `epsilon` of about 1.65%. + +A `get_quantile(rank)` query has the following guarantees: +- Let `q = get_quantile(r)` where `r` is the rank between zero and one. +- The quantile `q` will be an item from the input stream. +- Let `true_rank` be the true rank of `q` derived from the hypothetical sorted +stream of all `N` items. +- Let `eps = get_normalized_rank_error(false)`. +- Then `r - eps ≤ true_rank ≤ r + eps` with a confidence of 99%. Note that the +error is on the rank, not the quantile. + +A `get_rank(item)` query has the following guarantees: +- Let `r = get_rank(i)` where `i` is an item between the min and max items of +the input stream. +- Let `true_rank` be the true rank of `i` derived from the hypothetical sorted +stream of all `N` items. +- Let `eps = get_normalized_rank_error(false)`. +- Then `r - eps ≤ true_rank ≤ r + eps` with a confidence of 99%. + +A `get_pmf()` query has the following guarantees: +- Let `{r1, r2, ..., r(m+1)} = get_pmf(s1, s2, ..., sm)` where `s1, s2` are +split points (items from the input domain) between the min and max items of +the input stream. +- Let `mass_i = estimated mass between s_i and s_i+1`. +- Let `true_mass` be the true mass between the items of `s_i`, +`s_i+1` derived from the hypothetical sorted stream of all `N` items. +- Let `eps = get_normalized_rank_error(true)`. +- then `mass - eps ≤ true_mass ≤ mass + eps` with a confidence of 99%. +- `r(m+1)` includes the mass of all points larger than `s_m`. + +A `get_cdf(...)` query has the following guarantees; +- Let `{r1, r2, ..., r(m+1)} = get_cdf(s1, s2, ..., sm)` where `s1, s2, ...` are +split points (items from the input domain) between the min and max items of +the input stream. +- Let `mass_i = r_(i+1) - r_i`. +- Let `true_mass` be the true mass between the true ranks of `s_i`, +`s_i+1` derived from the hypothetical sorted stream of all `N` items. +- Let `eps = get_normalized_rank_error(true)`. +- then `mass - eps ≤ true_mass ≤ mass + eps` with a confidence of 99%. +- `1 - r(m+1)` includes the mass of all points larger than `s_m`. + +From the above, it might seem like we could make some estimates to bound the +`item` returned from a call to `get_quantile()`. The sketch, however, does not +let us derive error bounds or confidences around items. Because errors are independent, we +can approximately bracket a value as shown below, but there are no error estimates available. +Additionally, the interval may be quite large for certain distributions. +- Let `q = get_quantile(r)`, the estimated quantile of rank `r`. +- Let `eps = get_normalized_rank_error(false)`. +- Let `q_lo = estimated quantile of rank (r - eps)`. +- Let `q_hi = estimated quantile of rank (r + eps)`. +- Then `q_lo ≤ q ≤ q_hi`, with 99% confidence. + +.. note:: + For the :class:`kll_items_sketch`, objects must be comparable with ``__lt__``. + +.. note:: + Serializing and deserializing a :class:`kll_items_sketch` requires the use of a :class:`PyObjectSerDe`. + + +.. autoclass:: kll_ints_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_normalized_rank_error + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_normalized_rank_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: kll_floats_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_normalized_rank_error + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_normalized_rank_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: kll_doubles_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_normalized_rank_error + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_normalized_rank_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: kll_items_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_normalized_rank_error + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_normalized_rank_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + diff --git a/docs/5.1.0/_sources/quantiles/quantiles_depr.rst.txt b/docs/5.1.0/_sources/quantiles/quantiles_depr.rst.txt new file mode 100644 index 00000000..18dd5df6 --- /dev/null +++ b/docs/5.1.0/_sources/quantiles/quantiles_depr.rst.txt @@ -0,0 +1,106 @@ +Quantiles Sketch (Deprecated) +----------------------------- + +.. currentmodule:: datasketches + +This is a deprecated quantiles sketch that is included for cross-language compatibility. +Most new projects will favor the KLL sketch over this one, or the REQ sketch for higher accuracy +at the very edge of a distribution. + +This is a stochastic streaming sketch that enables near-real time analysis of the +approximate distribution from a very large stream in a single pass. +The analysis is obtained using `get_rank()` and `get_quantile()` functions, +the Probability Mass Function from `get_pmf()`` and the Cumulative Distribution Function from `get_cdf`. + +Consider a large stream of one million values such as packet sizes coming into a network node. +The natural rank of any specific size value is its index in the hypothetical sorted +array of values. +The normalized rank is the natural rank divided by the stream size, +in this case one million. +The value corresponding to the normalized rank of `0.5` represents the 50th percentile or median +value of the distribution, or `get_quantile(0.5)`. +Similarly, the 95th percentile is obtained from `get_quantile(0.95)`. + +From the min and max values, for example, 1 and 1000 bytes, +you can obtain the PMF from `get_pmf(100, 500, 900)` that will result in an array of +4 fractional values such as {.4, .3, .2, .1}, which means that +40% of the values were < 100, +30% of the values were ≥ 100 and < 500, +20% of the values were ≥ 500 and < 900, and +10% of the values were ≥ 900. +A frequency histogram can be obtained by multiplying these fractions by `get_n()`, +which is the total count of values received. +The `get_cdf()`` works similarly, but produces the cumulative distribution instead. + +As of November 2021, this implementation produces serialized sketches which are binary-compatible +with the equivalent Java implementation only when template parameter T = double +(64-bit double precision values). + +The accuracy of this sketch is a function of the configured value `k`, which also affects +the overall size of the sketch. Accuracy of this quantile sketch is always with respect to +the normalized rank. A `k` of 128 produces a normalized, rank error of about 1.7%. +For example, the median item returned from `get_quantile(0.5)` will be between the actual items +from the hypothetically sorted array of input items at normalized ranks of 0.483 and 0.517, with +a confidence of about 99%. + +.. note:: + For the :class:`quantiles_items_sketch`, objects must be comparable with ``__lt__``. + +.. note:: + Serializing and deserializing a :class:`quantiles_items_sketch` requires the use of a :class:`PyObjectSerDe`. + +.. autoclass:: quantiles_ints_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_normalized_rank_error + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_normalized_rank_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: quantiles_floats_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_normalized_rank_error + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_normalized_rank_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: quantiles_doubles_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_normalized_rank_error + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_normalized_rank_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: quantiles_items_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_normalized_rank_error + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_normalized_rank_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ diff --git a/docs/5.1.0/_sources/quantiles/req.rst.txt b/docs/5.1.0/_sources/quantiles/req.rst.txt new file mode 100644 index 00000000..3f63e01e --- /dev/null +++ b/docs/5.1.0/_sources/quantiles/req.rst.txt @@ -0,0 +1,79 @@ +Relative Error Quantiles (REQ) Sketch +------------------------------------- + +.. currentmodule:: datasketches + +This is an implementation based on the `paper `_ "Relative Error Streaming Quantiles" by Graham Cormode, Zohar Karnin, Edo Liberty, Justin Thaler, Pavel Veselý, and loosely derived from a Python prototype written by Pavel Veselý. + +This implementation differs from the algorithm described in the paper in the following: + +The algorithm requires no upper bound on the stream length. +Instead, each relative-compactor counts the number of compaction operations performed so far (via variable state). +Initially, the relative-compactor starts with `INIT_NUMBER_OF_SECTIONS`. +Each time the number of compactions `(variable state) exceeds 2^{numSections - 1}`, we double `numSections`. +Note that after merging the sketch with another one variable state may not correspond to the number of compactions performed at a particular level, however, +since the state variable never exceeds the number of compactions, the guarantees of the sketch remain valid. + +The size of each section (variable `k` and `section_size` in the code and parameter `k` in the paper) is +initialized with a number set by the user via variable `k`. +When the number of sections doubles, we decrease section_size by a factor of `sqrt(2)`. +This is applied at each level separately. +Thus, when we double the number of sections, the nominal compactor size increases by a factor of approx. `sqrt(2) (+/- rounding)`. + +The merge operation here does not perform "special compactions", which are used in the paper to allow for a tight mathematical analysis of the sketch. +This implementation provides a number of capabilities not discussed in the paper or provided in the Python prototype. + +The Python prototype only implemented high accuracy for low ranks. This implementation provides the user with the ability to +choose either high rank accuracy or low rank accuracy at the time of sketch construction. +The Python prototype only implemented a comparison criterion of `INCLUSIVE`. +This implementation allows the user to use both the `INCLUSIVE` criterion and the `EXCLUSIVE` criterion. +This implementation provides extensive debug visibility into the operation of the sketch with two levels of detail output. +This is not only useful for debugging, but is a powerful tool to help users understand how the sketch works. + +.. note:: + For the :class:`req_items_sketch`, objects must be comparable with ``__lt__``. + +.. note:: + Serializing and deserializing a :class:`req_items_sketch` requires the use of a :class:`PyObjectSerDe`. + +.. autoclass:: req_ints_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_RSE + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_RSE + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: req_floats_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_RSE + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_RSE + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: req_items_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_RSE + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_RSE + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ diff --git a/docs/5.1.0/_sources/sampling/ebpps.rst.txt b/docs/5.1.0/_sources/sampling/ebpps.rst.txt new file mode 100644 index 00000000..b2253209 --- /dev/null +++ b/docs/5.1.0/_sources/sampling/ebpps.rst.txt @@ -0,0 +1,33 @@ +Exact and Bounded, Probabilitiy Proportional to Size (EBPPS) Sampling +--------------------------------------------------------------------- + +.. currentmodule:: datasketches + +An EBPPS sketch produces a randome sample of data from a stream of items, ensuring that the probability +of including an item is always exactly equal to the item's size. The size of an item is defined as its +weight relative to the total weight of all items seen so far by the sketch. In contrast to VarOpt sampling, +this sketch may return fewer than `k` items in order to keep the probability of including an item strictly +proportional to its size. + +This sketch is based on: B. Hentschel, P. J. Haas, Y. Tian +"Exact PPS Sampling with Bounded Sample Size", +Information Processing Letters, 2023. + +EBPPS sampling is related to reservoir sampling, but handles unequal item weights. +Feeding the sketch items with a uniform weight value will produce a sample equivalent to reservoir sampling. + +.. note:: + Serializing and deserializing this sketch requires the use of a :class:`PyObjectSerDe`. + +.. autoclass:: ebpps_sketch + :members: + :undoc-members: + :exclude-members: deserialize + + .. rubric:: Static Methods: + + .. automethod:: deserialize + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ diff --git a/docs/5.1.0/_sources/sampling/index.rst.txt b/docs/5.1.0/_sources/sampling/index.rst.txt new file mode 100644 index 00000000..fca6c3ce --- /dev/null +++ b/docs/5.1.0/_sources/sampling/index.rst.txt @@ -0,0 +1,21 @@ +Random Sampling Sketches +======================== + +.. currentmodule:: datasketches + +These sketches are used to randomly sample items. The length of the input +stream does not need to be known in advance. + +Both VarOpt (Variance Optimal) and EBPPS (Exact and Bounded, +Probability Proportional to Size) sketches will include sample items based on +each item's weight relative to the weight of the entire stream but +they differ in details: + + * :class:`ebpps_sketch` ensures that the probability of including an item is always exactly proportional to the item's weight. + * :class:`var_opt_sketch` optimizes for applying a predicate to the resulting sample such that the variance of the subset sum after applying the predicate is minimized, even if the inclusion probability differs somewhat from being proportional to the item's weight. + +.. toctree:: + :maxdepth: 1 + + varopt + ebpps diff --git a/docs/5.1.0/_sources/sampling/varopt.rst.txt b/docs/5.1.0/_sources/sampling/varopt.rst.txt new file mode 100644 index 00000000..d837835e --- /dev/null +++ b/docs/5.1.0/_sources/sampling/varopt.rst.txt @@ -0,0 +1,42 @@ +Variance Optimal Sampling (VarOpt) +---------------------------------- + +.. currentmodule:: datasketches + +A VarOpt sketch samples data from a stream of items. The sketch is desinged for optimal (minimum) +variance when querying the sketch to estimate subset sums of items matching a provided predicate. +The sketch will produce a sample of size `k` (or smaller if fewer items have been presented), with +the probability of including an item roughly corresponding it the item's weight relative to the total +weight of all items presented to the sketch. + +VarOpt sampling is related to reservoir sampling, with improved error bounds for subset sum estimation. +Feeding the sketch items with a uniform weight value will produce a sample equivalent to reservoir sampling. + +.. note:: + Serializing and deserializing this sketch requires the use of a :class:`PyObjectSerDe`. + +.. autoclass:: var_opt_sketch + :members: + :undoc-members: + :exclude-members: deserialize + + .. rubric:: Static Methods: + + .. automethod:: deserialize + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: var_opt_union + :members: + :undoc-members: + :exclude-members: deserialize + + .. rubric:: Static Methods: + + .. automethod:: deserialize + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ diff --git a/docs/5.1.0/_sources/vector/density_sketch.rst.txt b/docs/5.1.0/_sources/vector/density_sketch.rst.txt new file mode 100644 index 00000000..07d83181 --- /dev/null +++ b/docs/5.1.0/_sources/vector/density_sketch.rst.txt @@ -0,0 +1,28 @@ +Density Sketch +-------------- + +.. currentmodule:: datasketches + +Builds a coreset from the given set of input points. +Provides density estimate at a given point. + +Based on the following paper: Zohar Karnin, Edo Liberty +"Discrepancy, Coresets, and Sketches in Machine Learning" +https://proceedings.mlr.press/v99/karnin19a/karnin19a.pdf + +Inspired by the following implementation: https://github.com/edoliberty/streaming-quantiles/blob/f688c8161a25582457b0a09deb4630a81406293b/gde.py + +Requires the use of a :class:`KernelFunction` to compute the distance between two vectors. + +.. autoclass:: density_sketch + :members: + :undoc-members: + :exclude-members: deserialize + + .. rubric:: Static Methods: + + .. automethod:: deserialize + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ diff --git a/docs/5.1.0/_sources/vector/index.rst.txt b/docs/5.1.0/_sources/vector/index.rst.txt new file mode 100644 index 00000000..1b83a43c --- /dev/null +++ b/docs/5.1.0/_sources/vector/index.rst.txt @@ -0,0 +1,12 @@ +Vector Sketches +================== + +.. currentmodule:: dataksetches + +These sketches are designed to accept vector inputs. For now, the library provides only the +:class:`density_sketch` for Kernel Density Estimation. + +.. toctree:: + :maxdepth: 1 + + density_sketch \ No newline at end of file diff --git a/docs/5.1.0/_static/_sphinx_javascript_frameworks_compat.js b/docs/5.1.0/_static/_sphinx_javascript_frameworks_compat.js new file mode 100644 index 00000000..81415803 --- /dev/null +++ b/docs/5.1.0/_static/_sphinx_javascript_frameworks_compat.js @@ -0,0 +1,123 @@ +/* Compatability shim for jQuery and underscores.js. + * + * Copyright Sphinx contributors + * Released under the two clause BSD licence + */ + +/** + * small helper function to urldecode strings + * + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL + */ +jQuery.urldecode = function(x) { + if (!x) { + return x + } + return decodeURIComponent(x.replace(/\+/g, ' ')); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s === 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node, addItems) { + if (node.nodeType === 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && + !jQuery(node.parentNode).hasClass(className) && + !jQuery(node.parentNode).hasClass("nohighlight")) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.className = className; + } + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + if (isInSVG) { + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + var bbox = node.parentElement.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": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} diff --git a/docs/5.1.0/_static/basic.css b/docs/5.1.0/_static/basic.css new file mode 100644 index 00000000..f316efcb --- /dev/null +++ b/docs/5.1.0/_static/basic.css @@ -0,0 +1,925 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- 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: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +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/docs/5.1.0/_static/css/badge_only.css b/docs/5.1.0/_static/css/badge_only.css new file mode 100644 index 00000000..c718cee4 --- /dev/null +++ b/docs/5.1.0/_static/css/badge_only.css @@ -0,0 +1 @@ +.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}} \ No newline at end of file diff --git a/docs/5.1.0/_static/css/fonts/Roboto-Slab-Bold.woff b/docs/5.1.0/_static/css/fonts/Roboto-Slab-Bold.woff new file mode 100644 index 00000000..6cb60000 Binary files /dev/null and b/docs/5.1.0/_static/css/fonts/Roboto-Slab-Bold.woff differ diff --git a/docs/5.1.0/_static/css/fonts/Roboto-Slab-Bold.woff2 b/docs/5.1.0/_static/css/fonts/Roboto-Slab-Bold.woff2 new file mode 100644 index 00000000..7059e231 Binary files /dev/null and b/docs/5.1.0/_static/css/fonts/Roboto-Slab-Bold.woff2 differ diff --git a/docs/5.1.0/_static/css/fonts/Roboto-Slab-Regular.woff b/docs/5.1.0/_static/css/fonts/Roboto-Slab-Regular.woff new file mode 100644 index 00000000..f815f63f Binary files /dev/null and b/docs/5.1.0/_static/css/fonts/Roboto-Slab-Regular.woff differ diff --git a/docs/5.1.0/_static/css/fonts/Roboto-Slab-Regular.woff2 b/docs/5.1.0/_static/css/fonts/Roboto-Slab-Regular.woff2 new file mode 100644 index 00000000..f2c76e5b Binary files /dev/null and b/docs/5.1.0/_static/css/fonts/Roboto-Slab-Regular.woff2 differ diff --git a/docs/5.1.0/_static/css/fonts/fontawesome-webfont.eot b/docs/5.1.0/_static/css/fonts/fontawesome-webfont.eot new file mode 100644 index 00000000..e9f60ca9 Binary files /dev/null and b/docs/5.1.0/_static/css/fonts/fontawesome-webfont.eot differ diff --git a/docs/5.1.0/_static/css/fonts/fontawesome-webfont.svg b/docs/5.1.0/_static/css/fonts/fontawesome-webfont.svg new file mode 100644 index 00000000..855c845e --- /dev/null +++ b/docs/5.1.0/_static/css/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/5.1.0/_static/css/fonts/fontawesome-webfont.ttf b/docs/5.1.0/_static/css/fonts/fontawesome-webfont.ttf new file mode 100644 index 00000000..35acda2f Binary files /dev/null and b/docs/5.1.0/_static/css/fonts/fontawesome-webfont.ttf differ diff --git a/docs/5.1.0/_static/css/fonts/fontawesome-webfont.woff b/docs/5.1.0/_static/css/fonts/fontawesome-webfont.woff new file mode 100644 index 00000000..400014a4 Binary files /dev/null and b/docs/5.1.0/_static/css/fonts/fontawesome-webfont.woff differ diff --git a/docs/5.1.0/_static/css/fonts/fontawesome-webfont.woff2 b/docs/5.1.0/_static/css/fonts/fontawesome-webfont.woff2 new file mode 100644 index 00000000..4d13fc60 Binary files /dev/null and b/docs/5.1.0/_static/css/fonts/fontawesome-webfont.woff2 differ diff --git a/docs/5.1.0/_static/css/fonts/lato-bold-italic.woff b/docs/5.1.0/_static/css/fonts/lato-bold-italic.woff new file mode 100644 index 00000000..88ad05b9 Binary files /dev/null and b/docs/5.1.0/_static/css/fonts/lato-bold-italic.woff differ diff --git a/docs/5.1.0/_static/css/fonts/lato-bold-italic.woff2 b/docs/5.1.0/_static/css/fonts/lato-bold-italic.woff2 new file mode 100644 index 00000000..c4e3d804 Binary files /dev/null and b/docs/5.1.0/_static/css/fonts/lato-bold-italic.woff2 differ diff --git a/docs/5.1.0/_static/css/fonts/lato-bold.woff b/docs/5.1.0/_static/css/fonts/lato-bold.woff new file mode 100644 index 00000000..c6dff51f Binary files /dev/null and b/docs/5.1.0/_static/css/fonts/lato-bold.woff differ diff --git a/docs/5.1.0/_static/css/fonts/lato-bold.woff2 b/docs/5.1.0/_static/css/fonts/lato-bold.woff2 new file mode 100644 index 00000000..bb195043 Binary files /dev/null and b/docs/5.1.0/_static/css/fonts/lato-bold.woff2 differ diff --git a/docs/5.1.0/_static/css/fonts/lato-normal-italic.woff b/docs/5.1.0/_static/css/fonts/lato-normal-italic.woff new file mode 100644 index 00000000..76114bc0 Binary files /dev/null and b/docs/5.1.0/_static/css/fonts/lato-normal-italic.woff differ diff --git a/docs/5.1.0/_static/css/fonts/lato-normal-italic.woff2 b/docs/5.1.0/_static/css/fonts/lato-normal-italic.woff2 new file mode 100644 index 00000000..3404f37e Binary files /dev/null and b/docs/5.1.0/_static/css/fonts/lato-normal-italic.woff2 differ diff --git a/docs/5.1.0/_static/css/fonts/lato-normal.woff b/docs/5.1.0/_static/css/fonts/lato-normal.woff new file mode 100644 index 00000000..ae1307ff Binary files /dev/null and b/docs/5.1.0/_static/css/fonts/lato-normal.woff differ diff --git a/docs/5.1.0/_static/css/fonts/lato-normal.woff2 b/docs/5.1.0/_static/css/fonts/lato-normal.woff2 new file mode 100644 index 00000000..3bf98433 Binary files /dev/null and b/docs/5.1.0/_static/css/fonts/lato-normal.woff2 differ diff --git a/docs/5.1.0/_static/css/theme.css b/docs/5.1.0/_static/css/theme.css new file mode 100644 index 00000000..19a446a0 --- /dev/null +++ b/docs/5.1.0/_static/css/theme.css @@ -0,0 +1,4 @@ +html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden],audio:not([controls]){display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;text-decoration:none}ins,mark{color:#000}mark{background:#ff0;font-style:italic;font-weight:700}.rst-content code,.rst-content tt,code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:after,q:before{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,ol,ul{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure,form{margin:0}label{cursor:pointer}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{body,html,section{background:none!important}*{box-shadow:none!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}.rst-content .toctree-wrapper>p.caption,h2,h3,p{orphans:3;widows:3}.rst-content .toctree-wrapper>p.caption,h2,h3{page-break-after:avoid}}.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .eqno .headerlink:before,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .eqno .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a button.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-left.toctree-expand,.wy-menu-vertical li button.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .eqno .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a button.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-right.toctree-expand,.wy-menu-vertical li button.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .eqno .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a button.pull-left.toctree-expand,.wy-menu-vertical li.on a button.pull-left.toctree-expand,.wy-menu-vertical li button.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .eqno .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a button.pull-right.toctree-expand,.wy-menu-vertical li.on a button.pull-right.toctree-expand,.wy-menu-vertical li button.pull-right.toctree-expand{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li button.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content .eqno a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content p a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li a button.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content .eqno .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content p .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li button.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content .eqno .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a button.toctree-expand,.btn .wy-menu-vertical li.on a button.toctree-expand,.btn .wy-menu-vertical li button.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content .eqno .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a button.toctree-expand,.nav .wy-menu-vertical li.on a button.toctree-expand,.nav .wy-menu-vertical li button.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .eqno .btn .headerlink,.rst-content .eqno .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p .btn .headerlink,.rst-content p .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn button.toctree-expand,.wy-menu-vertical li.current>a .btn button.toctree-expand,.wy-menu-vertical li.current>a .nav button.toctree-expand,.wy-menu-vertical li .nav button.toctree-expand,.wy-menu-vertical li.on a .btn button.toctree-expand,.wy-menu-vertical li.on a .nav button.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .eqno .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li button.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .eqno .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li button.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .eqno .btn .fa-large.headerlink,.rst-content .eqno .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p .btn .fa-large.headerlink,.rst-content p .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn button.fa-large.toctree-expand,.wy-menu-vertical li .nav button.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .eqno .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li button.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .eqno .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li button.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .eqno .btn .fa-spin.headerlink,.rst-content .eqno .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p .btn .fa-spin.headerlink,.rst-content p .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn button.fa-spin.toctree-expand,.wy-menu-vertical li .nav button.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content .eqno .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li button.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content .eqno .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li button.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content .eqno .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li button.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content .eqno .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini button.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.rst-content section ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.rst-content section ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.rst-content section ul li p:last-child,.rst-content section ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.rst-content section ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.rst-content section ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.rst-content section ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content .section ol.arabic,.rst-content .toctree-wrapper ol,.rst-content .toctree-wrapper ol.arabic,.rst-content section ol,.rst-content section ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol.arabic li,.rst-content .section ol li,.rst-content .toctree-wrapper ol.arabic li,.rst-content .toctree-wrapper ol li,.rst-content section ol.arabic li,.rst-content section ol li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol.arabic li ul,.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content .toctree-wrapper ol.arabic li ul,.rst-content .toctree-wrapper ol li p:last-child,.rst-content .toctree-wrapper ol li ul,.rst-content section ol.arabic li ul,.rst-content section ol li p:last-child,.rst-content section ol li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol.arabic li ul li,.rst-content .section ol li ul li,.rst-content .toctree-wrapper ol.arabic li ul li,.rst-content .toctree-wrapper ol li ul li,.rst-content section ol.arabic li ul li,.rst-content section ol li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs>li{display:inline-block;padding-top:5px}.wy-breadcrumbs>li.wy-breadcrumbs-aside{float:right}.rst-content .wy-breadcrumbs>li code,.rst-content .wy-breadcrumbs>li tt,.wy-breadcrumbs>li .rst-content tt,.wy-breadcrumbs>li code{all:inherit;color:inherit}.breadcrumb-item:before{content:"/";color:#bbb;font-size:13px;padding:0 6px 0 3px}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li button.toctree-expand{display:block;float:left;margin-left:-1.2em;line-height:18px;color:#4d4d4d;border:none;background:none;padding:0}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover button.toctree-expand,.wy-menu-vertical li.on a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand{display:block;line-height:18px;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{padding:.4045em 1.618em .4045em 4.045em}.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{padding:.4045em 1.618em .4045em 5.663em}.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a{padding:.4045em 1.618em .4045em 7.281em}.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a{padding:.4045em 1.618em .4045em 8.899em}.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a{padding:.4045em 1.618em .4045em 10.517em}.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a{padding:.4045em 1.618em .4045em 12.135em}.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a{padding:.4045em 1.618em .4045em 13.753em}.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a{padding:.4045em 1.618em .4045em 15.371em}.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 1.618em .4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 button.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 button.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover button.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active button.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em;max-width:100%}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search>a:hover{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.version{margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .eqno .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content .eqno .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}.rst-content .toctree-wrapper>p.caption,.rst-content h1,.rst-content h2,.rst-content h3,.rst-content h4,.rst-content h5,.rst-content h6{margin-bottom:24px}.rst-content img{max-width:100%;height:auto}.rst-content div.figure,.rst-content figure{margin-bottom:24px}.rst-content div.figure .caption-text,.rst-content figure .caption-text{font-style:italic}.rst-content div.figure p:last-child.caption,.rst-content figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center,.rst-content figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img,.rst-content section>a>img,.rst-content section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp,.rst-content div.highlight span.linenos{user-select:none;pointer-events:none}.rst-content div.highlight span.linenos{display:inline-block;padding-left:0;padding-right:12px;margin-right:12px;border-right:1px solid #e6e9ea}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li,.rst-content .toctree-wrapper ol.loweralpha,.rst-content .toctree-wrapper ol.loweralpha>li,.rst-content section ol.loweralpha,.rst-content section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li,.rst-content .toctree-wrapper ol.upperalpha,.rst-content .toctree-wrapper ol.upperalpha>li,.rst-content section ol.upperalpha,.rst-content section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*,.rst-content .toctree-wrapper ol li>*,.rst-content .toctree-wrapper ul li>*,.rst-content section ol li>*,.rst-content section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child,.rst-content .toctree-wrapper ol li>:first-child,.rst-content .toctree-wrapper ul li>:first-child,.rst-content section ol li>:first-child,.rst-content section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child,.rst-content .toctree-wrapper ol li>p,.rst-content .toctree-wrapper ol li>p:last-child,.rst-content .toctree-wrapper ul li>p,.rst-content .toctree-wrapper ul li>p:last-child,.rst-content section ol li>p,.rst-content section ol li>p:last-child,.rst-content section ul li>p,.rst-content section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child,.rst-content .toctree-wrapper ol li>p:only-child,.rst-content .toctree-wrapper ol li>p:only-child:last-child,.rst-content .toctree-wrapper ul li>p:only-child,.rst-content .toctree-wrapper ul li>p:only-child:last-child,.rst-content section ol li>p:only-child,.rst-content section ol li>p:only-child:last-child,.rst-content section ul li>p:only-child,.rst-content section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul,.rst-content .toctree-wrapper ol li>ol,.rst-content .toctree-wrapper ol li>ul,.rst-content .toctree-wrapper ul li>ol,.rst-content .toctree-wrapper ul li>ul,.rst-content section ol li>ol,.rst-content section ol li>ul,.rst-content section ul li>ol,.rst-content section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul,.rst-content .toctree-wrapper ol.simple li>*,.rst-content .toctree-wrapper ol.simple li ol,.rst-content .toctree-wrapper ol.simple li ul,.rst-content .toctree-wrapper ul.simple li>*,.rst-content .toctree-wrapper ul.simple li ol,.rst-content .toctree-wrapper ul.simple li ul,.rst-content section ol.simple li>*,.rst-content section ol.simple li ol,.rst-content section ol.simple li ul,.rst-content section ul.simple li>*,.rst-content section ul.simple li ol,.rst-content section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink{opacity:0;font-size:14px;font-family:FontAwesome;margin-left:.5em}.rst-content .code-block-caption .headerlink:focus,.rst-content .code-block-caption:hover .headerlink,.rst-content .eqno .headerlink:focus,.rst-content .eqno:hover .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink:focus,.rst-content .toctree-wrapper>p.caption:hover .headerlink,.rst-content dl dt .headerlink:focus,.rst-content dl dt:hover .headerlink,.rst-content h1 .headerlink:focus,.rst-content h1:hover .headerlink,.rst-content h2 .headerlink:focus,.rst-content h2:hover .headerlink,.rst-content h3 .headerlink:focus,.rst-content h3:hover .headerlink,.rst-content h4 .headerlink:focus,.rst-content h4:hover .headerlink,.rst-content h5 .headerlink:focus,.rst-content h5:hover .headerlink,.rst-content h6 .headerlink:focus,.rst-content h6:hover .headerlink,.rst-content p.caption .headerlink:focus,.rst-content p.caption:hover .headerlink,.rst-content p .headerlink:focus,.rst-content p:hover .headerlink,.rst-content table>caption .headerlink:focus,.rst-content table>caption:hover .headerlink{opacity:1}.rst-content p a{overflow-wrap:anywhere}.rst-content .wy-table td p,.rst-content .wy-table td ul,.rst-content .wy-table th p,.rst-content .wy-table th ul,.rst-content table.docutils td p,.rst-content table.docutils td ul,.rst-content table.docutils th p,.rst-content table.docutils th ul,.rst-content table.field-list td p,.rst-content table.field-list td ul,.rst-content table.field-list th p,.rst-content table.field-list th ul{font-size:inherit}.rst-content .btn:focus{outline:2px solid}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .citation-reference>span.fn-bracket,.rst-content .footnote-reference>span.fn-bracket{display:none}.rst-content .hlist{width:100%}.rst-content dl dt span.classifier:before{content:" : "}.rst-content dl dt span.classifier-delimiter{display:none!important}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:auto minmax(80%,95%)}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{display:inline-grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{display:grid;grid-template-columns:auto auto minmax(.65rem,auto) minmax(40%,95%)}html.writer-html5 .rst-content aside.citation>span.label,html.writer-html5 .rst-content aside.footnote>span.label,html.writer-html5 .rst-content div.citation>span.label{grid-column-start:1;grid-column-end:2}html.writer-html5 .rst-content aside.citation>span.backrefs,html.writer-html5 .rst-content aside.footnote>span.backrefs,html.writer-html5 .rst-content div.citation>span.backrefs{grid-column-start:2;grid-column-end:3;grid-row-start:1;grid-row-end:3}html.writer-html5 .rst-content aside.citation>p,html.writer-html5 .rst-content aside.footnote>p,html.writer-html5 .rst-content div.citation>p{grid-column-start:4;grid-column-end:5}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{margin-bottom:24px}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.citation>dt>span.brackets:before,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.citation>dt>span.brackets:after,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a{word-break:keep-all}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a:not(:first-child):before,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.citation>dd p,html.writer-html5 .rst-content dl.footnote>dd p{font-size:.9rem}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{padding-left:1rem;padding-right:1rem;font-size:.9rem;line-height:1.2rem}html.writer-html5 .rst-content aside.citation p,html.writer-html5 .rst-content aside.footnote p,html.writer-html5 .rst-content div.citation p{font-size:.9rem;line-height:1.2rem;margin-bottom:12px}html.writer-html5 .rst-content aside.citation span.backrefs,html.writer-html5 .rst-content aside.footnote span.backrefs,html.writer-html5 .rst-content div.citation span.backrefs{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content aside.citation span.backrefs>a,html.writer-html5 .rst-content aside.footnote span.backrefs>a,html.writer-html5 .rst-content div.citation span.backrefs>a{word-break:keep-all}html.writer-html5 .rst-content aside.citation span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content aside.footnote span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content div.citation span.backrefs>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content aside.citation span.label,html.writer-html5 .rst-content aside.footnote span.label,html.writer-html5 .rst-content div.citation span.label{line-height:1.2rem}html.writer-html5 .rst-content aside.citation-list,html.writer-html5 .rst-content aside.footnote-list,html.writer-html5 .rst-content div.citation-list{margin-bottom:24px}html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content aside.footnote-list aside.footnote,html.writer-html5 .rst-content div.citation-list>div.citation,html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content aside.footnote-list aside.footnote code,html.writer-html5 .rst-content aside.footnote-list aside.footnote tt,html.writer-html5 .rst-content aside.footnote code,html.writer-html5 .rst-content aside.footnote tt,html.writer-html5 .rst-content div.citation-list>div.citation code,html.writer-html5 .rst-content div.citation-list>div.citation tt,html.writer-html5 .rst-content dl.citation code,html.writer-html5 .rst-content dl.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c;white-space:normal}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040;overflow-wrap:normal}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}.rst-content dl dd>ol:last-child,.rst-content dl dd>p:last-child,.rst-content dl dd>table:last-child,.rst-content dl dd>ul:last-child{margin-bottom:0}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px;max-width:100%}html.writer-html4 .rst-content dl:not(.docutils) .k,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .k{font-style:italic}html.writer-html4 .rst-content dl:not(.docutils) .descclassname,html.writer-html4 .rst-content dl:not(.docutils) .descname,html.writer-html4 .rst-content dl:not(.docutils) .sig-name,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .sig-name{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#000}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel,.rst-content .menuselection{font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .guilabel,.rst-content .menuselection{border:1px solid #7fbbe3;background:#e7f2fa}.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>.kbd,.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>kbd{color:inherit;font-size:80%;background-color:#fff;border:1px solid #a6a6a6;border-radius:4px;box-shadow:0 2px grey;padding:2.4px 6px;margin:auto 0}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block} \ No newline at end of file diff --git a/docs/5.1.0/_static/doctools.js b/docs/5.1.0/_static/doctools.js new file mode 100644 index 00000000..4d67807d --- /dev/null +++ b/docs/5.1.0/_static/doctools.js @@ -0,0 +1,156 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Base JavaScript utilities for all Sphinx HTML documentation. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"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/docs/5.1.0/_static/documentation_options.js b/docs/5.1.0/_static/documentation_options.js new file mode 100644 index 00000000..e21c068c --- /dev/null +++ b/docs/5.1.0/_static/documentation_options.js @@ -0,0 +1,13 @@ +const DOCUMENTATION_OPTIONS = { + VERSION: '0.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/docs/5.1.0/_static/file.png b/docs/5.1.0/_static/file.png new file mode 100644 index 00000000..a858a410 Binary files /dev/null and b/docs/5.1.0/_static/file.png differ diff --git a/docs/5.1.0/_static/jquery.js b/docs/5.1.0/_static/jquery.js new file mode 100644 index 00000000..c4c6022f --- /dev/null +++ b/docs/5.1.0/_static/jquery.js @@ -0,0 +1,2 @@ +/*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=y.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=y.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),y.elements=c+" "+a,j(b)}function f(a){var b=x[a[v]];return b||(b={},w++,a[v]=w,x[w]=b),b}function g(a,c,d){if(c||(c=b),q)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():u.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||t.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),q)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return y.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(y,b.frag)}function j(a){a||(a=b);var d=f(a);return!y.shivCSS||p||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),q||i(a,d),a}function k(a){for(var b,c=a.getElementsByTagName("*"),e=c.length,f=RegExp("^(?:"+d().join("|")+")$","i"),g=[];e--;)b=c[e],f.test(b.nodeName)&&g.push(b.applyElement(l(b)));return g}function l(a){for(var b,c=a.attributes,d=c.length,e=a.ownerDocument.createElement(A+":"+a.nodeName);d--;)b=c[d],b.specified&&e.setAttribute(b.nodeName,b.nodeValue);return e.style.cssText=a.style.cssText,e}function m(a){for(var b,c=a.split("{"),e=c.length,f=RegExp("(^|[\\s,>+~])("+d().join("|")+")(?=[[\\s,>+~#.:]|$)","gi"),g="$1"+A+"\\:$2";e--;)b=c[e]=c[e].split("}"),b[b.length-1]=b[b.length-1].replace(f,g),c[e]=b.join("}");return c.join("{")}function n(a){for(var b=a.length;b--;)a[b].removeNode()}function o(a){function b(){clearTimeout(g._removeSheetTimer),d&&d.removeNode(!0),d=null}var d,e,g=f(a),h=a.namespaces,i=a.parentWindow;return!B||a.printShived?a:("undefined"==typeof h[A]&&h.add(A),i.attachEvent("onbeforeprint",function(){b();for(var f,g,h,i=a.styleSheets,j=[],l=i.length,n=Array(l);l--;)n[l]=i[l];for(;h=n.pop();)if(!h.disabled&&z.test(h.media)){try{f=h.imports,g=f.length}catch(o){g=0}for(l=0;g>l;l++)n.push(f[l]);try{j.push(h.cssText)}catch(o){}}j=m(j.reverse().join("")),e=k(a),d=c(a,j)}),i.attachEvent("onafterprint",function(){n(e),clearTimeout(g._removeSheetTimer),g._removeSheetTimer=setTimeout(b,500)}),a.printShived=!0,a)}var p,q,r="3.7.3",s=a.html5||{},t=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,u=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,v="_html5shiv",w=0,x={};!function(){try{var a=b.createElement("a");a.innerHTML="",p="hidden"in a,q=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){p=!0,q=!0}}();var y={elements:s.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:r,shivCSS:s.shivCSS!==!1,supportsUnknownElements:q,shivMethods:s.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=y,j(b);var z=/^$|\b(?:all|print)\b/,A="html5shiv",B=!q&&function(){var c=b.documentElement;return!("undefined"==typeof b.namespaces||"undefined"==typeof b.parentWindow||"undefined"==typeof c.applyElement||"undefined"==typeof c.removeNode||"undefined"==typeof a.attachEvent)}();y.type+=" print",y.shivPrint=o,o(b),"object"==typeof module&&module.exports&&(module.exports=y)}("undefined"!=typeof window?window:this,document); \ No newline at end of file diff --git a/docs/5.1.0/_static/js/html5shiv.min.js b/docs/5.1.0/_static/js/html5shiv.min.js new file mode 100644 index 00000000..cd1c674f --- /dev/null +++ b/docs/5.1.0/_static/js/html5shiv.min.js @@ -0,0 +1,4 @@ +/** +* @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed +*/ +!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.3-pre",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b),"object"==typeof module&&module.exports&&(module.exports=t)}("undefined"!=typeof window?window:this,document); \ No newline at end of file diff --git a/docs/5.1.0/_static/js/theme.js b/docs/5.1.0/_static/js/theme.js new file mode 100644 index 00000000..1fddb6ee --- /dev/null +++ b/docs/5.1.0/_static/js/theme.js @@ -0,0 +1 @@ +!function(n){var e={};function t(i){if(e[i])return e[i].exports;var o=e[i]={i:i,l:!1,exports:{}};return n[i].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=n,t.c=e,t.d=function(n,e,i){t.o(n,e)||Object.defineProperty(n,e,{enumerable:!0,get:i})},t.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},t.t=function(n,e){if(1&e&&(n=t(n)),8&e)return n;if(4&e&&"object"==typeof n&&n&&n.__esModule)return n;var i=Object.create(null);if(t.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:n}),2&e&&"string"!=typeof n)for(var o in n)t.d(i,o,function(e){return n[e]}.bind(null,o));return i},t.n=function(n){var e=n&&n.__esModule?function(){return n.default}:function(){return n};return t.d(e,"a",e),e},t.o=function(n,e){return Object.prototype.hasOwnProperty.call(n,e)},t.p="",t(t.s=0)}([function(n,e,t){t(1),n.exports=t(3)},function(n,e,t){(function(){var e="undefined"!=typeof window?window.jQuery:t(2);n.exports.ThemeNav={navBar:null,win:null,winScroll:!1,winResize:!1,linkScroll:!1,winPosition:0,winHeight:null,docHeight:null,isRunning:!1,enable:function(n){var t=this;void 0===n&&(n=!0),t.isRunning||(t.isRunning=!0,e((function(e){t.init(e),t.reset(),t.win.on("hashchange",t.reset),n&&t.win.on("scroll",(function(){t.linkScroll||t.winScroll||(t.winScroll=!0,requestAnimationFrame((function(){t.onScroll()})))})),t.win.on("resize",(function(){t.winResize||(t.winResize=!0,requestAnimationFrame((function(){t.onResize()})))})),t.onResize()})))},enableSticky:function(){this.enable(!0)},init:function(n){n(document);var e=this;this.navBar=n("div.wy-side-scroll:first"),this.win=n(window),n(document).on("click","[data-toggle='wy-nav-top']",(function(){n("[data-toggle='wy-nav-shift']").toggleClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift")})).on("click",".wy-menu-vertical .current ul li a",(function(){var t=n(this);n("[data-toggle='wy-nav-shift']").removeClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift"),e.toggleCurrent(t),e.hashChange()})).on("click","[data-toggle='rst-current-version']",(function(){n("[data-toggle='rst-versions']").toggleClass("shift-up")})),n("table.docutils:not(.field-list,.footnote,.citation)").wrap("
"),n("table.docutils.footnote").wrap("
"),n("table.docutils.citation").wrap("
"),n(".wy-menu-vertical ul").not(".simple").siblings("a").each((function(){var t=n(this);expand=n(''),expand.on("click",(function(n){return e.toggleCurrent(t),n.stopPropagation(),!1})),t.prepend(expand)}))},reset:function(){var n=encodeURI(window.location.hash)||"#";try{var e=$(".wy-menu-vertical"),t=e.find('[href="'+n+'"]');if(0===t.length){var i=$('.document [id="'+n.substring(1)+'"]').closest("div.section");0===(t=e.find('[href="#'+i.attr("id")+'"]')).length&&(t=e.find('[href="#"]'))}if(t.length>0){$(".wy-menu-vertical .current").removeClass("current").attr("aria-expanded","false"),t.addClass("current").attr("aria-expanded","true"),t.closest("li.toctree-l1").parent().addClass("current").attr("aria-expanded","true");for(let n=1;n<=10;n++)t.closest("li.toctree-l"+n).addClass("current").attr("aria-expanded","true");t[0].scrollIntoView()}}catch(n){console.log("Error expanding nav for anchor",n)}},onScroll:function(){this.winScroll=!1;var n=this.win.scrollTop(),e=n+this.winHeight,t=this.navBar.scrollTop()+(n-this.winPosition);n<0||e>this.docHeight||(this.navBar.scrollTop(t),this.winPosition=n)},onResize:function(){this.winResize=!1,this.winHeight=this.win.height(),this.docHeight=$(document).height()},hashChange:function(){this.linkScroll=!0,this.win.one("hashchange",(function(){this.linkScroll=!1}))},toggleCurrent:function(n){var e=n.closest("li");e.siblings("li.current").removeClass("current").attr("aria-expanded","false"),e.siblings().find("li.current").removeClass("current").attr("aria-expanded","false");var t=e.find("> ul li");t.length&&(t.removeClass("current").attr("aria-expanded","false"),e.toggleClass("current").attr("aria-expanded",(function(n,e){return"true"==e?"false":"true"})))}},"undefined"!=typeof window&&(window.SphinxRtdTheme={Navigation:n.exports.ThemeNav,StickyNav:n.exports.ThemeNav}),function(){for(var n=0,e=["ms","moz","webkit","o"],t=0;t0 + 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/docs/5.1.0/_static/minus.png b/docs/5.1.0/_static/minus.png new file mode 100644 index 00000000..d96755fd Binary files /dev/null and b/docs/5.1.0/_static/minus.png differ diff --git a/docs/5.1.0/_static/plus.png b/docs/5.1.0/_static/plus.png new file mode 100644 index 00000000..7107cec9 Binary files /dev/null and b/docs/5.1.0/_static/plus.png differ diff --git a/docs/5.1.0/_static/pygments.css b/docs/5.1.0/_static/pygments.css new file mode 100644 index 00000000..84ab3030 --- /dev/null +++ b/docs/5.1.0/_static/pygments.css @@ -0,0 +1,75 @@ +pre { line-height: 125%; } +td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +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: #3D7B7B; font-style: italic } /* Comment */ +.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .k { color: #008000; font-weight: bold } /* Keyword */ +.highlight .o { color: #666666 } /* Operator */ +.highlight .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */ +.highlight .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #9C6500 } /* Comment.Preproc */ +.highlight .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */ +.highlight .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */ +.highlight .gr { color: #E40000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #008400 } /* Generic.Inserted */ +.highlight .go { color: #717171 } /* Generic.Output */ +.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #0044DD } /* Generic.Traceback */ +.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #008000 } /* Keyword.Pseudo */ +.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #B00040 } /* Keyword.Type */ +.highlight .m { color: #666666 } /* Literal.Number */ +.highlight .s { color: #BA2121 } /* Literal.String */ +.highlight .na { color: #687822 } /* Name.Attribute */ +.highlight .nb { color: #008000 } /* Name.Builtin */ +.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */ +.highlight .no { color: #880000 } /* Name.Constant */ +.highlight .nd { color: #AA22FF } /* Name.Decorator */ +.highlight .ni { color: #717171; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #0000FF } /* Name.Function */ +.highlight .nl { color: #767600 } /* Name.Label */ +.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #19177C } /* Name.Variable */ +.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mb { color: #666666 } /* Literal.Number.Bin */ +.highlight .mf { color: #666666 } /* Literal.Number.Float */ +.highlight .mh { color: #666666 } /* Literal.Number.Hex */ +.highlight .mi { color: #666666 } /* Literal.Number.Integer */ +.highlight .mo { color: #666666 } /* Literal.Number.Oct */ +.highlight .sa { color: #BA2121 } /* Literal.String.Affix */ +.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */ +.highlight .sc { color: #BA2121 } /* Literal.String.Char */ +.highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */ +.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #BA2121 } /* Literal.String.Double */ +.highlight .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */ +.highlight .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */ +.highlight .sx { color: #008000 } /* Literal.String.Other */ +.highlight .sr { color: #A45A77 } /* Literal.String.Regex */ +.highlight .s1 { color: #BA2121 } /* Literal.String.Single */ +.highlight .ss { color: #19177C } /* Literal.String.Symbol */ +.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */ +.highlight .fm { color: #0000FF } /* Name.Function.Magic */ +.highlight .vc { color: #19177C } /* Name.Variable.Class */ +.highlight .vg { color: #19177C } /* Name.Variable.Global */ +.highlight .vi { color: #19177C } /* Name.Variable.Instance */ +.highlight .vm { color: #19177C } /* Name.Variable.Magic */ +.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/docs/5.1.0/_static/searchtools.js b/docs/5.1.0/_static/searchtools.js new file mode 100644 index 00000000..b08d58c9 --- /dev/null +++ b/docs/5.1.0/_static/searchtools.js @@ -0,0 +1,620 @@ +/* + * searchtools.js + * ~~~~~~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for the full-text search. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"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] = 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, + }; +} + +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] = item; + + let listItem = document.createElement("li"); + 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 = _( + "Search finished, found ${resultCount} page(s) matching the search query." + ).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]. +// 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.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]. + 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], + ]); + } + } + } + + // 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], + ]; + 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]], + ]); + }; + 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], + ]); + } + 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/docs/5.1.0/_static/sphinx_highlight.js b/docs/5.1.0/_static/sphinx_highlight.js new file mode 100644 index 00000000..8a96c69a --- /dev/null +++ b/docs/5.1.0/_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/docs/5.1.0/distinct_counting/cpc.html b/docs/5.1.0/distinct_counting/cpc.html new file mode 100644 index 00000000..6b7c53e3 --- /dev/null +++ b/docs/5.1.0/distinct_counting/cpc.html @@ -0,0 +1,270 @@ + + + + + + + Compressed Probabilistic Counting (CPC) — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Compressed Probabilistic Counting (CPC)

+

High performance C++ implementation of Compressed Probabilistic Counting (CPC) Sketch. +This is a unique-counting sketch that implements the Compressed Probabilistic Counting (CPC, a.k.a FM85) algorithms developed by Kevin Lang in his paper +Back to the Future: an Even More Nearly Optimal Cardinality Estimation Algorithm. +This sketch is extremely space-efficient when serialized. +In an apples-to-apples empirical comparison against compressed HyperLogLog sketches, this new algorithm simultaneously wins on the two dimensions of the space/accuracy tradeoff and produces sketches that are smaller than the entropy of HLL, so no possible implementation of compressed HLL can match its space efficiency for a given accuracy. As described in the paper this sketch implements a newly developed ICON estimator algorithm that survives unioning operations, another well-known estimator, the Historical Inverse Probability (HIP) estimator does not. +The update speed performance of this sketch is quite fast and is comparable to the speed of HLL. +The unioning (merging) capability of this sketch also allows for merging of sketches with different configurations of K. +For additional security this sketch can be configured with a user-specified hash seed.

+
+
+class cpc_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.cpc_sketch
+

Reads a bytes object and returns the corresponding cpc_sketch

+
+ +

Non-static Methods:

+
+
+__init__(self, lg_k: int = 11, seed: int = 9001) None
+

Creates a new CPC sketch

+
+
Parameters:
+
    +
  • lg_k (int, optional) – base 2 logarithm of the number of bins in the sketch

  • +
  • seed (int, optional) – seed value for the hash function

  • +
+
+
+
+ +
+
+get_estimate
+

Estimate of the distinct count of the input stream

+
+ +
+
+get_lower_bound
+

Returns an approximate lower bound on the estimate for kappa values in {1, 2, 3}, roughly corresponding to standard deviations

+
+ +
+
+get_upper_bound
+

Returns an approximate upper bound on the estimate for kappa values in {1, 2, 3}, roughly corresponding to standard deviations

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+property lg_k
+

Configured lg_k of this sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, datum: int) -> None

  2. +
+

Updates the sketch with the given 64-bit integer value

+
    +
  1. update(self, datum: float) -> None

  2. +
+

Updates the sketch with the given 64-bit floating point

+
    +
  1. update(self, datum: str) -> None

  2. +
+

Updates the sketch with the given string

+
+ +
+ +
+
+class cpc_union(*args, **kwargs)
+
+
+__init__(self, lg_k: int, seed: int = 9001) None
+
+ +
+
+get_result
+

Returns a CPC sketch with the result of the union

+
+ +
+
+update
+

Updates the union with the provided CPC sketch

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.0/distinct_counting/hyper_log_log.html b/docs/5.1.0/distinct_counting/hyper_log_log.html new file mode 100644 index 00000000..fb30ff6d --- /dev/null +++ b/docs/5.1.0/distinct_counting/hyper_log_log.html @@ -0,0 +1,426 @@ + + + + + + + HyperLogLog (HLL) — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

HyperLogLog (HLL)

+

This is a high performance implementation of Phillipe Flajolet’s HLL sketch but with significantly improved error behavior.

+

If the ONLY use case for sketching is counting uniques and merging, the HLL sketch is a reasonable choice, although the highest performing in terms of accuracy for storage space consumed is CPC (Compressed Probabilistic Counting). For large enough counts, this HLL version (with HLL_4) can be 2 to 16 times smaller than the Theta sketch family for the same accuracy.

+

This implementation offers three different types of HLL sketch, each with different trade-offs with accuracy, space and performance. +These types are specified with the target_hll_type parameter.

+

In terms of accuracy, all three types, for the same lg_config_k, have the same error distribution as a function of n, the number of unique values fed to the sketch. +The configuration parameter lg_config_k is the log-base-2 of k, where k is the number of buckets or slots for the sketch.

+

During warmup, when the sketch has only received a small number of unique items (up to about 10% of k), this implementation leverages a new class of estimator algorithms with significantly better accuracy.

+
+
+class tgt_hll_type(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
+

Target HLL flavor

+
+
+HLL_4 : 4 bits per entry
+
+ +
+
+HLL_6 : 6 bits per entry
+
+ +
+
+HLL_8 : 8 bits per entry
+
+ +
+ +
+
+class hll_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.hll_sketch
+

Reads a bytes object and returns the corresponding hll_sketch

+
+ +
+
+get_max_updatable_serialization_bytes(lg_k: int, tgt_type: _datasketches.tgt_hll_type) int
+

Provides a likely upper bound on serialization size for the given parameters

+
+ +
+
+get_rel_err(upper_bound: bool, unioned: bool, lg_k: int, num_std_devs: int) float
+

Returns the a priori relative error bound for the given parameters

+
+ +

Non-static Methods:

+
+
+__init__(self, lg_k: int, tgt_type: _datasketches.tgt_hll_type = tgt_hll_type.HLL_8, start_max_size: bool = False) None
+

Constructs a new HLL sketch

+
+
Parameters:
+
    +
  • lg_config_k (int) – A full sketch can hold 2^lg_config_k rows. Must be between 7 and 21, inclusive,

  • +
  • tgt_type (tgt_hll_type) – The HLL mode to use, if/when the sketch reaches estimation mode

  • +
  • start_full_size (bool) – Indicates whether to start in HLL mode, keeping memory use constant (if HLL_6 or HLL_8) at the cost of much higher initial memory use. Default (and recommended) is False.

  • +
+
+
+
+ +
+
+get_compact_serialization_bytes
+

Returns the size of the serialized sketch when compressing the exception table if HLL_4

+
+ +
+
+get_estimate
+

Estimate of the distinct count of the input stream

+
+ +
+
+get_lower_bound
+

Returns the approximate lower error bound given the specified number of standard deviations in {1, 2, 3}

+
+ +
+
+get_updatable_serialization_bytes
+

Returns the size of the serialized sketch

+
+ +
+
+get_upper_bound
+

Returns the approximate upper error bound given the specified number of standard deviations in {1, 2, 3}

+
+ +
+
+is_compact
+

True if the sketch is compact, otherwise False

+
+ +
+
+is_empty
+

True if the sketch is empty, otherwise False

+
+ +
+
+property lg_config_k
+

Configured lg_k value for the sketch

+
+ +
+
+reset
+

Resets the sketch to the empty state in coupon collection mode

+
+ +
+
+serialize_compact
+

Serializes the sketch into a bytes object, compressing the exception table if HLL_4

+
+ +
+
+serialize_updatable
+

Serializes the sketch into a bytes object

+
+ +
+
+property tgt_type
+

The HLL type (4, 6, or 8) when in estimation mode

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, datum: int) -> None

  2. +
+

Updates the sketch with the given integral value

+
    +
  1. update(self, datum: float) -> None

  2. +
+

Updates the sketch with the given floating point value

+
    +
  1. update(self, datum: str) -> None

  2. +
+

Updates the sketch with the given string value

+
+ +
+ +
+
+class hll_union(*args, **kwargs)
+

Static Methods:

+
+
+get_rel_err(upper_bound: bool, unioned: bool, lg_k: int, num_std_devs: int) float
+

Returns the a priori relative error bound for the given parameters

+
+ +

Non-static Methods:

+
+
+__init__(self, lg_max_k: int) None
+

Construct an hll_union object if the given size.

+
+
Parameters:
+

lg_max_k (int) – The maximum size, in log2, of k. Must be between 7 and 21, inclusive.

+
+
+
+ +
+
+get_estimate
+

Estimate of the distinct count of the input stream

+
+ +
+
+get_lower_bound
+

Returns the approximate lower error bound given the specified number of standard deviations in {1, 2, 3}

+
+ +
+
+get_result
+

Returns a sketch of the target type representing the current union state

+
+ +
+
+get_upper_bound
+

Returns the approximate upper error bound given the specified number of standard deviations in {1, 2, 3}

+
+ +
+
+is_empty
+

True if the union is empty, otherwise False

+
+ +
+
+property lg_config_k
+

Configured lg_k value for the union

+
+ +
+
+reset
+

Resets the union to the empty state

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, sketch: _datasketches.hll_sketch) -> None

  2. +
+

Updates the union with the given HLL sketch

+
    +
  1. update(self, datum: int) -> None

  2. +
+

Updates the union with the given integral value

+
    +
  1. update(self, datum: float) -> None

  2. +
+

Updates the union with the given floating point value

+
    +
  1. update(self, datum: str) -> None

  2. +
+

Updates the union with the given string value

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.0/distinct_counting/index.html b/docs/5.1.0/distinct_counting/index.html new file mode 100644 index 00000000..e75799a9 --- /dev/null +++ b/docs/5.1.0/distinct_counting/index.html @@ -0,0 +1,152 @@ + + + + + + + Distinct Counting — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Distinct Counting

+

Distinct counting is one of the earliest tasks to which sketches were applied. The concept is simple: +Provide an estimate of the number of unique elements in a set of data. One of the earliest solutions came +from Flajolet and Martin in 1985 with their seminal work +Probabilistic counting Algorithms for Data Base Applications.

+

The DataSketches library offers several types of distinct counting sketches, each with different properties.

+
+
    +
  • hll_sketch: Hyper Log Log, a well-known sketch for distinct counting but no longer state-of-the-art.

  • +
  • cpc_sketch: Provides a better accuracy-space trade-off than HLL, but with a somewhat larger footprint while in-memory.

  • +
  • theta_sketch: Theta sketch, a type of k-minimum value sketch, which provide good performance with intersection and set difference operations.

  • +
  • tuple_sketch: Tuple sketch, which is similar to a theta sketch but supports additional data stored with each key.

  • +
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.0/distinct_counting/theta.html b/docs/5.1.0/distinct_counting/theta.html new file mode 100644 index 00000000..ed83d933 --- /dev/null +++ b/docs/5.1.0/distinct_counting/theta.html @@ -0,0 +1,440 @@ + + + + + + + Theta Sketch — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Theta Sketch

+

Theta sketches are used for distinct counting.

+

The theta package contains the basic sketch classes that are members of the Theta Sketch Framework. +There is a separate Tuple package for many of the sketches that are derived from the same algorithms defined in the Theta Sketch Framework paper.

+

The Theta Sketch sketch is a space-efficient method for estimating cardinalities of sets. +It can also easily handle set operations (such as union, intersection, difference) while maintaining good accuracy. +Theta sketch is a practical variant of the K-Minimum Values sketch which avoids the need to sort the stored +hash values on every insertion to the sketch. +It has better error properties than the HyperLogLog sketch for set operations beyond the simple union.

+

Set operations (union, intersection, A-not-B) are performed through the use of dedicated objects.

+

Several Jaccard similarity +measures can be computed between theta sketches with the theta_jaccard_similarity class.

+
+
+class theta_sketch
+

An abstract base class for theta sketches

+
+
+get_estimate
+

Estimate of the distinct count of the input stream

+
+ +
+
+get_lower_bound
+

Returns an approximate lower bound on the estimate at standard deviations in {1, 2, 3}

+
+ +
+
+get_seed_hash
+

Returns a hash of the seed used in the sketch

+
+ +
+
+get_upper_bound
+

Returns an approximate upper bound on the estimate at standard deviations in {1, 2, 3}

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if sketch is in estimation mode, otherwise False

+
+ +
+
+is_ordered
+

Returns True if the sketch entries are sorted, otherwise False

+
+ +
+
+property num_retained
+

The number of items currently in the sketch

+
+ +
+
+property theta
+

Theta (effective sampling rate) as a fraction from 0 to 1

+
+ +
+
+property theta64
+

Theta as 64-bit value

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+ +
+
+class update_theta_sketch(*args, **kwargs)
+
+
+__init__(self, lg_k: int = 12, p: float = 1.0, seed: int = 9001) None
+

Creates an update_theta_sketch using the provided parameters

+
+
Parameters:
+
    +
  • lg_k (int, optional) – base 2 logarithm of the maximum size of the sketch. Default 12.

  • +
  • p (float, optional) – an initial sampling rate to use. Default 1.0

  • +
  • seed (int, optional) – the seed to use when hashing values

  • +
+
+
+
+ +
+
+compact
+

Returns a compacted form of the sketch, optionally sorting it

+
+ +
+
+reset
+

Resets the sketch to the initial empty state

+
+ +
+
+trim
+

Removes retained entries in excess of the nominal size k (if any)

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, datum: int) -> None

  2. +
+

Updates the sketch with the given integral value

+
    +
  1. update(self, datum: float) -> None

  2. +
+

Updates the sketch with the given floating point value

+
    +
  1. update(self, datum: str) -> None

  2. +
+

Updates the sketch with the given string

+
+ +
+ +
+
+class compact_theta_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, seed: int = 9001) _datasketches.compact_theta_sketch
+

Reads a bytes object and returns the corresponding compact_theta_sketch

+
+ +

Non-static Methods:

+
+
+__init__(self, arg0: _datasketches.theta_sketch, arg1: bool, /) None
+

Creates a compact_theta_sketch from an existing theta_sketch.

+
+
Parameters:
+
    +
  • other (theta_sketch) – a source theta_sketch

  • +
  • ordered (bool) – whether the incoming sketch entries are sorted. Default True

  • +
+
+
+
+ +
+
+serialize
+

Serializes the sketch into a bytes object, optionally compressing the data

+
+ +
+ +
+
+class theta_union(*args, **kwargs)
+
+
+__init__(self, lg_k: int = 12, p: float = 1.0, seed: int = 9001) None
+

Creates a theta_union using the provided parameters

+
+
Parameters:
+
    +
  • lg_k (int, optional) – base 2 logarithm of the maximum size of the union. Default 12.

  • +
  • p (float, optional) – an initial sampling rate to use. Default 1.0

  • +
  • seed (int, optional) – the seed to use when hashing values. Must match all sketch seeds.

  • +
+
+
+
+ +
+
+get_result
+

Returns the sketch corresponding to the union result

+
+ +
+
+update
+

Updates the union with the given sketch

+
+ +
+ +
+
+class theta_intersection(*args, **kwargs)
+
+
+__init__(self, seed: int = 9001) None
+

Creates a theta_intersection using the provided parameters

+
+
Parameters:
+

seed (int, optional) – the seed to use when hashing values. Must match all sketch seeds

+
+
+
+ +
+
+get_result
+

Returns the sketch corresponding to the intersection result

+
+ +
+
+has_result
+

Returns True if the intersection has a valid result, otherwise False

+
+ +
+
+update
+

Intersections the provided sketch with the current intersection state

+
+ +
+ +
+
+class theta_a_not_b(*args, **kwargs)
+
+
+__init__(self, seed: int = 9001) None
+

Creates a tuple_a_not_b object

+
+
Parameters:
+

seed (int, optional) – the seed to use when hashing values. Must match all sketch seeds.

+
+
+
+ +
+
+compute
+

Returns a sketch with the result of applying the A-not-B operation on the given inputs

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.0/distinct_counting/tuple.html b/docs/5.1.0/distinct_counting/tuple.html new file mode 100644 index 00000000..ce19e79d --- /dev/null +++ b/docs/5.1.0/distinct_counting/tuple.html @@ -0,0 +1,514 @@ + + + + + + + Tuple Sketch — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Tuple Sketch

+

Tuple sketches are an extension of Theta sketches, meaning they provide estimate of distinct counts, that +allow the keeping of arbitrary summaries associated with each retained key +(for example, a count for every key). The use of a tuple_sketch requires a TuplePolicy which +defines how summaries are created, updated, merged, or intersected. The library provides a few basic +examples of TuplePolicy implementations, but the right custom summary and policy can allow very +complicated analysis to be performed quite easily.

+

Set operations (union, intersection, A-not-B) are performed through the use of dedicated objects.

+

Several Jaccard similarity +measures can be computed between theta sketches with the tuple_jaccard_similarity class.

+
+

Note

+

Serializing and deserializing this sketch requires the use of a PyObjectSerDe.

+
+
+
+class tuple_sketch
+

An abstract base class for tuple sketches.

+
+
+DEFAULT_SEED = 9001
+
+ +
+
+get_estimate
+

Estimate of the distinct count of the input stream

+
+ +
+
+get_lower_bound
+

Returns an approximate lower bound on the estimate at standard deviations in {1, 2, 3}

+
+ +
+
+get_seed_hash
+

Returns a hash of the seed used in the sketch

+
+ +
+
+get_upper_bound
+

Returns an approximate upper bound on the estimate at standard deviations in {1, 2, 3}

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if sketch is in estimation mode, otherwise False

+
+ +
+
+is_ordered
+

Returns True if the sketch entries are sorted, otherwise False

+
+ +
+
+property num_retained
+

The number of items currently in the sketch

+
+ +
+
+property theta
+

Theta (effective sampling rate) as a fraction from 0 to 1

+
+ +
+
+property theta64
+

Theta as 64-bit value

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+ +
+
+class update_tuple_sketch(*args, **kwargs)
+
+
+__init__(self, policy: _datasketches.TuplePolicy, lg_k: int = 12, p: float = 1.0, seed: int = 9001) None
+

Creates an update_tuple_sketch using the provided parameters

+
+
Parameters:
+
    +
  • policy (TuplePolicy) – a policy to use when updating

  • +
  • lg_k (int, optional) – base 2 logarithm of the maximum size of the sketch. Default 12.

  • +
  • p (float, optional) – an initial sampling rate to use. Default 1.0

  • +
  • seed (int, optional) – the seed to use when hashing values

  • +
+
+
+
+ +
+
+compact
+

Returns a compacted form of the sketch, optionally sorting it

+
+ +
+
+filter
+

Produces a compact_tuple_sketch from the given sketch by applying a predicate to the summary in each entry.

+
+
Parameters:
+

predicate – A function returning true or value evaluated on each tuple summary

+
+
Returns:
+

A compact_tuple_sketch with the selected entries

+
+
Return type:
+

compact_tuple_sketch

+
+
+
+ +
+
+reset
+

Resets the sketch to the initial empty state

+
+ +
+
+trim
+

Removes retained entries in excess of the nominal size k (if any)

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, datum: int, value: object) -> None

  2. +
+

Updates the sketch with the given integral item and summary value

+
    +
  1. update(self, datum: float, value: object) -> None

  2. +
+

Updates the sketch with the given floating point item and summary value

+
    +
  1. update(self, datum: str, value: object) -> None

  2. +
+

Updates the sketch with the given string item and summary value

+
+ +
+ +
+
+class compact_tuple_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe, seed: int = 9001) _datasketches.compact_tuple_sketch
+

Reads a bytes object and returns the corresponding compact_tuple_sketch

+
+ +

Non-static Methods:

+
+
+__init__(self, other: _datasketches.tuple_sketch, ordered: bool = True) None
+
+__init__(self, other: _datasketches.theta_sketch, summary: object) None
+

Overloaded function.

+
    +
  1. __init__(self, other: _datasketches.tuple_sketch, ordered: bool = True) -> None

  2. +
+

Creates a compact_tuple_sketch from an existing tuple_sketch.

+
+
Parameters:
+
    +
  • other (tuple_sketch) – a sourch tuple_sketch

  • +
  • ordered (bool, optional) – whether the incoming sketch entries are sorted. Default True

  • +
+
+
+
    +
  1. __init__(self, other: _datasketches.theta_sketch, summary: object) -> None

  2. +
+

Creates a compact_tuple_sketch from a theta_sketch using a fixed summary value.

+
+
Parameters:
+
    +
  • other (theta_sketch) – a source theta sketch

  • +
  • summary (object) – a summary to use for every sketch entry

  • +
+
+
+
+ +
+
+filter
+

Produces a compact_tuple_sketch from the given sketch by applying a predicate to the summary in each entry.

+
+
Parameters:
+

predicate – A function returning true or value evaluated on each tuple summary

+
+
Returns:
+

A compact_tuple_sketch with the selected entries

+
+
Return type:
+

compact_tuple_sketch

+
+
+
+ +
+
+serialize
+

Serializes the sketch into a bytes object

+
+ +
+ +
+
+class tuple_union(*args, **kwargs)
+
+
+__init__(self, policy: _datasketches.TuplePolicy, lg_k: int = 12, p: float = 1.0, seed: int = 9001) None
+

Creates a tuple_union using the provided parameters

+
+
Parameters:
+
    +
  • policy (TuplePolicy) – a policy to use when unioning entries

  • +
  • lg_k (int, optional) – base 2 logarithm of the maximum size of the union. Default 12.

  • +
  • p (float, optional) – an initial sampling rate to use. Default 1.0

  • +
  • seed (int, optional) – the seed to use when hashing values. Must match any sketch seeds.

  • +
+
+
+
+ +
+
+get_result
+

Returns the sketch corresponding to the union result

+
+ +
+
+reset
+

Resets the sketch to the initial empty

+
+ +
+
+update
+

Updates the union with the given sketch

+
+ +
+ +
+
+class tuple_intersection(*args, **kwargs)
+
+
+__init__(self, policy: _datasketches.TuplePolicy, seed: int = 9001) None
+

Creates a tuple_intersection using the provided parameters

+
+
Parameters:
+
    +
  • policy (TuplePolicy) – a policy to use when intersecting entries

  • +
  • seed (int, optional) – the seed to use when hashing values. Must match any sketch seeds

  • +
+
+
+
+ +
+
+get_result
+

Returns the sketch corresponding to the intersection result

+
+ +
+
+has_result
+

Returns True if the intersection has a valid result, otherwise False

+
+ +
+
+update
+

Intersects the provided sketch with the current intersection state

+
+ +
+ +
+
+class tuple_a_not_b(*args, **kwargs)
+
+
+__init__(self, seed: int = 9001) None
+

Creates a tuple_a_not_b object

+
+
Parameters:
+

seed (int, optional) – the seed to use when hashing values. Must match any sketch seeds.

+
+
+
+ +
+
+compute
+

Returns a sketch with the result of applying the A-not-B operation on the given inputs

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.0/frequency/count_min_sketch.html b/docs/5.1.0/frequency/count_min_sketch.html new file mode 100644 index 00000000..c6a8e366 --- /dev/null +++ b/docs/5.1.0/frequency/count_min_sketch.html @@ -0,0 +1,303 @@ + + + + + + + CountMin Sketch — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

CountMin Sketch

+

The CountMin sketch, as described in Cormode and Muthukrishnan in +http://dimacs.rutgers.edu/~graham/pubs/papers/cm-full.pdf, +is used for approximate Frequency Estimation. +For an item \(x\) with frequency \(f_x\), the sketch provides an estimate, \(\hat{f_x}\), +such that \(f_x \approx \hat{f_x}.\) +The sketch guarantees that \(f_x \le \hat{f_x}\) and provides a probabilistic upper bound which is dependent on the size parameters. +The sketch provides an estimate of the occurrence frequency for any queried item but, in contrast +to the Frequent Items Sketch, this sketch does not provide a list of +heavy hitters.

+
+
+class count_min_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.count_min_sketch
+

Reads a bytes object and returns the corresponding count_min_sketch

+
+ +
+
+suggest_num_buckets(relative_error: float) int
+

Suggests the number of buckets needed to achieve an accuracy within the provided relative_error. For example, when relative_error = 0.05, the returned frequency estimates satisfy the ‘relative_error’ guarantee that never overestimates the weights but may underestimate the weights by 5% of the total weight in the sketch. Returns the number of hash buckets at every level of the sketch required in order to obtain the specified relative error.

+
+ +
+
+suggest_num_hashes(confidence: float) int
+

Suggests the number of hashes needed to achieve the provided confidence. For example, with 95% confidence, frequency estimates satisfy the ‘relative_error’ guarantee. Returns the number of hash functions that are required in order to achieve the specified confidence of the sketch. confidence = 1 - delta, with delta denoting the sketch failure probability.

+
+ +

Non-static Methods:

+
+
+get_estimate
+

Overloaded function.

+
    +
  1. get_estimate(self, item: int) -> float

  2. +
+

Returns an estimate of the frequency of the provided 64-bit integer value

+
    +
  1. get_estimate(self, item: str) -> float

  2. +
+

Returns an estimate of the frequency of the provided string

+
+ +
+
+get_lower_bound
+

Overloaded function.

+
    +
  1. get_lower_bound(self, item: int) -> float

  2. +
+

Returns a lower bound on the estimate for the given 64-bit integer value

+
    +
  1. get_lower_bound(self, item: str) -> float

  2. +
+

Returns a lower bound on the estimate for the provided string

+
+ +
+
+get_relative_error
+

Returns the maximum permissible error for any frequency estimate query

+
+ +
+
+get_serialized_size_bytes
+

Returns the size in bytes of the serialized image of the sketch

+
+ +
+
+get_upper_bound
+

Overloaded function.

+
    +
  1. get_upper_bound(self, item: int) -> float

  2. +
+

Returns an upper bound on the estimate for the given 64-bit integer value

+
    +
  1. get_upper_bound(self, item: str) -> float

  2. +
+

Returns an upper bound on the estimate for the provided string

+
+ +
+
+is_empty
+

Returns True if the sketch has seen no items, otherwise False

+
+ +
+
+merge
+

Merges the provided other sketch into this one

+
+ +
+
+property num_buckets
+

The configured number of buckets for the sketch

+
+ +
+
+property num_hashes
+

The configured number of hashes for the sketch

+
+ +
+
+property seed
+

The base hash seed for the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+property total_weight
+

The total weight currently inserted into the stream

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: int, weight: float = 1.0) -> None

  2. +
+

Updates the sketch with the given 64-bit integer value

+
    +
  1. update(self, item: str, weight: float = 1.0) -> None

  2. +
+

Updates the sketch with the given string

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.0/frequency/frequent_items.html b/docs/5.1.0/frequency/frequent_items.html new file mode 100644 index 00000000..5cd5d1b6 --- /dev/null +++ b/docs/5.1.0/frequency/frequent_items.html @@ -0,0 +1,479 @@ + + + + + + + Frequent Items — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Frequent Items

+

This sketch is useful for tracking approximate frequencies of items (object or string) with optional associated +integer counts that are members of a multiset of such items. +The true frequency of an item is defined to be the sum of associated counts.

+

This implementation provides the following capabilities:

+
    +
  • Estimate the frequency of an item.

  • +
  • Return upper and lower bounds of any item, such that the true frequency is always between the upper and lower bounds.

  • +
  • Return a global maximum error that holds for all items in the stream.

  • +
  • Return an array of frequent items that qualify either a NO_FALSE_POSITIVES or a NO_FALSE_NEGATIVES error type.

  • +
  • Merge itself with another sketch object created from this class.

  • +
  • Serialize/Deserialize to/from a byte array.

  • +
+

Space Usage

+

The sketch is initialized with a maximum map size, maxMapSize, that specifies the maximum physical length of the internal hash map of the form (object item, int count). +The maximum map size is always a power of 2, defined through the variables lg_max_map_size.

+

The hash map starts at a very small size (8 entries) and grows as needed up to the specified maximum map size.

+

Excluding external space required for the item objects, the internal memory space usage of this sketch is 18 * mapSize bytes (assuming 8 bytes for each reference), +plus a small constant number of additional bytes. +The internal memory space usage of this sketch will never exceed 18 * maxMapSize bytes, plus a small constant number of additional bytes.

+

Maximum Capacity of the Sketch

+

The LOAD_FACTOR for the hash map is internally set at \(75\%\), which means at any time the map capacity of (item, count) pairs is mapCap = 0.75 * mapSize. +The maximum capacity of (item, count) pairs of the sketch is maxMapCap = 0.75 * maxMapSize.

+

Updating the sketch with ``(item, count)`` pairs

+

If the item is found in the hash map, the mapped count field (the “counter”) is incremented by the incoming count; otherwise, a new counter (item, count) pair is created. +If the number of tracked counters reaches the maximum capacity of the hash map, the sketch decrements all of the counters (by an approximately computed median) +and removes any non-positive counters.

+

Accuracy

+

If fewer than 0.75 * maxMapSize different items are inserted into the sketch, the estimated frequencies returned by the sketch will be exact.

+

The logic of the frequent items sketch is such that the stored counts and true counts are never too different. +More specifically, for any item, the sketch can return an estimate of the true frequency of item, along with upper and lower bounds on the frequency (that hold deterministically).

+

For this implementation and for a specific active item, it is guaranteed that the true frequency will be between the Upper Bound (UB) and the Lower Bound (LB) computed for that item. +Specifically, (UB- LB) W * epsilon, where \(W\) denotes the sum of all item counts, and \(epsilon = 3.5/M\), where \(epsilon = M\) is the maxMapSize.

+

This is a worst-case guarantee that applies to arbitrary inputs. +For inputs typically seen in practice, (UB-LB) is usually much smaller.

+

Background

+

This code implements a variant of what is commonly known as the “Misra-Gries algorithm”. +Variants of it were discovered and rediscovered and redesigned several times over the years:

+
    +
  • Finding repeated elements, Misra, Gries, 1982

  • +
  • Frequency estimation of Internet packet streams with limited space Demaine, Lopez-Ortiz, Munro, 2002

  • +
  • A simple algorithm for finding frequent elements in streams and bags Karp, Shenker, Papadimitriou, 2003

  • +
  • Efficient Computation of Frequent and Top-k Elements in Data Streams Metwally, Agrawal, Abbadi, 2006

  • +
+

For speed, we do employ some randomization that introduces a small probability that our proof of the worst-case bound might not apply to a given run. +However, we have ensured that this probability is extremely small. +For example, if the stream causes one table purge (rebuild), our proof of the worst-case bound applies with a probability of at least 1 - 1E-14. +If the stream causes 1E9 purges, our proof applies with a probability of at least 1 - 1E-5.

+

There are two flavors of Frequent Items Sketches, one with generic items (objects) and another specific to strings. +The string version is a legacy name from before the library supported generic objects and is retained +only for backwards compatibility.

+
+

Note

+

The frequent_items_sketch uses an input object’s __hash__ and __eq__ methods.

+
+
+

Note

+

Serializing and deserializing the frequent_items_sketch requires the use of a PyObjectSerDe.

+
+
+
+class frequent_items_error_type(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
+
+
+NO_FALSE_POSITIVES : Returns only true positives but may miss some heavy hitters.
+
+ +
+
+NO_FALSE_NEGATIVES : Does not miss any heavy hitters but may return false positives.
+
+ +
+ +
+
+class frequent_items_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe) _datasketches.frequent_items_sketch
+

Reads a bytes object using the provided serde and returns the corresponding frequent_strings_sketch.

+
+ +
+
+get_epsilon_for_lg_size(lg_max_map_size: int) float
+

Returns the epsilon value used to compute a priori error for a given log2(max_map_size)

+
+ +
+
+get_apriori_error(lg_max_map_size: int, estimated_total_weight: int) float
+

Returns the estimated a priori error given the max_map_size for the sketch and the estimated_total_stream_weight.

+
+ +

Non-static Methods:

+
+
+__init__(self, lg_max_k: int) None
+

Creates an instance of the sketch

+
+
Parameters:
+

lg_max_k (int) – base 2 logarithm of the maximum size of the internal hash map of the sketch. Maximum capacity is 0.75 of this value, which is the maximum number of distinct items the sketch can contain.

+
+
+
+ +
+
+property epsilon
+

The epsilon value used by the sketch to compute error

+
+ +
+
+get_estimate
+

Returns the estimate of the weight (frequency) of the given item. +Note: The true frequency of a item would be the sum of the counts as a result of the two update functions.

+
+ +
+
+get_frequent_items
+
+ +
+
+get_lower_bound
+

Returns the guaranteed lower bound weight (frequency) of the given item.

+
+ +
+
+get_serialized_size_bytes
+

Computes the size needed to serialize the current state of the sketch using the provided serde. This can be expensive since every item needs to be looked at.

+
+ +
+
+get_upper_bound
+

Returns the guaranteed upper bound weight (frequency) of the given item.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+merge
+

Merges the given sketch into this one

+
+ +
+
+property num_active_items
+

The number of active items in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object using the provided serde.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+property total_weight
+

The sum of the weights (frequencies) in the stream seen so far by the sketch

+
+ +
+
+update
+

Updates the sketch with the given string and, optionally, a weight

+
+ +
+ +
+
+class frequent_strings_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.frequent_strings_sketch
+

Reads a bytes object and returns the corresponding frequent_strings_sketch.

+
+ +
+
+get_epsilon_for_lg_size(lg_max_map_size: int) float
+

Returns the epsilon value used to compute a priori error for a given log2(max_map_size)

+
+ +
+
+get_apriori_error(lg_max_map_size: int, estimated_total_weight: int) float
+

Returns the estimated a priori error given the max_map_size for the sketch and the estimated_total_stream_weight.

+
+ +

Non-static Methods:

+
+
+__init__(self, lg_max_k: int) None
+

Creates an instance of the sketch

+
+
Parameters:
+

lg_max_k (int) – base 2 logarithm of the maximum size of the internal hash map of the sketch. Maximum capacity is 0.75 of this value, which is the maximum number of distinct items the sketch can contain.

+
+
+
+ +
+
+property epsilon
+

The epsilon value used by the sketch to compute error

+
+ +
+
+get_estimate
+

Returns the estimate of the weight (frequency) of the given item. +Note: The true frequency of a item would be the sum of the counts as a result of the two update functions.

+
+ +
+
+get_frequent_items
+
+ +
+
+get_lower_bound
+

Returns the guaranteed lower bound weight (frequency) of the given item.

+
+ +
+
+get_serialized_size_bytes
+

Computes the size needed to serialize the current state of the sketch. This can be expensive since every item needs to be looked at.

+
+ +
+
+get_upper_bound
+

Returns the guaranteed upper bound weight (frequency) of the given item.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+merge
+

Merges the given sketch into this one

+
+ +
+
+property num_active_items
+

The number of active items in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+property total_weight
+

The sum of the weights (frequencies) in the stream seen so far by the sketch

+
+ +
+
+update
+

Updates the sketch with the given string and, optionally, a weight

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.0/frequency/index.html b/docs/5.1.0/frequency/index.html new file mode 100644 index 00000000..99bd3d37 --- /dev/null +++ b/docs/5.1.0/frequency/index.html @@ -0,0 +1,145 @@ + + + + + + + Frequency Sketches — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Frequency Sketches

+

Frequency estimation involves determining how often an item has been seen in a stream. The library currently +offers two types of sketches for frequency estimation, one of which has two closely-related variants.

+
+
    +
  • frequent_items_sketch: Identifies the Top K or heavy hitters in a stream, those items whose weight is above a certain percentage of the entire stream. Does not necessarily provide an estimate for most items outside the heavy hitters.

  • +
  • frequent_strings_sketch: Like the items version but containing snly strings (an implementation from before the library handled generic objects).

  • +
  • count_min_sketch: Provides an estimate for any item, regardless of relative weight, but does not maintain a list of the heaviest items.

  • +
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.0/genindex.html b/docs/5.1.0/genindex.html new file mode 100644 index 00000000..89991cbf --- /dev/null +++ b/docs/5.1.0/genindex.html @@ -0,0 +1,1390 @@ + + + + + + Index — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ + +

Index

+ +
+ _ + | A + | C + | D + | E + | F + | G + | H + | I + | J + | K + | L + | M + | N + | P + | Q + | R + | S + | T + | U + | V + +
+

_

+ + +
+ +

A

+ + +
+ +

C

+ + + +
+ +

D

+ + + +
+ +

E

+ + + +
+ +

F

+ + + +
+ +

G

+ + + +
+ +

H

+ + + +
+ +

I

+ + + +
+ +

J

+ + +
+ +

K

+ + + +
+ +

L

+ + + +
+ +

M

+ + + +
+ +

N

+ + + +
+ +

P

+ + + +
+ +

Q

+ + + +
+ +

R

+ + +
+ +

S

+ + + +
+ +

T

+ + + +
+ +

U

+ + + +
+ +

V

+ + + +
+ + + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.0/helper/index.html b/docs/5.1.0/helper/index.html new file mode 100644 index 00000000..d977f1ec --- /dev/null +++ b/docs/5.1.0/helper/index.html @@ -0,0 +1,154 @@ + + + + + + + Helper Classes — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Helper Classes

+

These classes are required for certain sketches or specific +functionality within sketches. +Some of them are abstract base classes, but in those cases there is at +least one reference example of a concrete class.

+
+
    +
  • serde is used when serializing and deserializing sketches.

  • +
  • jaccard is used to compute the Jaccard similarity between pairs of theta or tuple sketches.

  • +
  • tuple_policy is required to use a tuple_sketch by specifying how summaries are combined.

  • +
  • ks_test() performs a Kolmogorov-Smirnov test on absolute-error quantiles family sketches.

  • +
  • kernel_function is required when using a kernel_sketch for Kernel Density Estimation.

  • +
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.0/helper/jaccard.html b/docs/5.1.0/helper/jaccard.html new file mode 100644 index 00000000..b66dbf01 --- /dev/null +++ b/docs/5.1.0/helper/jaccard.html @@ -0,0 +1,212 @@ + + + + + + + Jaccard Similarity — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Jaccard Similarity

+

These objects provide measures related to the Jaccard similarity +of theta_sketch and tuple_sketch objects.

+

Note that there are separate classes to be used for theta and tuple sketches.

+
+
+class theta_jaccard_similarity
+

An object to help compute Jaccard similarity between theta sketches.

+
+
+jaccard(sketch_a: _datasketches.theta_sketch, sketch_b: _datasketches.theta_sketch, seed: int = 9001) list[float]
+

Returns a list with {lower_bound, estimate, upper_bound} of the Jaccard similarity between sketches

+
+ +
+
+exactly_equal(sketch_a: _datasketches.theta_sketch, sketch_b: _datasketches.theta_sketch, seed: int = 9001) bool
+

Returns True if sketch_a and sketch_b are equivalent, otherwise False

+
+ +
+
+similarity_test(actual: _datasketches.theta_sketch, expected: _datasketches.theta_sketch, threshold: float, seed: int = 9001) bool
+

Tests similarity of an actual sketch against an expected sketch. Computers the lower bound of the Jaccard index J_{LB} of the actual and expected sketches. If J_{LB} >= threshold, then the sketches are considered to be similar with a confidence of 97.7% and returns True, otherwise False.

+
+ +
+
+dissimilarity_test(actual: _datasketches.theta_sketch, expected: _datasketches.theta_sketch, threshold: float, seed: int = 9001) bool
+

Tests dissimilarity of an actual sketch against an expected sketch. Computers the lower bound of the Jaccard index J_{UB} of the actual and expected sketches. If J_{UB} <= threshold, then the sketches are considered to be dissimilar with a confidence of 97.7% and returns True, otherwise False.

+
+ +
+ +
+
+class tuple_jaccard_similarity
+

An object to help compute Jaccard similarity between tuple sketches.

+
+
+jaccard(sketch_a: _datasketches.tuple_sketch, sketch_b: _datasketches.tuple_sketch, seed: int = 9001) list[float]
+

Returns a list with {lower_bound, estimate, upper_bound} of the Jaccard similarity between sketches

+
+ +
+
+exactly_equal(sketch_a: _datasketches.tuple_sketch, sketch_b: _datasketches.tuple_sketch, seed: int = 9001) bool
+

Returns True if sketch_a and sketch_b are equivalent, otherwise False

+
+ +
+
+similarity_test(actual: _datasketches.tuple_sketch, expected: _datasketches.tuple_sketch, threshold: float, seed: int = 9001) bool
+

Tests similarity of an actual sketch against an expected sketch. Computes the lower bound of the Jaccard index J_{LB} of the actual and expected sketches. If J_{LB} >= threshold, then the sketches are considered to be similar with a confidence of 97.7% and returns True, otherwise False.

+
+ +
+
+dissimilarity_test(actual: _datasketches.tuple_sketch, expected: _datasketches.tuple_sketch, threshold: float, seed: int = 9001) bool
+

Tests dissimilarity of an actual sketch against an expected sketch. Computes the upper bound of the Jaccard index J_{UB} of the actual and expected sketches. If J_{UB} <= threshold, then the sketches are considered to be dissimilar with a confidence of 97.7% and returns True, otherwise False.

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.0/helper/kernel.html b/docs/5.1.0/helper/kernel.html new file mode 100644 index 00000000..a2a61177 --- /dev/null +++ b/docs/5.1.0/helper/kernel.html @@ -0,0 +1,184 @@ + + + + + + + Kernel Function — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Kernel Function

+

A kernel function is a specific type of +mathematical funciton that is particularly useful in certain machine learning and pattern recognition +contexts. The density_sketch performs approximate +kernel density estimation which, unsurprisingly, +relies on the use of such a kernel function.

+

The library provides an abstract base class KernelFunction and an example implementation of a +Gaussian (also known as a Radial Basis Function) kernel. Custom classes must override the base class +and provide a floating point value as a score indicating the similarity of two input vectors.

+
+
+class KernelFunction(*args, **kwargs)
+

A generic base class from which user-defined kernels must inherit.

+
+
+__call__(self, a: object, b: object) float
+

A method to evaluate a kernel with given inputs a and b.

+
+
Parameters:
+
    +
  • a (numpy array) – An input vector

  • +
  • b (numpy array) – An input vector

  • +
+
+
Returns:
+

A vector similarity score

+
+
Return type:
+

float

+
+
+
+ +
+ +
+
+class GaussianKernel(bandwidth: float = 1.0)
+

Bases: KernelFunction

+

Implements a basic Gaussian kernel

+
+
Parameters:
+

bandwidth (float) – The kernel bandwidth, default 1.0

+
+
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.0/helper/ks_test.html b/docs/5.1.0/helper/ks_test.html new file mode 100644 index 00000000..721be0a5 --- /dev/null +++ b/docs/5.1.0/helper/ks_test.html @@ -0,0 +1,210 @@ + + + + + + + Kolmogorov-Smirnov Test — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Kolmogorov-Smirnov Test

+

A Kolmogorov-Smirnov Test <https://en.wikipedia.org/wiki/Kolmogorov%E2%80%93Smirnov_test>`_ is +a test of equality of two distributions to determine if they are likely to have come from the same +underlying distribution. +The DataSketches library provides a modified form of the test that takes into account the error +in each underlying sketch in the analysis.

+

Currently, the test assumes both input sketches are of the same family and data type.

+
+
+ks_test(sk_1: _datasketches.kll_ints_sketch, sk_2: _datasketches.kll_ints_sketch, p: float) bool
+
+ks_test(sk_1: _datasketches.kll_floats_sketch, sk_2: _datasketches.kll_floats_sketch, p: float) bool
+
+ks_test(sk_1: _datasketches.kll_doubles_sketch, sk_2: _datasketches.kll_doubles_sketch, p: float) bool
+
+ks_test(sk_1: _datasketches.kll_items_sketch, sk_2: _datasketches.kll_items_sketch, p: float) bool
+
+ks_test(sk_1: _datasketches.quantiles_ints_sketch, sk_2: _datasketches.quantiles_ints_sketch, p: float) bool
+
+ks_test(sk_1: _datasketches.quantiles_floats_sketch, sk_2: _datasketches.quantiles_floats_sketch, p: float) bool
+
+ks_test(sk_1: _datasketches.quantiles_doubles_sketch, sk_2: _datasketches.quantiles_doubles_sketch, p: float) bool
+
+ks_test(sk_1: _datasketches.quantiles_items_sketch, sk_2: _datasketches.quantiles_items_sketch, p: float) bool
+

Overloaded function.

+
    +
  1. ks_test(sk_1: _datasketches.kll_ints_sketch, sk_2: _datasketches.kll_ints_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for kll_ints_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
    +
  1. ks_test(sk_1: _datasketches.kll_floats_sketch, sk_2: _datasketches.kll_floats_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for kll_floats_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
    +
  1. ks_test(sk_1: _datasketches.kll_doubles_sketch, sk_2: _datasketches.kll_doubles_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for kll_doubles_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
    +
  1. ks_test(sk_1: _datasketches.kll_items_sketch, sk_2: _datasketches.kll_items_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for kll_items_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
    +
  1. ks_test(sk_1: _datasketches.quantiles_ints_sketch, sk_2: _datasketches.quantiles_ints_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for quantiles_ints_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
    +
  1. ks_test(sk_1: _datasketches.quantiles_floats_sketch, sk_2: _datasketches.quantiles_floats_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for quantiles_floats_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +:Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
    +
  1. ks_test(sk_1: _datasketches.quantiles_doubles_sketch, sk_2: _datasketches.quantiles_doubles_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for quantiles_doubles_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
    +
  1. ks_test(sk_1: _datasketches.quantiles_items_sketch, sk_2: _datasketches.quantiles_items_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for quantiles_items_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.0/helper/serde.html b/docs/5.1.0/helper/serde.html new file mode 100644 index 00000000..a4ed73d0 --- /dev/null +++ b/docs/5.1.0/helper/serde.html @@ -0,0 +1,253 @@ + + + + + + + Serialize/Deserialize (SerDe) — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Serialize/Deserialize (SerDe)

+

A SerDe is a class used to serialize items sketches to a bytes object in binary. +Several example SerDes are provided as references.

+

The use of binary-compatible SerDes in different languages is critical for cross-language compatibility.

+

Each implementation must extend the PyObjectSerDe class and override all three of its methods.

+
+
+class PyObjectSerDe(*args, **kwargs)
+

An abstract base class for serde objects. All custom serdes must extend this class.

+
+
+get_size(self, item: object) int
+

Returns the size in bytes of an item

+
+
Parameters:
+

item (object) – The specified object

+
+
Returns:
+

The size of the item in bytes

+
+
Return type:
+

int

+
+
+
+ +
+
+to_bytes(self, item: object) bytes
+

Retuns a bytes object with a serialized version of an item

+
+
Parameters:
+

item (object) – The specified object

+
+
Returns:
+

A bytes object with the serialized object

+
+
Return type:
+

bytes

+
+
+
+ +
+
+from_bytes(self, data: bytes, offset: int) tuple
+

Reads a bytes object starting from the given offest and returns a tuple of the reconstructed object and the number of additional bytes read

+
+
Parameters:
+
    +
  • data (bytes) – A bytes object from which to deserialize

  • +
  • offset (int) – The offset, in bytes, at which to start reading

  • +
+
+
Returns:
+

A tuple with the reconstructed object and the number of bytes read

+
+
Return type:
+

tuple(object, int)

+
+
+
+ +
+ +

The provided SerDes are:

+
+
+class PyStringsSerDe(*args, **kwargs)
+

Bases: PyObjectSerDe

+

Implements a simple string-encoding scheme where a string is +written as <num_bytes> <string_contents>, with no null termination. +This format allows pre-allocating each string, at the cost of +additional storage. Using this format, the serialized string consumes +4 + len(item) bytes.

+
+ +
+
+class PyIntsSerDe(*args, **kwargs)
+

Bases: PyObjectSerDe

+

Implements an integer encoding scheme where each integer is written +as a 32-bit (4 byte) little-endian value.

+
+ +
+
+class PyLongsSerDe(*args, **kwargs)
+

Bases: PyObjectSerDe

+

Implements an integer encoding scheme where each integer is written +as a 64-bit (8 byte) little-endian value.

+
+ +
+
+class PyFloatsSerDe(*args, **kwargs)
+

Bases: PyObjectSerDe

+

Implements a floating point encoding scheme where each value is written +as a 32-bit floating point value.

+
+ +
+
+class PyDoublesSerDe(*args, **kwargs)
+

Implements a floating point encoding scheme where each value is written +as a 64-bit floating point value.

+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.0/helper/tuple_policy.html b/docs/5.1.0/helper/tuple_policy.html new file mode 100644 index 00000000..7aec98fb --- /dev/null +++ b/docs/5.1.0/helper/tuple_policy.html @@ -0,0 +1,230 @@ + + + + + + + Tuple Policy — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Tuple Policy

+

A Tuple Policy is needed when using a tuple_sketch in order to specify how the +summary values should be created, updated, combined, or intersected. A summary can consist of +any python object.

+

Each implementation must extend the abstract base class TuplePolicy.

+
+
+class TuplePolicy(*args, **kwargs)
+

An abstract base class for Tuple Policy objects. All custom policies must extend this class.

+
+
+create_summary(self) object
+

Creates a new Summary object

+
+
Returns:
+

a Summary object

+
+
Return type:
+

object

+
+
+
+ +
+
+update_summary(self, summary: object, update: object) object
+

Applies the relevant policy to update the provided summary with the data in update.

+
+
Parameters:
+
    +
  • summary (object) – An existing Summary

  • +
  • update (object) – An update to apply to the Summary

  • +
+
+
Returns:
+

The updated Summary

+
+
Return type:
+

object

+
+
+
+ +
+
+__call__(self, summary: object, update: object) object
+

Similar to update_summary but allows a different implementation for set operations (union and intersection)

+
+
Parameters:
+
    +
  • summary (object) – An existing Summary

  • +
  • update (object) – An update to apply to the Summary

  • +
+
+
Returns:
+

The updated Summary

+
+
Return type:
+

object

+
+
+
+ +
+ +
+
+class AccumulatorPolicy
+

Bases: TuplePolicy

+

Implements an accumulatory summary policy, where new values +are added to the existing value.

+
+ +
+
+class MinIntPolicy
+

Bases: TuplePolicy

+

Implements a MIN rule, where the smallest integer value is always kept.

+
+ +
+
+class MaxIntPolicy
+

Bases: TuplePolicy

+

Implements a MAX rule, where the largest integer value is always kept.

+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.0/index.html b/docs/5.1.0/index.html new file mode 100644 index 00000000..e2ba4b9d --- /dev/null +++ b/docs/5.1.0/index.html @@ -0,0 +1,215 @@ + + + + + + + Apache DataSketches — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Apache DataSketches

+

DataSketches are highly-efficient algorithms to analyze big data quickly.

+
+

Counting Distincts

+ +
+
+

Quantile Estimation

+ +
+
+

Frequency Sketches

+

This problem may also be known as heavy hitters or TopK

+ +
+
+

Vector Sketches

+ +
+
+

Random Sampling

+ +
+
+

Helper Classes

+ +
+

Note

+

This project is under active development.

+
+
+
+
+

Indices and tables

+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.0/objects.inv b/docs/5.1.0/objects.inv new file mode 100644 index 00000000..3eb72db6 Binary files /dev/null and b/docs/5.1.0/objects.inv differ diff --git a/docs/5.1.0/quantiles/index.html b/docs/5.1.0/quantiles/index.html new file mode 100644 index 00000000..184ed4dc --- /dev/null +++ b/docs/5.1.0/quantiles/index.html @@ -0,0 +1,154 @@ + + + + + + + Quantiles Sketches — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Quantiles Sketches

+

Quantile estimation is useful for understanding the distribution of data values in a stream. The sketches currently +in the library are designed to answer queries about the rank of an item in the stream of items. That is, when +applying a global ordering on all the items, what is the portion of items seen so far that are less than (alternatively, +less-than-or-equal-to) the given item. Using straightforward logic, they can also estimate the item at a given rank +in the stream.

+

These sketches may be used to compute approximate histograms, Probability Mass Functions (PMFs), or +Cumulative Distribution Functions (CDFs).

+

The library provides three types of quantiles sketches, each of which has generic items as well as versions +specific to a given numeric type (e.g. integer or floating point values). All three types provide error +bounds on rank estimation with proven probabilistic error distributions.

+
+
    +
  • KLL: Provides uniform rank estimation error over the entire range

  • +
  • REQ: Provides relative rank error estimates, which decreases approaching either the high or low end values.

  • +
  • Classic quantiles: Largely deprecated in favor of KLL, also provides uniform rank estimation error. Included largely for backwards compatibility with historic data.

  • +
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.0/quantiles/kll.html b/docs/5.1.0/quantiles/kll.html new file mode 100644 index 00000000..0dc2a14b --- /dev/null +++ b/docs/5.1.0/quantiles/kll.html @@ -0,0 +1,964 @@ + + + + + + + KLL Sketch — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

KLL Sketch

+

Implementation of a very compact quantiles sketch with lazy compaction scheme +and nearly optimal accuracy per retained item. +See Optimal Quantile Approximation in Streams.

+

This is a stochastic streaming sketch that enables near real-time analysis of the +approximate distribution of items from a very large stream in a single pass, requiring only +that the items are comparable. +The analysis is obtained using get_quantile() function or the +inverse functions get_rank(), get_pmf() (Probability Mass Function), and get_cdf() +(Cumulative Distribution Function).

+

As of May 2020, this implementation produces serialized sketches which are binary-compatible +with the equivalent Java implementation only when template parameter T = float +(32-bit single precision values).

+

Given an input stream of N items, the natural rank of any specific +item is defined as its index (1 to N) in inclusive mode +or (0 to N-1) in exclusive mode +in the hypothetical sorted stream of all N input items.

+

The normalized rank (rank) of any specific item is defined as its +natural rank divided by N. +Thus, the normalized rank is between zero and one. +In the documentation for this sketch natural rank is never used so any +reference to just rank should be interpreted to mean normalized rank.

+

This sketch is configured with a parameter k, which affects the size of the sketch +and its estimation error.

+

The estimation error is commonly called epsilon (or eps) and is a fraction +between zero and one. Larger values of k result in smaller values of epsilon. +Epsilon is always with respect to the rank and cannot be applied to the +corresponding items.

+

The relationship between the normalized rank and the corresponding items can be viewed +as a two-dimensional monotonic plot with the normalized rank on one axis and the +corresponding items on the other axis. If the y-axis is specified as the item-axis and +the x-axis as the normalized rank, then y = get_quantile(x) is a monotonically +increasing function.

+

The function get_quantile(rank) translates ranks into +corresponding quantiles. The functions get_rank(item), +get_cdf(…) (Cumulative Distribution Function), and get_pmf(…) +(Probability Mass Function) perform the opposite operation and translate items into ranks.

+

The get_pmf(…) function has about 13 to 47% worse rank error (depending +on k) than the other queries because the mass of each “bin” of the PMF has +“double-sided” error from the upper and lower edges of the bin as a result of a subtraction, +as the errors from the two edges can sometimes add.

+

The default k of 200 yields a “single-sided” epsilon of about 1.33% and a +“double-sided” (PMF) epsilon of about 1.65%.

+

A get_quantile(rank) query has the following guarantees: +- Let q = get_quantile(r) where r is the rank between zero and one. +- The quantile q will be an item from the input stream. +- Let true_rank be the true rank of q derived from the hypothetical sorted +stream of all N items. +- Let eps = get_normalized_rank_error(false). +- Then r - eps ≤ true_rank ≤ r + eps with a confidence of 99%. Note that the +error is on the rank, not the quantile.

+

A get_rank(item) query has the following guarantees: +- Let r = get_rank(i) where i is an item between the min and max items of +the input stream. +- Let true_rank be the true rank of i derived from the hypothetical sorted +stream of all N items. +- Let eps = get_normalized_rank_error(false). +- Then r - eps ≤ true_rank ≤ r + eps with a confidence of 99%.

+

A get_pmf() query has the following guarantees: +- Let {r1, r2, …, r(m+1)} = get_pmf(s1, s2, …, sm) where s1, s2 are +split points (items from the input domain) between the min and max items of +the input stream. +- Let mass_i = estimated mass between s_i and s_i+1. +- Let true_mass be the true mass between the items of s_i, +s_i+1 derived from the hypothetical sorted stream of all N items. +- Let eps = get_normalized_rank_error(true). +- then mass - eps ≤ true_mass ≤ mass + eps with a confidence of 99%. +- r(m+1) includes the mass of all points larger than s_m.

+

A get_cdf(…) query has the following guarantees; +- Let {r1, r2, …, r(m+1)} = get_cdf(s1, s2, …, sm) where s1, s2, … are +split points (items from the input domain) between the min and max items of +the input stream. +- Let mass_i = r_(i+1) - r_i. +- Let true_mass be the true mass between the true ranks of s_i, +s_i+1 derived from the hypothetical sorted stream of all N items. +- Let eps = get_normalized_rank_error(true). +- then mass - eps ≤ true_mass ≤ mass + eps with a confidence of 99%. +- 1 - r(m+1) includes the mass of all points larger than s_m.

+

From the above, it might seem like we could make some estimates to bound the +item returned from a call to get_quantile(). The sketch, however, does not +let us derive error bounds or confidences around items. Because errors are independent, we +can approximately bracket a value as shown below, but there are no error estimates available. +Additionally, the interval may be quite large for certain distributions. +- Let q = get_quantile(r), the estimated quantile of rank r. +- Let eps = get_normalized_rank_error(false). +- Let q_lo = estimated quantile of rank (r - eps). +- Let q_hi = estimated quantile of rank (r + eps). +- Then q_lo ≤ q ≤ q_hi, with 99% confidence.

+
+

Note

+

For the kll_items_sketch, objects must be comparable with __lt__.

+
+
+

Note

+

Serializing and deserializing a kll_items_sketch requires the use of a PyObjectSerDe.

+
+
+
+class kll_ints_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.kll_ints_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 200) None
+

Creates a KLL sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 200.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given normalized rank in a hypothetical sorted version of the input stream so far. +For kll_floats_sketch: if the sketch is empty this returns nan. For kll_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: int) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=int32]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class kll_floats_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.kll_floats_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 200) None
+

Creates a KLL sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 200.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given normalized rank in a hypothetical sorted version of the input stream so far. +For kll_floats_sketch: if the sketch is empty this returns nan. For kll_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: float) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=float32]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class kll_doubles_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.kll_doubles_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 200) None
+

Creates a KLL sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 200.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given normalized rank in a hypothetical sorted version of the input stream so far. +For kll_floats_sketch: if the sketch is empty this returns nan. For kll_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: float) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=float64]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class kll_items_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe) _datasketches.kll_items_sketch
+

Deserializes the sketch from a bytes object using the provided serde.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 200) None
+

Creates a KLL sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 200.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given normalized rank in a hypothetical sorted version of the input stream so far. +For kll_floats_sketch: if the sketch is empty this returns nan. For kll_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object using the provided serde.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Updates the sketch with the given value

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.0/quantiles/quantiles_depr.html b/docs/5.1.0/quantiles/quantiles_depr.html new file mode 100644 index 00000000..e63e9176 --- /dev/null +++ b/docs/5.1.0/quantiles/quantiles_depr.html @@ -0,0 +1,903 @@ + + + + + + + Quantiles Sketch (Deprecated) — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Quantiles Sketch (Deprecated)

+

This is a deprecated quantiles sketch that is included for cross-language compatibility. +Most new projects will favor the KLL sketch over this one, or the REQ sketch for higher accuracy +at the very edge of a distribution.

+

This is a stochastic streaming sketch that enables near-real time analysis of the +approximate distribution from a very large stream in a single pass. +The analysis is obtained using get_rank() and get_quantile() functions, +the Probability Mass Function from get_pmf()` and the Cumulative Distribution Function from get_cdf.

+

Consider a large stream of one million values such as packet sizes coming into a network node. +The natural rank of any specific size value is its index in the hypothetical sorted +array of values. +The normalized rank is the natural rank divided by the stream size, +in this case one million. +The value corresponding to the normalized rank of 0.5 represents the 50th percentile or median +value of the distribution, or get_quantile(0.5). +Similarly, the 95th percentile is obtained from get_quantile(0.95).

+

From the min and max values, for example, 1 and 1000 bytes, +you can obtain the PMF from get_pmf(100, 500, 900) that will result in an array of +4 fractional values such as {.4, .3, .2, .1}, which means that +40% of the values were < 100, +30% of the values were ≥ 100 and < 500, +20% of the values were ≥ 500 and < 900, and +10% of the values were ≥ 900. +A frequency histogram can be obtained by multiplying these fractions by get_n(), +which is the total count of values received. +The get_cdf()` works similarly, but produces the cumulative distribution instead.

+

As of November 2021, this implementation produces serialized sketches which are binary-compatible +with the equivalent Java implementation only when template parameter T = double +(64-bit double precision values).

+

The accuracy of this sketch is a function of the configured value k, which also affects +the overall size of the sketch. Accuracy of this quantile sketch is always with respect to +the normalized rank. A k of 128 produces a normalized, rank error of about 1.7%. +For example, the median item returned from get_quantile(0.5) will be between the actual items +from the hypothetically sorted array of input items at normalized ranks of 0.483 and 0.517, with +a confidence of about 99%.

+
+

Note

+

For the quantiles_items_sketch, objects must be comparable with __lt__.

+
+
+

Note

+

Serializing and deserializing a quantiles_items_sketch requires the use of a PyObjectSerDe.

+
+
+
+class quantiles_ints_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.quantiles_ints_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 128) None
+

Creates a classic quantiles sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 128.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given rank in a hypothetical sorted version of the input stream so far. +For quantiles_floats_sketch: if the sketch is empty this returns nan. For quantiles_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: int) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=int32]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class quantiles_floats_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.quantiles_floats_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 128) None
+

Creates a classic quantiles sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 128.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given rank in a hypothetical sorted version of the input stream so far. +For quantiles_floats_sketch: if the sketch is empty this returns nan. For quantiles_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: float) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=float32]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class quantiles_doubles_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.quantiles_doubles_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 128) None
+

Creates a classic quantiles sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 128.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given rank in a hypothetical sorted version of the input stream so far. +For quantiles_floats_sketch: if the sketch is empty this returns nan. For quantiles_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: float) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=float64]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class quantiles_items_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe) _datasketches.quantiles_items_sketch
+

Deserializes the sketch from a bytes object using the provided serde.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 128) None
+

Creates a classic quantiles sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 128.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given rank in a hypothetical sorted version of the input stream so far. +For quantiles_floats_sketch: if the sketch is empty this returns nan. For quantiles_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object using the provided serde.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Updates the sketch with the given value

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.0/quantiles/req.html b/docs/5.1.0/quantiles/req.html new file mode 100644 index 00000000..7ece205d --- /dev/null +++ b/docs/5.1.0/quantiles/req.html @@ -0,0 +1,754 @@ + + + + + + + Relative Error Quantiles (REQ) Sketch — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Relative Error Quantiles (REQ) Sketch

+

This is an implementation based on the paper “Relative Error Streaming Quantiles” by Graham Cormode, Zohar Karnin, Edo Liberty, Justin Thaler, Pavel Veselý, and loosely derived from a Python prototype written by Pavel Veselý.

+

This implementation differs from the algorithm described in the paper in the following:

+

The algorithm requires no upper bound on the stream length. +Instead, each relative-compactor counts the number of compaction operations performed so far (via variable state). +Initially, the relative-compactor starts with INIT_NUMBER_OF_SECTIONS. +Each time the number of compactions (variable state) exceeds 2^{numSections - 1}, we double numSections. +Note that after merging the sketch with another one variable state may not correspond to the number of compactions performed at a particular level, however, +since the state variable never exceeds the number of compactions, the guarantees of the sketch remain valid.

+

The size of each section (variable k and section_size in the code and parameter k in the paper) is +initialized with a number set by the user via variable k. +When the number of sections doubles, we decrease section_size by a factor of sqrt(2). +This is applied at each level separately. +Thus, when we double the number of sections, the nominal compactor size increases by a factor of approx. sqrt(2) (+/- rounding).

+

The merge operation here does not perform “special compactions”, which are used in the paper to allow for a tight mathematical analysis of the sketch. +This implementation provides a number of capabilities not discussed in the paper or provided in the Python prototype.

+

The Python prototype only implemented high accuracy for low ranks. This implementation provides the user with the ability to +choose either high rank accuracy or low rank accuracy at the time of sketch construction. +The Python prototype only implemented a comparison criterion of INCLUSIVE. +This implementation allows the user to use both the INCLUSIVE criterion and the EXCLUSIVE criterion. +This implementation provides extensive debug visibility into the operation of the sketch with two levels of detail output. +This is not only useful for debugging, but is a powerful tool to help users understand how the sketch works.

+
+

Note

+

For the req_items_sketch, objects must be comparable with __lt__.

+
+
+

Note

+

Serializing and deserializing a req_items_sketch requires the use of a PyObjectSerDe.

+
+
+
+class req_ints_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.req_ints_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_RSE(k: int, rank: float, is_hra: bool, n: int) float
+

Returns an a priori estimate of relative standard error (RSE, expressed as a number in [0,1]). Derived from Lemma 12 in http://arxiv.org/abs/2004.01668v2, but the constant factors have been modified based on empirical measurements, for a given value of parameter k. +Normalized rank must be a value between 0.0 and 1.0 (inclusive). If is_hra is True, uses high rank accuracy mode, else low rank accuracy. N is an estimate of the total number of points provided to the sketch.

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 12, is_hra: bool = True) None
+

Creates an REQ sketch instance with the given value of k.

+
+
Parameters:
+
    +
  • k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 12.

  • +
  • is_hra (bool, optional) – Specifies whether the skech has High Rank Accuracy (True) or Low Rank Accuracy. Default True.

  • +
+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, req_floats_sketch returns nan; req_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, req_floats_sketch returns nan; req_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given normalized rank in a hypothetical sorted version of the input stream so far. +For req_floats_sketch: if the sketch is empty this returns nan. For req_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+get_rank_lower_bound
+

Returns an approximate lower bound on the given normalized rank. +Normalized rank must be a value between 0.0 and 1.0 (inclusive); the number of standard deviations must be 1, 2, or 3.

+
+ +
+
+get_rank_upper_bound
+

Returns an approximate upper bound on the given normalized rank. +Normalized rank must be a value between 0.0 and 1.0 (inclusive); the number of standard deviations must be 1, 2, or 3.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+is_hra
+

Returns True if the sketch is in High Rank Accuracy mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: int) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=int32]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class req_floats_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.req_floats_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_RSE(k: int, rank: float, is_hra: bool, n: int) float
+

Returns an a priori estimate of relative standard error (RSE, expressed as a number in [0,1]). Derived from Lemma 12 in http://arxiv.org/abs/2004.01668v2, but the constant factors have been modified based on empirical measurements, for a given value of parameter k. +Normalized rank must be a value between 0.0 and 1.0 (inclusive). If is_hra is True, uses high rank accuracy mode, else low rank accuracy. N is an estimate of the total number of points provided to the sketch.

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 12, is_hra: bool = True) None
+

Creates an REQ sketch instance with the given value of k.

+
+
Parameters:
+
    +
  • k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 12.

  • +
  • is_hra (bool, optional) – Specifies whether the skech has High Rank Accuracy (True) or Low Rank Accuracy. Default True.

  • +
+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, req_floats_sketch returns nan; req_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, req_floats_sketch returns nan; req_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given normalized rank in a hypothetical sorted version of the input stream so far. +For req_floats_sketch: if the sketch is empty this returns nan. For req_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+get_rank_lower_bound
+

Returns an approximate lower bound on the given normalized rank. +Normalized rank must be a value between 0.0 and 1.0 (inclusive); the number of standard deviations must be 1, 2, or 3.

+
+ +
+
+get_rank_upper_bound
+

Returns an approximate upper bound on the given normalized rank. +Normalized rank must be a value between 0.0 and 1.0 (inclusive); the number of standard deviations must be 1, 2, or 3.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+is_hra
+

Returns True if the sketch is in High Rank Accuracy mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: float) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=float32]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class req_items_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe) _datasketches.req_items_sketch
+

Deserializes the sketch from a bytes object using the provided serde.

+
+ +
+
+get_RSE(k: int, rank: float, is_hra: bool, n: int) float
+

Returns an a priori estimate of relative standard error (RSE, expressed as a number in [0,1]). Derived from Lemma 12 in http://arxiv.org/abs/2004.01668v2, but the constant factors have been modified based on empirical measurements, for a given value of parameter k. +Normalized rank must be a value between 0.0 and 1.0 (inclusive). If is_hra is True, uses high rank accuracy mode, else low rank accuracy. N is an estimate of the total number of points provided to the sketch.

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 12, is_hra: bool = True) None
+

Creates an REQ sketch instance with the given value of k.

+
+
Parameters:
+
    +
  • k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 12.

  • +
  • is_hra (bool, optional) – Specifies whether the skech has High Rank Accuracy (True) or Low Rank Accuracy. Default True.

  • +
+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, req_floats_sketch returns nan; req_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, req_floats_sketch returns nan; req_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given normalized rank in a hypothetical sorted version of the input stream so far. +For req_floats_sketch: if the sketch is empty this returns nan. For req_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+get_rank_lower_bound
+

Returns an approximate lower bound on the given normalized rank. +Normalized rank must be a value between 0.0 and 1.0 (inclusive); the number of standard deviations must be 1, 2, or 3.

+
+ +
+
+get_rank_upper_bound
+

Returns an approximate upper bound on the given normalized rank. +Normalized rank must be a value between 0.0 and 1.0 (inclusive); the number of standard deviations must be 1, 2, or 3.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+is_hra
+

Returns True if the sketch is in High Rank Accuracy mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object using the provided serde.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Updates the sketch with the given value

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.0/sampling/ebpps.html b/docs/5.1.0/sampling/ebpps.html new file mode 100644 index 00000000..07b97185 --- /dev/null +++ b/docs/5.1.0/sampling/ebpps.html @@ -0,0 +1,238 @@ + + + + + + + Exact and Bounded, Probabilitiy Proportional to Size (EBPPS) Sampling — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Exact and Bounded, Probabilitiy Proportional to Size (EBPPS) Sampling

+

An EBPPS sketch produces a randome sample of data from a stream of items, ensuring that the probability +of including an item is always exactly equal to the item’s size. The size of an item is defined as its +weight relative to the total weight of all items seen so far by the sketch. In contrast to VarOpt sampling, +this sketch may return fewer than k items in order to keep the probability of including an item strictly +proportional to its size.

+

This sketch is based on: B. Hentschel, P. J. Haas, Y. Tian +“Exact PPS Sampling with Bounded Sample Size”, +Information Processing Letters, 2023.

+

EBPPS sampling is related to reservoir sampling, but handles unequal item weights. +Feeding the sketch items with a uniform weight value will produce a sample equivalent to reservoir sampling.

+
+

Note

+

Serializing and deserializing this sketch requires the use of a PyObjectSerDe.

+
+
+
+class ebpps_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe) _datasketches.ebpps_sketch
+

Reads a bytes object and returns the corresponding ebpps_sketch

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int) None
+

Creates a new EBPPS sketch instance

+
+
Parameters:
+

k (int) – Maximum number of samples in the sketch

+
+
+
+ +
+
+property c
+

The expected number of samples returned upon a call to get_result() or the creation of an iterator. The number is a floating point value, where the fractional portion represents the probability of including a “partial item” from the sample. The value C should be no larger than the sketch’s configured value of k, although numerical precision limitations mean it may exceed k by double precision floating point error margins in certain cases.

+
+ +
+
+get_serialized_size_bytes
+

Computes the size in bytes needed to serialize the current sketch

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+property k
+

The sketch’s maximum configured sample size

+
+ +
+
+merge
+

Merges the sketch with the given sketch

+
+ +
+
+property n
+

The total stream length

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object

+
+ +
+
+to_string
+

Produces a string summary of the sketch and optionally prints the items

+
+ +
+
+update
+

Updates the sketch with the given value and weight

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.0/sampling/index.html b/docs/5.1.0/sampling/index.html new file mode 100644 index 00000000..7cc2cb53 --- /dev/null +++ b/docs/5.1.0/sampling/index.html @@ -0,0 +1,147 @@ + + + + + + + Random Sampling Sketches — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Random Sampling Sketches

+

These sketches are used to randomly sample items. The length of the input +stream does not need to be known in advance.

+

Both VarOpt (Variance Optimal) and EBPPS (Exact and Bounded, +Probability Proportional to Size) sketches will include sample items based on +each item’s weight relative to the weight of the entire stream but +they differ in details:

+
+
    +
  • ebpps_sketch ensures that the probability of including an item is always exactly proportional to the item’s weight.

  • +
  • var_opt_sketch optimizes for applying a predicate to the resulting sample such that the variance of the subset sum after applying the predicate is minimized, even if the inclusion probability differs somewhat from being proportional to the item’s weight.

  • +
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.0/sampling/varopt.html b/docs/5.1.0/sampling/varopt.html new file mode 100644 index 00000000..1b3889f6 --- /dev/null +++ b/docs/5.1.0/sampling/varopt.html @@ -0,0 +1,300 @@ + + + + + + + Variance Optimal Sampling (VarOpt) — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Variance Optimal Sampling (VarOpt)

+

A VarOpt sketch samples data from a stream of items. The sketch is desinged for optimal (minimum) +variance when querying the sketch to estimate subset sums of items matching a provided predicate. +The sketch will produce a sample of size k (or smaller if fewer items have been presented), with +the probability of including an item roughly corresponding it the item’s weight relative to the total +weight of all items presented to the sketch.

+

VarOpt sampling is related to reservoir sampling, with improved error bounds for subset sum estimation. +Feeding the sketch items with a uniform weight value will produce a sample equivalent to reservoir sampling.

+
+

Note

+

Serializing and deserializing this sketch requires the use of a PyObjectSerDe.

+
+
+
+class var_opt_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe) _datasketches.var_opt_sketch
+

Reads a bytes object and returns the corresponding var opt sketch

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int) None
+

Creates a new Var Opt sketch instance

+
+
Parameters:
+

k (int) – Maximum number of samples in the sketch

+
+
+
+ +
+
+estimate_subset_sum
+

Applies a provided predicate to the sketch and returns the estimated total weight matching the predicate, as well as upper and lower bounds on the estimate and the total weight processed by the sketch

+
+ +
+
+get_serialized_size_bytes
+

Computes the size in bytes needed to serialize the current sketch

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+property k
+

Returns the sketch’s maximum configured sample size

+
+ +
+
+property n
+

Returns the total stream length

+
+ +
+
+property num_samples
+

Returns the number of samples currently in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object

+
+ +
+
+to_string
+

Produces a string summary of the sketch and optionally prints the items

+
+ +
+
+update
+

Updates the sketch with the given value and weight

+
+ +
+ +
+
+class var_opt_union(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe) _datasketches.var_opt_union
+

Constructs a var opt union from the given bytes using the provided serde

+
+ +

Non-static Methods:

+
+
+__init__(self, max_k: int) None
+
+ +
+
+get_result
+

Returns a sketch corresponding to the union result

+
+ +
+
+get_serialized_size_bytes
+

Computes the size in bytes needed to serialize the current union

+
+ +
+
+reset
+

Resets the union to the empty state

+
+ +
+
+serialize
+

Serializes the union into a bytes object with the provided serde

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Updates the union with the given sketch

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.0/search.html b/docs/5.1.0/search.html new file mode 100644 index 00000000..21031339 --- /dev/null +++ b/docs/5.1.0/search.html @@ -0,0 +1,136 @@ + + + + + + Search — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ + + + +
+ +
+ +
+
+ +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/docs/5.1.0/searchindex.js b/docs/5.1.0/searchindex.js new file mode 100644 index 00000000..f00a5800 --- /dev/null +++ b/docs/5.1.0/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"alltitles": {"Apache DataSketches": [[14, null]], "Compressed Probabilistic Counting (CPC)": [[0, null]], "CountMin Sketch": [[5, null]], "Counting Distincts": [[14, "counting-distincts"]], "Density Sketch": [[22, null]], "Distinct Counting": [[2, null]], "Exact and Bounded, Probabilitiy Proportional to Size (EBPPS) Sampling": [[19, null]], "Frequency Sketches": [[7, null], [14, "frequency-sketches"]], "Frequent Items": [[6, null]], "Helper Classes": [[8, null], [14, "helper-classes"]], "HyperLogLog (HLL)": [[1, null]], "Indices and tables": [[14, "indices-and-tables"]], "Jaccard Similarity": [[9, null]], "KLL Sketch": [[16, null]], "Kernel Function": [[10, null]], "Kolmogorov-Smirnov Test": [[11, null]], "Quantile Estimation": [[14, "quantile-estimation"]], "Quantiles Sketch (Deprecated)": [[17, null]], "Quantiles Sketches": [[15, null]], "Random Sampling": [[14, "random-sampling"]], "Random Sampling Sketches": [[20, null]], "Relative Error Quantiles (REQ) Sketch": [[18, null]], "Serialize/Deserialize (SerDe)": [[12, null]], "Theta Sketch": [[3, null]], "Tuple Policy": [[13, null]], "Tuple Sketch": [[4, null]], "Variance Optimal Sampling (VarOpt)": [[21, null]], "Vector Sketches": [[14, "vector-sketches"], [23, null]]}, "docnames": ["distinct_counting/cpc", "distinct_counting/hyper_log_log", "distinct_counting/index", "distinct_counting/theta", "distinct_counting/tuple", "frequency/count_min_sketch", "frequency/frequent_items", "frequency/index", "helper/index", "helper/jaccard", "helper/kernel", "helper/ks_test", "helper/serde", "helper/tuple_policy", "index", "quantiles/index", "quantiles/kll", "quantiles/quantiles_depr", "quantiles/req", "sampling/ebpps", "sampling/index", "sampling/varopt", "vector/density_sketch", "vector/index"], "envversion": {"sphinx": 62, "sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2}, "filenames": ["distinct_counting/cpc.rst", "distinct_counting/hyper_log_log.rst", "distinct_counting/index.rst", "distinct_counting/theta.rst", "distinct_counting/tuple.rst", "frequency/count_min_sketch.rst", "frequency/frequent_items.rst", "frequency/index.rst", "helper/index.rst", "helper/jaccard.rst", "helper/kernel.rst", "helper/ks_test.rst", "helper/serde.rst", "helper/tuple_policy.rst", "index.rst", "quantiles/index.rst", "quantiles/kll.rst", "quantiles/quantiles_depr.rst", "quantiles/req.rst", "sampling/ebpps.rst", "sampling/index.rst", "sampling/varopt.rst", "vector/density_sketch.rst", "vector/index.rst"], "indexentries": {"__call__() (kernelfunction method)": [[10, "datasketches.KernelFunction.__call__", false]], "__call__() (tuplepolicy method)": [[13, "datasketches.TuplePolicy.__call__", false]], "__init__() (compact_theta_sketch method)": [[3, "datasketches.compact_theta_sketch.__init__", false]], "__init__() (compact_tuple_sketch method)": [[4, "datasketches.compact_tuple_sketch.__init__", false]], "__init__() (cpc_sketch method)": [[0, "datasketches.cpc_sketch.__init__", false]], "__init__() (cpc_union method)": [[0, "datasketches.cpc_union.__init__", false]], "__init__() (density_sketch method)": [[22, "datasketches.density_sketch.__init__", false]], "__init__() (ebpps_sketch method)": [[19, "datasketches.ebpps_sketch.__init__", false]], "__init__() (frequent_items_sketch method)": [[6, "datasketches.frequent_items_sketch.__init__", false]], "__init__() (frequent_strings_sketch method)": [[6, "datasketches.frequent_strings_sketch.__init__", false]], "__init__() (hll_sketch method)": [[1, "datasketches.hll_sketch.__init__", false]], "__init__() (hll_union method)": [[1, "datasketches.hll_union.__init__", false]], "__init__() (kll_doubles_sketch method)": [[16, "datasketches.kll_doubles_sketch.__init__", false]], "__init__() (kll_floats_sketch method)": [[16, "datasketches.kll_floats_sketch.__init__", false]], "__init__() (kll_ints_sketch method)": [[16, "datasketches.kll_ints_sketch.__init__", false]], "__init__() (kll_items_sketch method)": [[16, "datasketches.kll_items_sketch.__init__", false]], "__init__() (quantiles_doubles_sketch method)": [[17, "datasketches.quantiles_doubles_sketch.__init__", false]], "__init__() (quantiles_floats_sketch method)": [[17, "datasketches.quantiles_floats_sketch.__init__", false]], "__init__() (quantiles_ints_sketch method)": [[17, "datasketches.quantiles_ints_sketch.__init__", false]], "__init__() (quantiles_items_sketch method)": [[17, "datasketches.quantiles_items_sketch.__init__", false]], "__init__() (req_floats_sketch method)": [[18, "datasketches.req_floats_sketch.__init__", false]], "__init__() (req_ints_sketch method)": [[18, "datasketches.req_ints_sketch.__init__", false]], "__init__() (req_items_sketch method)": [[18, "datasketches.req_items_sketch.__init__", false]], "__init__() (theta_a_not_b method)": [[3, "datasketches.theta_a_not_b.__init__", false]], "__init__() (theta_intersection method)": [[3, "datasketches.theta_intersection.__init__", false]], "__init__() (theta_union method)": [[3, "datasketches.theta_union.__init__", false]], "__init__() (tuple_a_not_b method)": [[4, "datasketches.tuple_a_not_b.__init__", false]], "__init__() (tuple_intersection method)": [[4, "datasketches.tuple_intersection.__init__", false]], "__init__() (tuple_union method)": [[4, "datasketches.tuple_union.__init__", false]], "__init__() (update_theta_sketch method)": [[3, "datasketches.update_theta_sketch.__init__", false]], "__init__() (update_tuple_sketch method)": [[4, "datasketches.update_tuple_sketch.__init__", false]], "__init__() (var_opt_sketch method)": [[21, "datasketches.var_opt_sketch.__init__", false]], "__init__() (var_opt_union method)": [[21, "datasketches.var_opt_union.__init__", false]], "accumulatorpolicy (class in datasketches)": [[13, "datasketches.AccumulatorPolicy", false]], "c (ebpps_sketch property)": [[19, "datasketches.ebpps_sketch.c", false]], "compact (update_theta_sketch attribute)": [[3, "datasketches.update_theta_sketch.compact", false]], "compact (update_tuple_sketch attribute)": [[4, "datasketches.update_tuple_sketch.compact", false]], "compact_theta_sketch (class in datasketches)": [[3, "datasketches.compact_theta_sketch", false]], "compact_tuple_sketch (class in datasketches)": [[4, "datasketches.compact_tuple_sketch", false]], "compute (theta_a_not_b attribute)": [[3, "datasketches.theta_a_not_b.compute", false]], "compute (tuple_a_not_b attribute)": [[4, "datasketches.tuple_a_not_b.compute", false]], "count_min_sketch (class in _datasketches)": [[5, "datasketches.count_min_sketch", false]], "cpc_sketch (class in _datasketches)": [[0, "datasketches.cpc_sketch", false]], "cpc_union (class in _datasketches)": [[0, "datasketches.cpc_union", false]], "create_summary() (tuplepolicy method)": [[13, "datasketches.TuplePolicy.create_summary", false]], "default_seed (tuple_sketch attribute)": [[4, "datasketches.tuple_sketch.DEFAULT_SEED", false]], "density_sketch (class in datasketches)": [[22, "datasketches.density_sketch", false]], "deserialize() (compact_theta_sketch method)": [[3, "datasketches.compact_theta_sketch.deserialize", false]], "deserialize() (compact_tuple_sketch method)": [[4, "datasketches.compact_tuple_sketch.deserialize", false]], "deserialize() (count_min_sketch method)": [[5, "datasketches.count_min_sketch.deserialize", false]], "deserialize() (cpc_sketch method)": [[0, "datasketches.cpc_sketch.deserialize", false]], "deserialize() (density_sketch method)": [[22, "datasketches.density_sketch.deserialize", false]], "deserialize() (ebpps_sketch method)": [[19, "datasketches.ebpps_sketch.deserialize", false]], "deserialize() (frequent_items_sketch method)": [[6, "datasketches.frequent_items_sketch.deserialize", false]], "deserialize() (frequent_strings_sketch method)": [[6, "datasketches.frequent_strings_sketch.deserialize", false]], "deserialize() (hll_sketch method)": [[1, "datasketches.hll_sketch.deserialize", false]], "deserialize() (kll_doubles_sketch method)": [[16, "datasketches.kll_doubles_sketch.deserialize", false]], "deserialize() (kll_floats_sketch method)": [[16, "datasketches.kll_floats_sketch.deserialize", false]], "deserialize() (kll_ints_sketch method)": [[16, "datasketches.kll_ints_sketch.deserialize", false]], "deserialize() (kll_items_sketch method)": [[16, "datasketches.kll_items_sketch.deserialize", false]], "deserialize() (quantiles_doubles_sketch method)": [[17, "datasketches.quantiles_doubles_sketch.deserialize", false]], "deserialize() (quantiles_floats_sketch method)": [[17, "datasketches.quantiles_floats_sketch.deserialize", false]], "deserialize() (quantiles_ints_sketch method)": [[17, "datasketches.quantiles_ints_sketch.deserialize", false]], "deserialize() (quantiles_items_sketch method)": [[17, "datasketches.quantiles_items_sketch.deserialize", false]], "deserialize() (req_floats_sketch method)": [[18, "datasketches.req_floats_sketch.deserialize", false]], "deserialize() (req_ints_sketch method)": [[18, "datasketches.req_ints_sketch.deserialize", false]], "deserialize() (req_items_sketch method)": [[18, "datasketches.req_items_sketch.deserialize", false]], "deserialize() (var_opt_sketch method)": [[21, "datasketches.var_opt_sketch.deserialize", false]], "deserialize() (var_opt_union method)": [[21, "datasketches.var_opt_union.deserialize", false]], "dim (density_sketch property)": [[22, "datasketches.density_sketch.dim", false]], "dissimilarity_test() (theta_jaccard_similarity method)": [[9, "datasketches.theta_jaccard_similarity.dissimilarity_test", false]], "dissimilarity_test() (tuple_jaccard_similarity method)": [[9, "datasketches.tuple_jaccard_similarity.dissimilarity_test", false]], "ebpps_sketch (class in datasketches)": [[19, "datasketches.ebpps_sketch", false]], "epsilon (frequent_items_sketch property)": [[6, "datasketches.frequent_items_sketch.epsilon", false]], "epsilon (frequent_strings_sketch property)": [[6, "datasketches.frequent_strings_sketch.epsilon", false]], "estimate_subset_sum (var_opt_sketch attribute)": [[21, "datasketches.var_opt_sketch.estimate_subset_sum", false]], "exactly_equal() (theta_jaccard_similarity method)": [[9, "datasketches.theta_jaccard_similarity.exactly_equal", false]], "exactly_equal() (tuple_jaccard_similarity method)": [[9, "datasketches.tuple_jaccard_similarity.exactly_equal", false]], "filter (compact_tuple_sketch attribute)": [[4, "datasketches.compact_tuple_sketch.filter", false]], "filter (update_tuple_sketch attribute)": [[4, "datasketches.update_tuple_sketch.filter", false]], "frequent_items_error_type (class in datasketches)": [[6, "datasketches.frequent_items_error_type", false]], "frequent_items_sketch (class in datasketches)": [[6, "datasketches.frequent_items_sketch", false]], "frequent_strings_sketch (class in datasketches)": [[6, "datasketches.frequent_strings_sketch", false]], "from_bytes() (pyobjectserde method)": [[12, "datasketches.PyObjectSerDe.from_bytes", false]], "gaussiankernel (class in datasketches)": [[10, "datasketches.GaussianKernel", false]], "get_apriori_error() (frequent_items_sketch method)": [[6, "datasketches.frequent_items_sketch.get_apriori_error", false]], "get_apriori_error() (frequent_strings_sketch method)": [[6, "datasketches.frequent_strings_sketch.get_apriori_error", false]], "get_cdf (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.get_cdf", false]], "get_cdf (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.get_cdf", false]], "get_cdf (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.get_cdf", false]], "get_cdf (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.get_cdf", false]], "get_cdf (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.get_cdf", false]], "get_cdf (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.get_cdf", false]], "get_cdf (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.get_cdf", false]], "get_cdf (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.get_cdf", false]], "get_cdf (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.get_cdf", false]], "get_cdf (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.get_cdf", false]], "get_cdf (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.get_cdf", false]], "get_compact_serialization_bytes (hll_sketch attribute)": [[1, "datasketches.hll_sketch.get_compact_serialization_bytes", false]], "get_epsilon_for_lg_size() (frequent_items_sketch method)": [[6, "datasketches.frequent_items_sketch.get_epsilon_for_lg_size", false]], "get_epsilon_for_lg_size() (frequent_strings_sketch method)": [[6, "datasketches.frequent_strings_sketch.get_epsilon_for_lg_size", false]], "get_estimate (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.get_estimate", false]], "get_estimate (cpc_sketch attribute)": [[0, "datasketches.cpc_sketch.get_estimate", false]], "get_estimate (density_sketch attribute)": [[22, "datasketches.density_sketch.get_estimate", false]], "get_estimate (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.get_estimate", false]], "get_estimate (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.get_estimate", false]], "get_estimate (hll_sketch attribute)": [[1, "datasketches.hll_sketch.get_estimate", false]], "get_estimate (hll_union attribute)": [[1, "datasketches.hll_union.get_estimate", false]], "get_estimate (theta_sketch attribute)": [[3, "datasketches.theta_sketch.get_estimate", false]], "get_estimate (tuple_sketch attribute)": [[4, "datasketches.tuple_sketch.get_estimate", false]], "get_frequent_items (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.get_frequent_items", false]], "get_frequent_items (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.get_frequent_items", false]], "get_lower_bound (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.get_lower_bound", false]], "get_lower_bound (cpc_sketch attribute)": [[0, "datasketches.cpc_sketch.get_lower_bound", false]], "get_lower_bound (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.get_lower_bound", false]], "get_lower_bound (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.get_lower_bound", false]], "get_lower_bound (hll_sketch attribute)": [[1, "datasketches.hll_sketch.get_lower_bound", false]], "get_lower_bound (hll_union attribute)": [[1, "datasketches.hll_union.get_lower_bound", false]], "get_lower_bound (theta_sketch attribute)": [[3, "datasketches.theta_sketch.get_lower_bound", false]], "get_lower_bound (tuple_sketch attribute)": [[4, "datasketches.tuple_sketch.get_lower_bound", false]], "get_max_updatable_serialization_bytes() (hll_sketch method)": [[1, "datasketches.hll_sketch.get_max_updatable_serialization_bytes", false]], "get_max_value (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.get_max_value", false]], "get_max_value (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.get_max_value", false]], "get_max_value (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.get_max_value", false]], "get_max_value (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.get_max_value", false]], "get_max_value (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.get_max_value", false]], "get_max_value (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.get_max_value", false]], "get_max_value (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.get_max_value", false]], "get_max_value (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.get_max_value", false]], "get_max_value (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.get_max_value", false]], "get_max_value (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.get_max_value", false]], "get_max_value (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.get_max_value", false]], "get_min_value (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.get_min_value", false]], "get_min_value (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.get_min_value", false]], "get_min_value (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.get_min_value", false]], "get_min_value (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.get_min_value", false]], "get_min_value (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.get_min_value", false]], "get_min_value (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.get_min_value", false]], "get_min_value (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.get_min_value", false]], "get_min_value (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.get_min_value", false]], "get_min_value (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.get_min_value", false]], "get_min_value (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.get_min_value", false]], "get_min_value (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.get_min_value", false]], "get_normalized_rank_error() (kll_doubles_sketch method)": [[16, "datasketches.kll_doubles_sketch.get_normalized_rank_error", false]], "get_normalized_rank_error() (kll_floats_sketch method)": [[16, "datasketches.kll_floats_sketch.get_normalized_rank_error", false]], "get_normalized_rank_error() (kll_ints_sketch method)": [[16, "datasketches.kll_ints_sketch.get_normalized_rank_error", false]], "get_normalized_rank_error() (kll_items_sketch method)": [[16, "datasketches.kll_items_sketch.get_normalized_rank_error", false]], "get_normalized_rank_error() (quantiles_doubles_sketch method)": [[17, "datasketches.quantiles_doubles_sketch.get_normalized_rank_error", false]], "get_normalized_rank_error() (quantiles_floats_sketch method)": [[17, "datasketches.quantiles_floats_sketch.get_normalized_rank_error", false]], "get_normalized_rank_error() (quantiles_ints_sketch method)": [[17, "datasketches.quantiles_ints_sketch.get_normalized_rank_error", false]], "get_normalized_rank_error() (quantiles_items_sketch method)": [[17, "datasketches.quantiles_items_sketch.get_normalized_rank_error", false]], "get_pmf (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.get_pmf", false]], "get_pmf (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.get_pmf", false]], "get_pmf (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.get_pmf", false]], "get_pmf (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.get_pmf", false]], "get_pmf (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.get_pmf", false]], "get_pmf (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.get_pmf", false]], "get_pmf (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.get_pmf", false]], "get_pmf (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.get_pmf", false]], "get_pmf (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.get_pmf", false]], "get_pmf (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.get_pmf", false]], "get_pmf (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.get_pmf", false]], "get_quantile (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.get_quantile", false]], "get_quantile (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.get_quantile", false]], "get_quantile (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.get_quantile", false]], "get_quantile (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.get_quantile", false]], "get_quantile (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.get_quantile", false]], "get_quantile (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.get_quantile", false]], "get_quantile (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.get_quantile", false]], "get_quantile (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.get_quantile", false]], "get_quantile (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.get_quantile", false]], "get_quantile (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.get_quantile", false]], "get_quantile (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.get_quantile", false]], "get_quantiles (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.get_quantiles", false]], "get_quantiles (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.get_quantiles", false]], "get_quantiles (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.get_quantiles", false]], "get_quantiles (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.get_quantiles", false]], "get_quantiles (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.get_quantiles", false]], "get_quantiles (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.get_quantiles", false]], "get_quantiles (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.get_quantiles", false]], "get_quantiles (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.get_quantiles", false]], "get_quantiles (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.get_quantiles", false]], "get_quantiles (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.get_quantiles", false]], "get_quantiles (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.get_quantiles", false]], "get_rank (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.get_rank", false]], "get_rank (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.get_rank", false]], "get_rank (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.get_rank", false]], "get_rank (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.get_rank", false]], "get_rank (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.get_rank", false]], "get_rank (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.get_rank", false]], "get_rank (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.get_rank", false]], "get_rank (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.get_rank", false]], "get_rank (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.get_rank", false]], "get_rank (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.get_rank", false]], "get_rank (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.get_rank", false]], "get_rank_lower_bound (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.get_rank_lower_bound", false]], "get_rank_lower_bound (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.get_rank_lower_bound", false]], "get_rank_lower_bound (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.get_rank_lower_bound", false]], "get_rank_upper_bound (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.get_rank_upper_bound", false]], "get_rank_upper_bound (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.get_rank_upper_bound", false]], "get_rank_upper_bound (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.get_rank_upper_bound", false]], "get_rel_err() (hll_sketch method)": [[1, "datasketches.hll_sketch.get_rel_err", false]], "get_rel_err() (hll_union method)": [[1, "datasketches.hll_union.get_rel_err", false]], "get_relative_error (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.get_relative_error", false]], "get_result (cpc_union attribute)": [[0, "datasketches.cpc_union.get_result", false]], "get_result (hll_union attribute)": [[1, "datasketches.hll_union.get_result", false]], "get_result (theta_intersection attribute)": [[3, "datasketches.theta_intersection.get_result", false]], "get_result (theta_union attribute)": [[3, "datasketches.theta_union.get_result", false]], "get_result (tuple_intersection attribute)": [[4, "datasketches.tuple_intersection.get_result", false]], "get_result (tuple_union attribute)": [[4, "datasketches.tuple_union.get_result", false]], "get_result (var_opt_union attribute)": [[21, "datasketches.var_opt_union.get_result", false]], "get_rse() (req_floats_sketch method)": [[18, "datasketches.req_floats_sketch.get_RSE", false]], "get_rse() (req_ints_sketch method)": [[18, "datasketches.req_ints_sketch.get_RSE", false]], "get_rse() (req_items_sketch method)": [[18, "datasketches.req_items_sketch.get_RSE", false]], "get_seed_hash (theta_sketch attribute)": [[3, "datasketches.theta_sketch.get_seed_hash", false]], "get_seed_hash (tuple_sketch attribute)": [[4, "datasketches.tuple_sketch.get_seed_hash", false]], "get_serialized_size_bytes (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.get_serialized_size_bytes", false]], "get_serialized_size_bytes (ebpps_sketch attribute)": [[19, "datasketches.ebpps_sketch.get_serialized_size_bytes", false]], "get_serialized_size_bytes (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.get_serialized_size_bytes", false]], "get_serialized_size_bytes (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.get_serialized_size_bytes", false]], "get_serialized_size_bytes (var_opt_sketch attribute)": [[21, "datasketches.var_opt_sketch.get_serialized_size_bytes", false]], "get_serialized_size_bytes (var_opt_union attribute)": [[21, "datasketches.var_opt_union.get_serialized_size_bytes", false]], "get_size() (pyobjectserde method)": [[12, "datasketches.PyObjectSerDe.get_size", false]], "get_updatable_serialization_bytes (hll_sketch attribute)": [[1, "datasketches.hll_sketch.get_updatable_serialization_bytes", false]], "get_upper_bound (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.get_upper_bound", false]], "get_upper_bound (cpc_sketch attribute)": [[0, "datasketches.cpc_sketch.get_upper_bound", false]], "get_upper_bound (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.get_upper_bound", false]], "get_upper_bound (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.get_upper_bound", false]], "get_upper_bound (hll_sketch attribute)": [[1, "datasketches.hll_sketch.get_upper_bound", false]], "get_upper_bound (hll_union attribute)": [[1, "datasketches.hll_union.get_upper_bound", false]], "get_upper_bound (theta_sketch attribute)": [[3, "datasketches.theta_sketch.get_upper_bound", false]], "get_upper_bound (tuple_sketch attribute)": [[4, "datasketches.tuple_sketch.get_upper_bound", false]], "has_result (theta_intersection attribute)": [[3, "datasketches.theta_intersection.has_result", false]], "has_result (tuple_intersection attribute)": [[4, "datasketches.tuple_intersection.has_result", false]], "hll_4 (tgt_hll_type attribute)": [[1, "datasketches.tgt_hll_type.HLL_4", false]], "hll_6 (tgt_hll_type attribute)": [[1, "datasketches.tgt_hll_type.HLL_6", false]], "hll_8 (tgt_hll_type attribute)": [[1, "datasketches.tgt_hll_type.HLL_8", false]], "hll_sketch (class in _datasketches)": [[1, "datasketches.hll_sketch", false]], "hll_union (class in _datasketches)": [[1, "datasketches.hll_union", false]], "is_compact (hll_sketch attribute)": [[1, "datasketches.hll_sketch.is_compact", false]], "is_empty (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.is_empty", false]], "is_empty (cpc_sketch attribute)": [[0, "datasketches.cpc_sketch.is_empty", false]], "is_empty (density_sketch attribute)": [[22, "datasketches.density_sketch.is_empty", false]], "is_empty (ebpps_sketch attribute)": [[19, "datasketches.ebpps_sketch.is_empty", false]], "is_empty (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.is_empty", false]], "is_empty (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.is_empty", false]], "is_empty (hll_sketch attribute)": [[1, "datasketches.hll_sketch.is_empty", false]], "is_empty (hll_union attribute)": [[1, "datasketches.hll_union.is_empty", false]], "is_empty (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.is_empty", false]], "is_empty (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.is_empty", false]], "is_empty (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.is_empty", false]], "is_empty (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.is_empty", false]], "is_empty (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.is_empty", false]], "is_empty (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.is_empty", false]], "is_empty (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.is_empty", false]], "is_empty (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.is_empty", false]], "is_empty (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.is_empty", false]], "is_empty (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.is_empty", false]], "is_empty (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.is_empty", false]], "is_empty (theta_sketch attribute)": [[3, "datasketches.theta_sketch.is_empty", false]], "is_empty (tuple_sketch attribute)": [[4, "datasketches.tuple_sketch.is_empty", false]], "is_empty (var_opt_sketch attribute)": [[21, "datasketches.var_opt_sketch.is_empty", false]], "is_estimation_mode (density_sketch attribute)": [[22, "datasketches.density_sketch.is_estimation_mode", false]], "is_estimation_mode (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.is_estimation_mode", false]], "is_estimation_mode (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.is_estimation_mode", false]], "is_estimation_mode (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.is_estimation_mode", false]], "is_estimation_mode (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.is_estimation_mode", false]], "is_estimation_mode (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.is_estimation_mode", false]], "is_estimation_mode (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.is_estimation_mode", false]], "is_estimation_mode (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.is_estimation_mode", false]], "is_estimation_mode (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.is_estimation_mode", false]], "is_estimation_mode (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.is_estimation_mode", false]], "is_estimation_mode (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.is_estimation_mode", false]], "is_estimation_mode (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.is_estimation_mode", false]], "is_estimation_mode (theta_sketch attribute)": [[3, "datasketches.theta_sketch.is_estimation_mode", false]], "is_estimation_mode (tuple_sketch attribute)": [[4, "datasketches.tuple_sketch.is_estimation_mode", false]], "is_hra (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.is_hra", false]], "is_hra (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.is_hra", false]], "is_hra (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.is_hra", false]], "is_ordered (theta_sketch attribute)": [[3, "datasketches.theta_sketch.is_ordered", false]], "is_ordered (tuple_sketch attribute)": [[4, "datasketches.tuple_sketch.is_ordered", false]], "jaccard() (theta_jaccard_similarity method)": [[9, "datasketches.theta_jaccard_similarity.jaccard", false]], "jaccard() (tuple_jaccard_similarity method)": [[9, "datasketches.tuple_jaccard_similarity.jaccard", false]], "k (density_sketch property)": [[22, "datasketches.density_sketch.k", false]], "k (ebpps_sketch property)": [[19, "datasketches.ebpps_sketch.k", false]], "k (kll_doubles_sketch property)": [[16, "datasketches.kll_doubles_sketch.k", false]], "k (kll_floats_sketch property)": [[16, "datasketches.kll_floats_sketch.k", false]], "k (kll_ints_sketch property)": [[16, "datasketches.kll_ints_sketch.k", false]], "k (kll_items_sketch property)": [[16, "datasketches.kll_items_sketch.k", false]], "k (quantiles_doubles_sketch property)": [[17, "datasketches.quantiles_doubles_sketch.k", false]], "k (quantiles_floats_sketch property)": [[17, "datasketches.quantiles_floats_sketch.k", false]], "k (quantiles_ints_sketch property)": [[17, "datasketches.quantiles_ints_sketch.k", false]], "k (quantiles_items_sketch property)": [[17, "datasketches.quantiles_items_sketch.k", false]], "k (req_floats_sketch property)": [[18, "datasketches.req_floats_sketch.k", false]], "k (req_ints_sketch property)": [[18, "datasketches.req_ints_sketch.k", false]], "k (req_items_sketch property)": [[18, "datasketches.req_items_sketch.k", false]], "k (var_opt_sketch property)": [[21, "datasketches.var_opt_sketch.k", false]], "kernelfunction (class in datasketches)": [[10, "datasketches.KernelFunction", false]], "kll_doubles_sketch (class in datasketches)": [[16, "datasketches.kll_doubles_sketch", false]], "kll_floats_sketch (class in datasketches)": [[16, "datasketches.kll_floats_sketch", false]], "kll_ints_sketch (class in datasketches)": [[16, "datasketches.kll_ints_sketch", false]], "kll_items_sketch (class in datasketches)": [[16, "datasketches.kll_items_sketch", false]], "ks_test() (in module datasketches)": [[11, "datasketches.ks_test", false]], "lg_config_k (hll_sketch property)": [[1, "datasketches.hll_sketch.lg_config_k", false]], "lg_config_k (hll_union property)": [[1, "datasketches.hll_union.lg_config_k", false]], "lg_k (cpc_sketch property)": [[0, "datasketches.cpc_sketch.lg_k", false]], "maxintpolicy (class in datasketches)": [[13, "datasketches.MaxIntPolicy", false]], "merge (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.merge", false]], "merge (density_sketch attribute)": [[22, "datasketches.density_sketch.merge", false]], "merge (ebpps_sketch attribute)": [[19, "datasketches.ebpps_sketch.merge", false]], "merge (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.merge", false]], "merge (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.merge", false]], "merge (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.merge", false]], "merge (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.merge", false]], "merge (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.merge", false]], "merge (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.merge", false]], "merge (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.merge", false]], "merge (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.merge", false]], "merge (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.merge", false]], "merge (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.merge", false]], "merge (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.merge", false]], "merge (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.merge", false]], "merge (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.merge", false]], "minintpolicy (class in datasketches)": [[13, "datasketches.MinIntPolicy", false]], "n (density_sketch property)": [[22, "datasketches.density_sketch.n", false]], "n (ebpps_sketch property)": [[19, "datasketches.ebpps_sketch.n", false]], "n (kll_doubles_sketch property)": [[16, "datasketches.kll_doubles_sketch.n", false]], "n (kll_floats_sketch property)": [[16, "datasketches.kll_floats_sketch.n", false]], "n (kll_ints_sketch property)": [[16, "datasketches.kll_ints_sketch.n", false]], "n (kll_items_sketch property)": [[16, "datasketches.kll_items_sketch.n", false]], "n (quantiles_doubles_sketch property)": [[17, "datasketches.quantiles_doubles_sketch.n", false]], "n (quantiles_floats_sketch property)": [[17, "datasketches.quantiles_floats_sketch.n", false]], "n (quantiles_ints_sketch property)": [[17, "datasketches.quantiles_ints_sketch.n", false]], "n (quantiles_items_sketch property)": [[17, "datasketches.quantiles_items_sketch.n", false]], "n (req_floats_sketch property)": [[18, "datasketches.req_floats_sketch.n", false]], "n (req_ints_sketch property)": [[18, "datasketches.req_ints_sketch.n", false]], "n (req_items_sketch property)": [[18, "datasketches.req_items_sketch.n", false]], "n (var_opt_sketch property)": [[21, "datasketches.var_opt_sketch.n", false]], "no_false_negatives (frequent_items_error_type attribute)": [[6, "datasketches.frequent_items_error_type.NO_FALSE_NEGATIVES", false]], "no_false_positives (frequent_items_error_type attribute)": [[6, "datasketches.frequent_items_error_type.NO_FALSE_POSITIVES", false]], "normalized_rank_error (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.normalized_rank_error", false]], "normalized_rank_error (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.normalized_rank_error", false]], "normalized_rank_error (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.normalized_rank_error", false]], "normalized_rank_error (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.normalized_rank_error", false]], "normalized_rank_error (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.normalized_rank_error", false]], "normalized_rank_error (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.normalized_rank_error", false]], "normalized_rank_error (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.normalized_rank_error", false]], "normalized_rank_error (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.normalized_rank_error", false]], "num_active_items (frequent_items_sketch property)": [[6, "datasketches.frequent_items_sketch.num_active_items", false]], "num_active_items (frequent_strings_sketch property)": [[6, "datasketches.frequent_strings_sketch.num_active_items", false]], "num_buckets (count_min_sketch property)": [[5, "datasketches.count_min_sketch.num_buckets", false]], "num_hashes (count_min_sketch property)": [[5, "datasketches.count_min_sketch.num_hashes", false]], "num_retained (density_sketch property)": [[22, "datasketches.density_sketch.num_retained", false]], "num_retained (kll_doubles_sketch property)": [[16, "datasketches.kll_doubles_sketch.num_retained", false]], "num_retained (kll_floats_sketch property)": [[16, "datasketches.kll_floats_sketch.num_retained", false]], "num_retained (kll_ints_sketch property)": [[16, "datasketches.kll_ints_sketch.num_retained", false]], "num_retained (kll_items_sketch property)": [[16, "datasketches.kll_items_sketch.num_retained", false]], "num_retained (quantiles_doubles_sketch property)": [[17, "datasketches.quantiles_doubles_sketch.num_retained", false]], "num_retained (quantiles_floats_sketch property)": [[17, "datasketches.quantiles_floats_sketch.num_retained", false]], "num_retained (quantiles_ints_sketch property)": [[17, "datasketches.quantiles_ints_sketch.num_retained", false]], "num_retained (quantiles_items_sketch property)": [[17, "datasketches.quantiles_items_sketch.num_retained", false]], "num_retained (req_floats_sketch property)": [[18, "datasketches.req_floats_sketch.num_retained", false]], "num_retained (req_ints_sketch property)": [[18, "datasketches.req_ints_sketch.num_retained", false]], "num_retained (req_items_sketch property)": [[18, "datasketches.req_items_sketch.num_retained", false]], "num_retained (theta_sketch property)": [[3, "datasketches.theta_sketch.num_retained", false]], "num_retained (tuple_sketch property)": [[4, "datasketches.tuple_sketch.num_retained", false]], "num_samples (var_opt_sketch property)": [[21, "datasketches.var_opt_sketch.num_samples", false]], "pydoublesserde (class in datasketches)": [[12, "datasketches.PyDoublesSerDe", false]], "pyfloatsserde (class in datasketches)": [[12, "datasketches.PyFloatsSerDe", false]], "pyintsserde (class in datasketches)": [[12, "datasketches.PyIntsSerDe", false]], "pylongsserde (class in datasketches)": [[12, "datasketches.PyLongsSerDe", false]], "pyobjectserde (class in datasketches)": [[12, "datasketches.PyObjectSerDe", false]], "pystringsserde (class in datasketches)": [[12, "datasketches.PyStringsSerDe", false]], "quantiles_doubles_sketch (class in datasketches)": [[17, "datasketches.quantiles_doubles_sketch", false]], "quantiles_floats_sketch (class in datasketches)": [[17, "datasketches.quantiles_floats_sketch", false]], "quantiles_ints_sketch (class in datasketches)": [[17, "datasketches.quantiles_ints_sketch", false]], "quantiles_items_sketch (class in datasketches)": [[17, "datasketches.quantiles_items_sketch", false]], "req_floats_sketch (class in datasketches)": [[18, "datasketches.req_floats_sketch", false]], "req_ints_sketch (class in datasketches)": [[18, "datasketches.req_ints_sketch", false]], "req_items_sketch (class in datasketches)": [[18, "datasketches.req_items_sketch", false]], "reset (hll_sketch attribute)": [[1, "datasketches.hll_sketch.reset", false]], "reset (hll_union attribute)": [[1, "datasketches.hll_union.reset", false]], "reset (tuple_union attribute)": [[4, "datasketches.tuple_union.reset", false]], "reset (update_theta_sketch attribute)": [[3, "datasketches.update_theta_sketch.reset", false]], "reset (update_tuple_sketch attribute)": [[4, "datasketches.update_tuple_sketch.reset", false]], "reset (var_opt_union attribute)": [[21, "datasketches.var_opt_union.reset", false]], "seed (count_min_sketch property)": [[5, "datasketches.count_min_sketch.seed", false]], "serialize (compact_theta_sketch attribute)": [[3, "datasketches.compact_theta_sketch.serialize", false]], "serialize (compact_tuple_sketch attribute)": [[4, "datasketches.compact_tuple_sketch.serialize", false]], "serialize (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.serialize", false]], "serialize (cpc_sketch attribute)": [[0, "datasketches.cpc_sketch.serialize", false]], "serialize (density_sketch attribute)": [[22, "datasketches.density_sketch.serialize", false]], "serialize (ebpps_sketch attribute)": [[19, "datasketches.ebpps_sketch.serialize", false]], "serialize (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.serialize", false]], "serialize (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.serialize", false]], "serialize (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.serialize", false]], "serialize (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.serialize", false]], "serialize (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.serialize", false]], "serialize (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.serialize", false]], "serialize (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.serialize", false]], "serialize (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.serialize", false]], "serialize (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.serialize", false]], "serialize (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.serialize", false]], "serialize (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.serialize", false]], "serialize (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.serialize", false]], "serialize (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.serialize", false]], "serialize (var_opt_sketch attribute)": [[21, "datasketches.var_opt_sketch.serialize", false]], "serialize (var_opt_union attribute)": [[21, "datasketches.var_opt_union.serialize", false]], "serialize_compact (hll_sketch attribute)": [[1, "datasketches.hll_sketch.serialize_compact", false]], "serialize_updatable (hll_sketch attribute)": [[1, "datasketches.hll_sketch.serialize_updatable", false]], "similarity_test() (theta_jaccard_similarity method)": [[9, "datasketches.theta_jaccard_similarity.similarity_test", false]], "similarity_test() (tuple_jaccard_similarity method)": [[9, "datasketches.tuple_jaccard_similarity.similarity_test", false]], "suggest_num_buckets() (count_min_sketch method)": [[5, "datasketches.count_min_sketch.suggest_num_buckets", false]], "suggest_num_hashes() (count_min_sketch method)": [[5, "datasketches.count_min_sketch.suggest_num_hashes", false]], "tgt_hll_type (class in _datasketches)": [[1, "datasketches.tgt_hll_type", false]], "tgt_type (hll_sketch property)": [[1, "datasketches.hll_sketch.tgt_type", false]], "theta (theta_sketch property)": [[3, "datasketches.theta_sketch.theta", false]], "theta (tuple_sketch property)": [[4, "datasketches.tuple_sketch.theta", false]], "theta64 (theta_sketch property)": [[3, "datasketches.theta_sketch.theta64", false]], "theta64 (tuple_sketch property)": [[4, "datasketches.tuple_sketch.theta64", false]], "theta_a_not_b (class in datasketches)": [[3, "datasketches.theta_a_not_b", false]], "theta_intersection (class in datasketches)": [[3, "datasketches.theta_intersection", false]], "theta_jaccard_similarity (class in datasketches)": [[9, "datasketches.theta_jaccard_similarity", false]], "theta_sketch (class in datasketches)": [[3, "datasketches.theta_sketch", false]], "theta_union (class in datasketches)": [[3, "datasketches.theta_union", false]], "to_bytes() (pyobjectserde method)": [[12, "datasketches.PyObjectSerDe.to_bytes", false]], "to_string (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.to_string", false]], "to_string (cpc_sketch attribute)": [[0, "datasketches.cpc_sketch.to_string", false]], "to_string (density_sketch attribute)": [[22, "datasketches.density_sketch.to_string", false]], "to_string (ebpps_sketch attribute)": [[19, "datasketches.ebpps_sketch.to_string", false]], "to_string (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.to_string", false]], "to_string (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.to_string", false]], "to_string (hll_sketch attribute)": [[1, "datasketches.hll_sketch.to_string", false]], "to_string (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.to_string", false]], "to_string (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.to_string", false]], "to_string (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.to_string", false]], "to_string (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.to_string", false]], "to_string (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.to_string", false]], "to_string (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.to_string", false]], "to_string (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.to_string", false]], "to_string (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.to_string", false]], "to_string (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.to_string", false]], "to_string (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.to_string", false]], "to_string (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.to_string", false]], "to_string (theta_sketch attribute)": [[3, "datasketches.theta_sketch.to_string", false]], "to_string (tuple_sketch attribute)": [[4, "datasketches.tuple_sketch.to_string", false]], "to_string (var_opt_sketch attribute)": [[21, "datasketches.var_opt_sketch.to_string", false]], "to_string (var_opt_union attribute)": [[21, "datasketches.var_opt_union.to_string", false]], "total_weight (count_min_sketch property)": [[5, "datasketches.count_min_sketch.total_weight", false]], "total_weight (frequent_items_sketch property)": [[6, "datasketches.frequent_items_sketch.total_weight", false]], "total_weight (frequent_strings_sketch property)": [[6, "datasketches.frequent_strings_sketch.total_weight", false]], "trim (update_theta_sketch attribute)": [[3, "datasketches.update_theta_sketch.trim", false]], "trim (update_tuple_sketch attribute)": [[4, "datasketches.update_tuple_sketch.trim", false]], "tuple_a_not_b (class in datasketches)": [[4, "datasketches.tuple_a_not_b", false]], "tuple_intersection (class in datasketches)": [[4, "datasketches.tuple_intersection", false]], "tuple_jaccard_similarity (class in datasketches)": [[9, "datasketches.tuple_jaccard_similarity", false]], "tuple_sketch (class in datasketches)": [[4, "datasketches.tuple_sketch", false]], "tuple_union (class in datasketches)": [[4, "datasketches.tuple_union", false]], "tuplepolicy (class in datasketches)": [[13, "datasketches.TuplePolicy", false]], "update (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.update", false]], "update (cpc_sketch attribute)": [[0, "datasketches.cpc_sketch.update", false]], "update (cpc_union attribute)": [[0, "datasketches.cpc_union.update", false]], "update (density_sketch attribute)": [[22, "datasketches.density_sketch.update", false]], "update (ebpps_sketch attribute)": [[19, "datasketches.ebpps_sketch.update", false]], "update (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.update", false]], "update (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.update", false]], "update (hll_sketch attribute)": [[1, "datasketches.hll_sketch.update", false]], "update (hll_union attribute)": [[1, "datasketches.hll_union.update", false]], "update (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.update", false]], "update (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.update", false]], "update (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.update", false]], "update (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.update", false]], "update (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.update", false]], "update (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.update", false]], "update (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.update", false]], "update (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.update", false]], "update (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.update", false]], "update (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.update", false]], "update (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.update", false]], "update (theta_intersection attribute)": [[3, "datasketches.theta_intersection.update", false]], "update (theta_union attribute)": [[3, "datasketches.theta_union.update", false]], "update (tuple_intersection attribute)": [[4, "datasketches.tuple_intersection.update", false]], "update (tuple_union attribute)": [[4, "datasketches.tuple_union.update", false]], "update (update_theta_sketch attribute)": [[3, "datasketches.update_theta_sketch.update", false]], "update (update_tuple_sketch attribute)": [[4, "datasketches.update_tuple_sketch.update", false]], "update (var_opt_sketch attribute)": [[21, "datasketches.var_opt_sketch.update", false]], "update (var_opt_union attribute)": [[21, "datasketches.var_opt_union.update", false]], "update_summary() (tuplepolicy method)": [[13, "datasketches.TuplePolicy.update_summary", false]], "update_theta_sketch (class in datasketches)": [[3, "datasketches.update_theta_sketch", false]], "update_tuple_sketch (class in datasketches)": [[4, "datasketches.update_tuple_sketch", false]], "var_opt_sketch (class in datasketches)": [[21, "datasketches.var_opt_sketch", false]], "var_opt_union (class in datasketches)": [[21, "datasketches.var_opt_union", false]]}, "objects": {"_datasketches": [[5, 0, 1, "datasketches.count_min_sketch", "count_min_sketch"], [0, 0, 1, "datasketches.cpc_sketch", "cpc_sketch"], [0, 0, 1, "datasketches.cpc_union", "cpc_union"], [1, 0, 1, "datasketches.hll_sketch", "hll_sketch"], [1, 0, 1, "datasketches.hll_union", "hll_union"], [1, 0, 1, "datasketches.tgt_hll_type", "tgt_hll_type"]], "_datasketches.count_min_sketch": [[5, 1, 1, "datasketches.count_min_sketch.deserialize", "deserialize"], [5, 2, 1, "datasketches.count_min_sketch.get_estimate", "get_estimate"], [5, 2, 1, "datasketches.count_min_sketch.get_lower_bound", "get_lower_bound"], [5, 2, 1, "datasketches.count_min_sketch.get_relative_error", "get_relative_error"], [5, 2, 1, "datasketches.count_min_sketch.get_serialized_size_bytes", "get_serialized_size_bytes"], [5, 2, 1, "datasketches.count_min_sketch.get_upper_bound", "get_upper_bound"], [5, 2, 1, "datasketches.count_min_sketch.is_empty", "is_empty"], [5, 2, 1, "datasketches.count_min_sketch.merge", "merge"], [5, 3, 1, "datasketches.count_min_sketch.num_buckets", "num_buckets"], [5, 3, 1, "datasketches.count_min_sketch.num_hashes", "num_hashes"], [5, 3, 1, "datasketches.count_min_sketch.seed", "seed"], [5, 2, 1, "datasketches.count_min_sketch.serialize", "serialize"], [5, 1, 1, "datasketches.count_min_sketch.suggest_num_buckets", "suggest_num_buckets"], [5, 1, 1, "datasketches.count_min_sketch.suggest_num_hashes", "suggest_num_hashes"], [5, 2, 1, "datasketches.count_min_sketch.to_string", "to_string"], [5, 3, 1, "datasketches.count_min_sketch.total_weight", "total_weight"], [5, 2, 1, "datasketches.count_min_sketch.update", "update"]], "_datasketches.cpc_sketch": [[0, 1, 1, "datasketches.cpc_sketch.__init__", "__init__"], [0, 1, 1, "datasketches.cpc_sketch.deserialize", "deserialize"], [0, 2, 1, "datasketches.cpc_sketch.get_estimate", "get_estimate"], [0, 2, 1, "datasketches.cpc_sketch.get_lower_bound", "get_lower_bound"], [0, 2, 1, "datasketches.cpc_sketch.get_upper_bound", "get_upper_bound"], [0, 2, 1, "datasketches.cpc_sketch.is_empty", "is_empty"], [0, 3, 1, "datasketches.cpc_sketch.lg_k", "lg_k"], [0, 2, 1, "datasketches.cpc_sketch.serialize", "serialize"], [0, 2, 1, "datasketches.cpc_sketch.to_string", "to_string"], [0, 2, 1, "datasketches.cpc_sketch.update", "update"]], "_datasketches.cpc_union": [[0, 1, 1, "datasketches.cpc_union.__init__", "__init__"], [0, 2, 1, "datasketches.cpc_union.get_result", "get_result"], [0, 2, 1, "datasketches.cpc_union.update", "update"]], "_datasketches.hll_sketch": [[1, 1, 1, "datasketches.hll_sketch.__init__", "__init__"], [1, 1, 1, "datasketches.hll_sketch.deserialize", "deserialize"], [1, 2, 1, "datasketches.hll_sketch.get_compact_serialization_bytes", "get_compact_serialization_bytes"], [1, 2, 1, "datasketches.hll_sketch.get_estimate", "get_estimate"], [1, 2, 1, "datasketches.hll_sketch.get_lower_bound", "get_lower_bound"], [1, 1, 1, "datasketches.hll_sketch.get_max_updatable_serialization_bytes", "get_max_updatable_serialization_bytes"], [1, 1, 1, "datasketches.hll_sketch.get_rel_err", "get_rel_err"], [1, 2, 1, "datasketches.hll_sketch.get_updatable_serialization_bytes", "get_updatable_serialization_bytes"], [1, 2, 1, "datasketches.hll_sketch.get_upper_bound", "get_upper_bound"], [1, 2, 1, "datasketches.hll_sketch.is_compact", "is_compact"], [1, 2, 1, "datasketches.hll_sketch.is_empty", "is_empty"], [1, 3, 1, "datasketches.hll_sketch.lg_config_k", "lg_config_k"], [1, 2, 1, "datasketches.hll_sketch.reset", "reset"], [1, 2, 1, "datasketches.hll_sketch.serialize_compact", "serialize_compact"], [1, 2, 1, "datasketches.hll_sketch.serialize_updatable", "serialize_updatable"], [1, 3, 1, "datasketches.hll_sketch.tgt_type", "tgt_type"], [1, 2, 1, "datasketches.hll_sketch.to_string", "to_string"], [1, 2, 1, "datasketches.hll_sketch.update", "update"]], "_datasketches.hll_union": [[1, 1, 1, "datasketches.hll_union.__init__", "__init__"], [1, 2, 1, "datasketches.hll_union.get_estimate", "get_estimate"], [1, 2, 1, "datasketches.hll_union.get_lower_bound", "get_lower_bound"], [1, 1, 1, "datasketches.hll_union.get_rel_err", "get_rel_err"], [1, 2, 1, "datasketches.hll_union.get_result", "get_result"], [1, 2, 1, "datasketches.hll_union.get_upper_bound", "get_upper_bound"], [1, 2, 1, "datasketches.hll_union.is_empty", "is_empty"], [1, 3, 1, "datasketches.hll_union.lg_config_k", "lg_config_k"], [1, 2, 1, "datasketches.hll_union.reset", "reset"], [1, 2, 1, "datasketches.hll_union.update", "update"]], "_datasketches.tgt_hll_type": [[1, 2, 1, "datasketches.tgt_hll_type.HLL_4", "HLL_4"], [1, 2, 1, "datasketches.tgt_hll_type.HLL_6", "HLL_6"], [1, 2, 1, "datasketches.tgt_hll_type.HLL_8", "HLL_8"]], "datasketches": [[13, 0, 1, "", "AccumulatorPolicy"], [10, 0, 1, "", "GaussianKernel"], [10, 0, 1, "", "KernelFunction"], [13, 0, 1, "", "MaxIntPolicy"], [13, 0, 1, "", "MinIntPolicy"], [12, 0, 1, "", "PyDoublesSerDe"], [12, 0, 1, "", "PyFloatsSerDe"], [12, 0, 1, "", "PyIntsSerDe"], [12, 0, 1, "", "PyLongsSerDe"], [12, 0, 1, "", "PyObjectSerDe"], [12, 0, 1, "", "PyStringsSerDe"], [13, 0, 1, "", "TuplePolicy"], [3, 0, 1, "", "compact_theta_sketch"], [4, 0, 1, "", "compact_tuple_sketch"], [22, 0, 1, "", "density_sketch"], [19, 0, 1, "", "ebpps_sketch"], [6, 0, 1, "", "frequent_items_error_type"], [6, 0, 1, "", "frequent_items_sketch"], [6, 0, 1, "", "frequent_strings_sketch"], [16, 0, 1, "", "kll_doubles_sketch"], [16, 0, 1, "", "kll_floats_sketch"], [16, 0, 1, "", "kll_ints_sketch"], [16, 0, 1, "", "kll_items_sketch"], [11, 4, 1, "", "ks_test"], [17, 0, 1, "", "quantiles_doubles_sketch"], [17, 0, 1, "", "quantiles_floats_sketch"], [17, 0, 1, "", "quantiles_ints_sketch"], [17, 0, 1, "", "quantiles_items_sketch"], [18, 0, 1, "", "req_floats_sketch"], [18, 0, 1, "", "req_ints_sketch"], [18, 0, 1, "", "req_items_sketch"], [3, 0, 1, "", "theta_a_not_b"], [3, 0, 1, "", "theta_intersection"], [9, 0, 1, "", "theta_jaccard_similarity"], [3, 0, 1, "", "theta_sketch"], [3, 0, 1, "", "theta_union"], [4, 0, 1, "", "tuple_a_not_b"], [4, 0, 1, "", "tuple_intersection"], [9, 0, 1, "", "tuple_jaccard_similarity"], [4, 0, 1, "", "tuple_sketch"], [4, 0, 1, "", "tuple_union"], [3, 0, 1, "", "update_theta_sketch"], [4, 0, 1, "", "update_tuple_sketch"], [21, 0, 1, "", "var_opt_sketch"], [21, 0, 1, "", "var_opt_union"]], "datasketches.KernelFunction": [[10, 1, 1, "", "__call__"]], "datasketches.PyObjectSerDe": [[12, 1, 1, "", "from_bytes"], [12, 1, 1, "", "get_size"], [12, 1, 1, "", "to_bytes"]], "datasketches.TuplePolicy": [[13, 1, 1, "", "__call__"], [13, 1, 1, "", "create_summary"], [13, 1, 1, "", "update_summary"]], "datasketches.compact_theta_sketch": [[3, 1, 1, "", "__init__"], [3, 1, 1, "", "deserialize"], [3, 2, 1, "", "serialize"]], "datasketches.compact_tuple_sketch": [[4, 1, 1, "", "__init__"], [4, 1, 1, "", "deserialize"], [4, 2, 1, "", "filter"], [4, 2, 1, "", "serialize"]], "datasketches.density_sketch": [[22, 1, 1, "", "__init__"], [22, 1, 1, "", "deserialize"], [22, 3, 1, "", "dim"], [22, 2, 1, "", "get_estimate"], [22, 2, 1, "", "is_empty"], [22, 2, 1, "", "is_estimation_mode"], [22, 3, 1, "", "k"], [22, 2, 1, "", "merge"], [22, 3, 1, "", "n"], [22, 3, 1, "", "num_retained"], [22, 2, 1, "", "serialize"], [22, 2, 1, "", "to_string"], [22, 2, 1, "", "update"]], "datasketches.ebpps_sketch": [[19, 1, 1, "", "__init__"], [19, 3, 1, "", "c"], [19, 1, 1, "", "deserialize"], [19, 2, 1, "", "get_serialized_size_bytes"], [19, 2, 1, "", "is_empty"], [19, 3, 1, "", "k"], [19, 2, 1, "", "merge"], [19, 3, 1, "", "n"], [19, 2, 1, "", "serialize"], [19, 2, 1, "", "to_string"], [19, 2, 1, "", "update"]], "datasketches.frequent_items_error_type": [[6, 2, 1, "", "NO_FALSE_NEGATIVES"], [6, 2, 1, "", "NO_FALSE_POSITIVES"]], "datasketches.frequent_items_sketch": [[6, 1, 1, "", "__init__"], [6, 1, 1, "", "deserialize"], [6, 3, 1, "", "epsilon"], [6, 1, 1, "", "get_apriori_error"], [6, 1, 1, "", "get_epsilon_for_lg_size"], [6, 2, 1, "", "get_estimate"], [6, 2, 1, "", "get_frequent_items"], [6, 2, 1, "", "get_lower_bound"], [6, 2, 1, "", "get_serialized_size_bytes"], [6, 2, 1, "", "get_upper_bound"], [6, 2, 1, "", "is_empty"], [6, 2, 1, "", "merge"], [6, 3, 1, "", "num_active_items"], [6, 2, 1, "", "serialize"], [6, 2, 1, "", "to_string"], [6, 3, 1, "", "total_weight"], [6, 2, 1, "", "update"]], "datasketches.frequent_strings_sketch": [[6, 1, 1, "", "__init__"], [6, 1, 1, "", "deserialize"], [6, 3, 1, "", "epsilon"], [6, 1, 1, "", "get_apriori_error"], [6, 1, 1, "", "get_epsilon_for_lg_size"], [6, 2, 1, "", "get_estimate"], [6, 2, 1, "", "get_frequent_items"], [6, 2, 1, "", "get_lower_bound"], [6, 2, 1, "", "get_serialized_size_bytes"], [6, 2, 1, "", "get_upper_bound"], [6, 2, 1, "", "is_empty"], [6, 2, 1, "", "merge"], [6, 3, 1, "", "num_active_items"], [6, 2, 1, "", "serialize"], [6, 2, 1, "", "to_string"], [6, 3, 1, "", "total_weight"], [6, 2, 1, "", "update"]], "datasketches.kll_doubles_sketch": [[16, 1, 1, "", "__init__"], [16, 1, 1, "", "deserialize"], [16, 2, 1, "", "get_cdf"], [16, 2, 1, "", "get_max_value"], [16, 2, 1, "", "get_min_value"], [16, 1, 1, "", "get_normalized_rank_error"], [16, 2, 1, "", "get_pmf"], [16, 2, 1, "", "get_quantile"], [16, 2, 1, "", "get_quantiles"], [16, 2, 1, "", "get_rank"], [16, 2, 1, "", "is_empty"], [16, 2, 1, "", "is_estimation_mode"], [16, 3, 1, "", "k"], [16, 2, 1, "", "merge"], [16, 3, 1, "", "n"], [16, 2, 1, "", "normalized_rank_error"], [16, 3, 1, "", "num_retained"], [16, 2, 1, "", "serialize"], [16, 2, 1, "", "to_string"], [16, 2, 1, "", "update"]], "datasketches.kll_floats_sketch": [[16, 1, 1, "", "__init__"], [16, 1, 1, "", "deserialize"], [16, 2, 1, "", "get_cdf"], [16, 2, 1, "", "get_max_value"], [16, 2, 1, "", "get_min_value"], [16, 1, 1, "", "get_normalized_rank_error"], [16, 2, 1, "", "get_pmf"], [16, 2, 1, "", "get_quantile"], [16, 2, 1, "", "get_quantiles"], [16, 2, 1, "", "get_rank"], [16, 2, 1, "", "is_empty"], [16, 2, 1, "", "is_estimation_mode"], [16, 3, 1, "", "k"], [16, 2, 1, "", "merge"], [16, 3, 1, "", "n"], [16, 2, 1, "", "normalized_rank_error"], [16, 3, 1, "", "num_retained"], [16, 2, 1, "", "serialize"], [16, 2, 1, "", "to_string"], [16, 2, 1, "", "update"]], "datasketches.kll_ints_sketch": [[16, 1, 1, "", "__init__"], [16, 1, 1, "", "deserialize"], [16, 2, 1, "", "get_cdf"], [16, 2, 1, "", "get_max_value"], [16, 2, 1, "", "get_min_value"], [16, 1, 1, "", "get_normalized_rank_error"], [16, 2, 1, "", "get_pmf"], [16, 2, 1, "", "get_quantile"], [16, 2, 1, "", "get_quantiles"], [16, 2, 1, "", "get_rank"], [16, 2, 1, "", "is_empty"], [16, 2, 1, "", "is_estimation_mode"], [16, 3, 1, "", "k"], [16, 2, 1, "", "merge"], [16, 3, 1, "", "n"], [16, 2, 1, "", "normalized_rank_error"], [16, 3, 1, "", "num_retained"], [16, 2, 1, "", "serialize"], [16, 2, 1, "", "to_string"], [16, 2, 1, "", "update"]], "datasketches.kll_items_sketch": [[16, 1, 1, "", "__init__"], [16, 1, 1, "", "deserialize"], [16, 2, 1, "", "get_cdf"], [16, 2, 1, "", "get_max_value"], [16, 2, 1, "", "get_min_value"], [16, 1, 1, "", "get_normalized_rank_error"], [16, 2, 1, "", "get_pmf"], [16, 2, 1, "", "get_quantile"], [16, 2, 1, "", "get_quantiles"], [16, 2, 1, "", "get_rank"], [16, 2, 1, "", "is_empty"], [16, 2, 1, "", "is_estimation_mode"], [16, 3, 1, "", "k"], [16, 2, 1, "", "merge"], [16, 3, 1, "", "n"], [16, 2, 1, "", "normalized_rank_error"], [16, 3, 1, "", "num_retained"], [16, 2, 1, "", "serialize"], [16, 2, 1, "", "to_string"], [16, 2, 1, "", "update"]], "datasketches.quantiles_doubles_sketch": [[17, 1, 1, "", "__init__"], [17, 1, 1, "", "deserialize"], [17, 2, 1, "", "get_cdf"], [17, 2, 1, "", "get_max_value"], [17, 2, 1, "", "get_min_value"], [17, 1, 1, "", "get_normalized_rank_error"], [17, 2, 1, "", "get_pmf"], [17, 2, 1, "", "get_quantile"], [17, 2, 1, "", "get_quantiles"], [17, 2, 1, "", "get_rank"], [17, 2, 1, "", "is_empty"], [17, 2, 1, "", "is_estimation_mode"], [17, 3, 1, "", "k"], [17, 2, 1, "", "merge"], [17, 3, 1, "", "n"], [17, 2, 1, "", "normalized_rank_error"], [17, 3, 1, "", "num_retained"], [17, 2, 1, "", "serialize"], [17, 2, 1, "", "to_string"], [17, 2, 1, "", "update"]], "datasketches.quantiles_floats_sketch": [[17, 1, 1, "", "__init__"], [17, 1, 1, "", "deserialize"], [17, 2, 1, "", "get_cdf"], [17, 2, 1, "", "get_max_value"], [17, 2, 1, "", "get_min_value"], [17, 1, 1, "", "get_normalized_rank_error"], [17, 2, 1, "", "get_pmf"], [17, 2, 1, "", "get_quantile"], [17, 2, 1, "", "get_quantiles"], [17, 2, 1, "", "get_rank"], [17, 2, 1, "", "is_empty"], [17, 2, 1, "", "is_estimation_mode"], [17, 3, 1, "", "k"], [17, 2, 1, "", "merge"], [17, 3, 1, "", "n"], [17, 2, 1, "", "normalized_rank_error"], [17, 3, 1, "", "num_retained"], [17, 2, 1, "", "serialize"], [17, 2, 1, "", "to_string"], [17, 2, 1, "", "update"]], "datasketches.quantiles_ints_sketch": [[17, 1, 1, "", "__init__"], [17, 1, 1, "", "deserialize"], [17, 2, 1, "", "get_cdf"], [17, 2, 1, "", "get_max_value"], [17, 2, 1, "", "get_min_value"], [17, 1, 1, "", "get_normalized_rank_error"], [17, 2, 1, "", "get_pmf"], [17, 2, 1, "", "get_quantile"], [17, 2, 1, "", "get_quantiles"], [17, 2, 1, "", "get_rank"], [17, 2, 1, "", "is_empty"], [17, 2, 1, "", "is_estimation_mode"], [17, 3, 1, "", "k"], [17, 2, 1, "", "merge"], [17, 3, 1, "", "n"], [17, 2, 1, "", "normalized_rank_error"], [17, 3, 1, "", "num_retained"], [17, 2, 1, "", "serialize"], [17, 2, 1, "", "to_string"], [17, 2, 1, "", "update"]], "datasketches.quantiles_items_sketch": [[17, 1, 1, "", "__init__"], [17, 1, 1, "", "deserialize"], [17, 2, 1, "", "get_cdf"], [17, 2, 1, "", "get_max_value"], [17, 2, 1, "", "get_min_value"], [17, 1, 1, "", "get_normalized_rank_error"], [17, 2, 1, "", "get_pmf"], [17, 2, 1, "", "get_quantile"], [17, 2, 1, "", "get_quantiles"], [17, 2, 1, "", "get_rank"], [17, 2, 1, "", "is_empty"], [17, 2, 1, "", "is_estimation_mode"], [17, 3, 1, "", "k"], [17, 2, 1, "", "merge"], [17, 3, 1, "", "n"], [17, 2, 1, "", "normalized_rank_error"], [17, 3, 1, "", "num_retained"], [17, 2, 1, "", "serialize"], [17, 2, 1, "", "to_string"], [17, 2, 1, "", "update"]], "datasketches.req_floats_sketch": [[18, 1, 1, "", "__init__"], [18, 1, 1, "", "deserialize"], [18, 1, 1, "", "get_RSE"], [18, 2, 1, "", "get_cdf"], [18, 2, 1, "", "get_max_value"], [18, 2, 1, "", "get_min_value"], [18, 2, 1, "", "get_pmf"], [18, 2, 1, "", "get_quantile"], [18, 2, 1, "", "get_quantiles"], [18, 2, 1, "", "get_rank"], [18, 2, 1, "", "get_rank_lower_bound"], [18, 2, 1, "", "get_rank_upper_bound"], [18, 2, 1, "", "is_empty"], [18, 2, 1, "", "is_estimation_mode"], [18, 2, 1, "", "is_hra"], [18, 3, 1, "", "k"], [18, 2, 1, "", "merge"], [18, 3, 1, "", "n"], [18, 3, 1, "", "num_retained"], [18, 2, 1, "", "serialize"], [18, 2, 1, "", "to_string"], [18, 2, 1, "", "update"]], "datasketches.req_ints_sketch": [[18, 1, 1, "", "__init__"], [18, 1, 1, "", "deserialize"], [18, 1, 1, "", "get_RSE"], [18, 2, 1, "", "get_cdf"], [18, 2, 1, "", "get_max_value"], [18, 2, 1, "", "get_min_value"], [18, 2, 1, "", "get_pmf"], [18, 2, 1, "", "get_quantile"], [18, 2, 1, "", "get_quantiles"], [18, 2, 1, "", "get_rank"], [18, 2, 1, "", "get_rank_lower_bound"], [18, 2, 1, "", "get_rank_upper_bound"], [18, 2, 1, "", "is_empty"], [18, 2, 1, "", "is_estimation_mode"], [18, 2, 1, "", "is_hra"], [18, 3, 1, "", "k"], [18, 2, 1, "", "merge"], [18, 3, 1, "", "n"], [18, 3, 1, "", "num_retained"], [18, 2, 1, "", "serialize"], [18, 2, 1, "", "to_string"], [18, 2, 1, "", "update"]], "datasketches.req_items_sketch": [[18, 1, 1, "", "__init__"], [18, 1, 1, "", "deserialize"], [18, 1, 1, "", "get_RSE"], [18, 2, 1, "", "get_cdf"], [18, 2, 1, "", "get_max_value"], [18, 2, 1, "", "get_min_value"], [18, 2, 1, "", "get_pmf"], [18, 2, 1, "", "get_quantile"], [18, 2, 1, "", "get_quantiles"], [18, 2, 1, "", "get_rank"], [18, 2, 1, "", "get_rank_lower_bound"], [18, 2, 1, "", "get_rank_upper_bound"], [18, 2, 1, "", "is_empty"], [18, 2, 1, "", "is_estimation_mode"], [18, 2, 1, "", "is_hra"], [18, 3, 1, "", "k"], [18, 2, 1, "", "merge"], [18, 3, 1, "", "n"], [18, 3, 1, "", "num_retained"], [18, 2, 1, "", "serialize"], [18, 2, 1, "", "to_string"], [18, 2, 1, "", "update"]], "datasketches.theta_a_not_b": [[3, 1, 1, "", "__init__"], [3, 2, 1, "", "compute"]], "datasketches.theta_intersection": [[3, 1, 1, "", "__init__"], [3, 2, 1, "", "get_result"], [3, 2, 1, "", "has_result"], [3, 2, 1, "", "update"]], "datasketches.theta_jaccard_similarity": [[9, 1, 1, "", "dissimilarity_test"], [9, 1, 1, "", "exactly_equal"], [9, 1, 1, "", "jaccard"], [9, 1, 1, "", "similarity_test"]], "datasketches.theta_sketch": [[3, 2, 1, "", "get_estimate"], [3, 2, 1, "", "get_lower_bound"], [3, 2, 1, "", "get_seed_hash"], [3, 2, 1, "", "get_upper_bound"], [3, 2, 1, "", "is_empty"], [3, 2, 1, "", "is_estimation_mode"], [3, 2, 1, "", "is_ordered"], [3, 3, 1, "", "num_retained"], [3, 3, 1, "", "theta"], [3, 3, 1, "", "theta64"], [3, 2, 1, "", "to_string"]], "datasketches.theta_union": [[3, 1, 1, "", "__init__"], [3, 2, 1, "", "get_result"], [3, 2, 1, "", "update"]], "datasketches.tuple_a_not_b": [[4, 1, 1, "", "__init__"], [4, 2, 1, "", "compute"]], "datasketches.tuple_intersection": [[4, 1, 1, "", "__init__"], [4, 2, 1, "", "get_result"], [4, 2, 1, "", "has_result"], [4, 2, 1, "", "update"]], "datasketches.tuple_jaccard_similarity": [[9, 1, 1, "", "dissimilarity_test"], [9, 1, 1, "", "exactly_equal"], [9, 1, 1, "", "jaccard"], [9, 1, 1, "", "similarity_test"]], "datasketches.tuple_sketch": [[4, 2, 1, "", "DEFAULT_SEED"], [4, 2, 1, "", "get_estimate"], [4, 2, 1, "", "get_lower_bound"], [4, 2, 1, "", "get_seed_hash"], [4, 2, 1, "", "get_upper_bound"], [4, 2, 1, "", "is_empty"], [4, 2, 1, "", "is_estimation_mode"], [4, 2, 1, "", "is_ordered"], [4, 3, 1, "", "num_retained"], [4, 3, 1, "", "theta"], [4, 3, 1, "", "theta64"], [4, 2, 1, "", "to_string"]], "datasketches.tuple_union": [[4, 1, 1, "", "__init__"], [4, 2, 1, "", "get_result"], [4, 2, 1, "", "reset"], [4, 2, 1, "", "update"]], "datasketches.update_theta_sketch": [[3, 1, 1, "", "__init__"], [3, 2, 1, "", "compact"], [3, 2, 1, "", "reset"], [3, 2, 1, "", "trim"], [3, 2, 1, "", "update"]], "datasketches.update_tuple_sketch": [[4, 1, 1, "", "__init__"], [4, 2, 1, "", "compact"], [4, 2, 1, "", "filter"], [4, 2, 1, "", "reset"], [4, 2, 1, "", "trim"], [4, 2, 1, "", "update"]], "datasketches.var_opt_sketch": [[21, 1, 1, "", "__init__"], [21, 1, 1, "", "deserialize"], [21, 2, 1, "", "estimate_subset_sum"], [21, 2, 1, "", "get_serialized_size_bytes"], [21, 2, 1, "", "is_empty"], [21, 3, 1, "", "k"], [21, 3, 1, "", "n"], [21, 3, 1, "", "num_samples"], [21, 2, 1, "", "serialize"], [21, 2, 1, "", "to_string"], [21, 2, 1, "", "update"]], "datasketches.var_opt_union": [[21, 1, 1, "", "__init__"], [21, 1, 1, "", "deserialize"], [21, 2, 1, "", "get_result"], [21, 2, 1, "", "get_serialized_size_bytes"], [21, 2, 1, "", "reset"], [21, 2, 1, "", "serialize"], [21, 2, 1, "", "to_string"], [21, 2, 1, "", "update"]]}, "objnames": {"0": ["py", "class", "Python class"], "1": ["py", "method", "Python method"], "2": ["py", "attribute", "Python attribute"], "3": ["py", "property", "Python property"], "4": ["py", "function", "Python function"]}, "objtypes": {"0": "py:class", "1": "py:method", "2": "py:attribute", "3": "py:property", "4": "py:function"}, "terms": {"": [1, 6, 19, 20, 21], "0": [3, 4, 5, 6, 10, 16, 17, 18], "01668v2": 18, "05": 5, "1": [0, 1, 3, 4, 5, 6, 10, 16, 17, 18], "10": [1, 17], "100": 17, "1000": 17, "11": 0, "12": [3, 4, 18], "128": 17, "13": 16, "14": 6, "16": 1, "18": 6, "1982": 6, "1985": 2, "1e": 6, "1e9": 6, "2": [0, 1, 3, 4, 6, 17, 18], "20": 17, "200": 16, "2002": 6, "2003": 6, "2004": 18, "2006": 6, "2020": 16, "2021": 17, "2023": 19, "21": 1, "3": [0, 1, 3, 4, 6, 17, 18], "30": 17, "32": [12, 16], "33": 16, "4": [1, 12, 17], "40": 17, "47": 16, "483": 17, "5": [5, 6, 17], "500": 17, "50th": 17, "517": 17, "6": 1, "64": [0, 3, 4, 5, 12, 17], "65": 16, "7": [1, 9, 17], "75": 6, "8": [1, 6, 12], "80": 11, "900": 17, "9001": [0, 3, 4, 9], "93smirnov_test": 11, "95": [5, 17], "95th": 17, "97": 9, "99": [16, 17], "A": [1, 3, 4, 6, 10, 11, 12, 13, 16, 17, 21], "As": [0, 16, 17], "For": [0, 1, 5, 6, 16, 17, 18, 23], "If": [1, 6, 9, 16, 17, 18], "In": [0, 1, 16, 19], "It": [3, 16, 17, 18], "One": 2, "That": 15, "The": [0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 22], "Then": 16, "There": [3, 6], "These": [1, 8, 9, 15, 20, 23], "With": [16, 17, 18], "_": 11, "__call__": [10, 13], "__eq__": 6, "__hash__": 6, "__init__": [0, 1, 3, 4, 6, 16, 17, 18, 19, 21, 22], "__lt__": [16, 17, 18], "_datasketch": [0, 1, 3, 4, 5, 6, 9, 11, 16, 17, 18, 19, 21, 22], "ab": 18, "abbadi": 6, "abil": 18, "about": [1, 15, 16, 17], "abov": [7, 16], "absolut": 8, "abstract": [3, 4, 8, 10, 12, 13], "accept": 23, "account": 11, "accumulatori": 13, "accumulatorpolici": 13, "accuraci": [0, 1, 2, 3, 5, 6, 16, 17, 18], "achiev": 5, "activ": [6, 14], "actual": [9, 17], "ad": 13, "add": 16, "addit": [0, 2, 6, 12], "addition": 16, "advanc": 20, "affect": [16, 17], "after": [18, 20], "against": [0, 9], "agraw": 6, "algorithm": [0, 1, 2, 3, 6, 14, 18], "all": [1, 3, 6, 12, 13, 15, 16, 17, 19, 21], "alloc": 12, "allow": [0, 4, 12, 13, 18], "along": 6, "also": [0, 3, 10, 14, 15, 17], "altern": 15, "although": [1, 19], "alwai": [6, 13, 16, 17, 19, 20], "an": [0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 12, 13, 15, 16, 17, 18, 19, 20, 21, 22], "analog": [16, 17, 18], "analysi": [4, 11, 16, 17, 18], "analyz": 14, "ani": [3, 4, 5, 6, 7, 13, 16, 17], "anoth": [0, 6, 18], "answer": 15, "appl": 0, "appli": [2, 3, 4, 6, 13, 15, 16, 18, 20, 21], "applic": 2, "approach": 15, "approx": [5, 18], "approxim": [0, 1, 3, 4, 5, 6, 10, 15, 16, 17, 18, 22], "ar": [0, 1, 3, 4, 5, 6, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 20, 23], "arbitrari": [4, 6], "arg": [0, 1, 3, 4, 5, 6, 10, 12, 13, 16, 17, 18, 19, 21, 22], "arg0": 3, "arg1": 3, "around": 16, "arrai": [6, 10, 16, 17, 18], "art": 2, "arxiv": 18, "as_pmf": [16, 17], "associ": [4, 6, 16, 17, 18], "assum": [6, 11], "avail": 16, "avoid": 3, "axi": 16, "b": [3, 4, 10, 19], "back": 0, "background": 6, "backward": [6, 15], "bag": 6, "bandwidth": 10, "base": [0, 1, 2, 3, 4, 5, 6, 8, 10, 12, 13, 18, 19, 20, 22], "basi": 10, "basic": [3, 4, 10], "becaus": 16, "been": [7, 16, 17, 18, 21], "befor": [6, 7], "behavior": 1, "being": 20, "below": 16, "best": [16, 17], "better": [1, 2, 3], "between": [1, 3, 4, 6, 8, 9, 16, 17, 18, 22], "beyond": 3, "big": 14, "bin": [0, 16], "binari": [12, 16, 17], "bit": [0, 1, 3, 4, 5, 12, 16, 17], "blob": 22, "bool": [1, 3, 4, 9, 11, 16, 17, 18], "both": [11, 18, 20], "bound": [0, 1, 3, 4, 5, 6, 9, 14, 15, 16, 18, 20, 21], "boundari": [1, 6], "bracket": 16, "bucket": [1, 5], "build": 22, "byte": [0, 1, 3, 4, 5, 6, 12, 16, 17, 18, 19, 21, 22], "c": [0, 19], "call": [16, 19], "came": 2, "can": [0, 1, 3, 4, 6, 11, 13, 15, 16, 17, 18], "cannot": 16, "capabl": [0, 6, 18], "capac": 6, "cardin": [0, 3], "case": [1, 6, 8, 17, 19], "caus": 6, "cdf": [15, 16, 17, 18], "certain": [7, 8, 10, 16, 19], "choic": 1, "choos": 18, "class": [0, 1, 3, 4, 5, 6, 9, 10, 12, 13, 16, 17, 18, 19, 21, 22], "classic": [15, 17], "close": 7, "cm": 5, "code": [6, 18], "collect": 1, "com": 22, "combin": [8, 13], "come": [11, 17], "commonli": [6, 16], "compact": [1, 3, 4, 16, 18], "compact_theta_sketch": 3, "compact_tuple_sketch": 4, "compactor": 18, "compar": [0, 16, 17, 18], "comparison": [0, 18], "compat": [6, 12, 15, 16, 17], "complic": 4, "compress": [1, 2, 3, 14], "comput": [3, 4, 6, 8, 9, 15, 19, 21, 22], "concept": 2, "concret": 8, "confid": [5, 9, 16, 17], "configur": [0, 1, 5, 16, 17, 18, 19, 21, 22], "consecut": [16, 17, 18], "consid": [9, 17], "consist": 13, "constant": [1, 6, 16, 17, 18], "construct": [1, 18, 21], "consum": [1, 12], "contain": [3, 6, 7], "context": 10, "contrast": [5, 19], "control": [16, 17, 18, 22], "coreset": 22, "cormod": [5, 18], "correspond": [0, 1, 3, 4, 5, 6, 16, 17, 18, 19, 21, 22], "cost": [1, 12], "could": [16, 17, 18], "count": [1, 3, 4, 6, 17, 18], "count_min_sketch": [5, 7], "counter": 6, "countmin": [7, 14], "coupon": 1, "cpc": [1, 2, 14], "cpc_sketch": [0, 2], "cpc_union": 0, "creat": [0, 3, 4, 6, 13, 16, 17, 18, 19, 21, 22], "create_summari": 13, "creation": 19, "criterion": 18, "critic": 12, "cross": [12, 17], "cumul": [15, 16, 17, 18], "current": [1, 3, 4, 5, 6, 7, 11, 15, 19, 21], "custom": [4, 10, 12, 13], "data": [2, 3, 6, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 22], "datasketch": [2, 11], "datum": [0, 1, 3, 4], "debug": 18, "decreas": [15, 18], "decrement": 6, "dedic": [3, 4], "default": [1, 3, 4, 10, 16, 17, 18], "default_se": 4, "defin": [3, 4, 6, 10, 16, 19], "definit": [16, 17, 18], "delta": 5, "demain": 6, "denot": [5, 6], "densiti": [8, 10, 14, 23], "density_sketch": [10, 22, 23], "depend": [5, 16], "deprec": [14, 15], "deriv": [3, 16, 17, 18], "describ": [0, 5, 18], "deseri": [0, 1, 3, 4, 5, 6, 8, 14, 16, 17, 18, 19, 21, 22], "design": [15, 23], "desing": 21, "detail": [18, 20], "determin": [7, 11], "determinist": 6, "develop": [0, 14], "deviat": [0, 1, 3, 4, 18], "differ": [0, 1, 2, 3, 6, 12, 13, 18, 20], "dim": 22, "dimac": 5, "dimens": [0, 22], "dimension": 16, "discov": 6, "discrep": 22, "discuss": 18, "disjoint": [16, 17, 18], "dissimilar": 9, "dissimilarity_test": 9, "distanc": 22, "distinct": [0, 1, 3, 4, 6], "distribut": [1, 11, 15, 16, 17, 18], "divid": [16, 17, 18], "do": 6, "document": 16, "doe": [0, 5, 6, 7, 16, 18, 20], "domain": 16, "doubl": [16, 17, 18, 19], "dtype": [16, 17, 18], "dure": 1, "e": 15, "e2": 11, "each": [1, 2, 4, 6, 11, 12, 13, 15, 16, 17, 18, 20], "earliest": 2, "easili": [3, 4], "ebpp": [14, 20], "ebpps_sketch": [19, 20], "edg": [16, 17], "edo": [18, 22], "edoliberti": 22, "edu": 5, "effect": [3, 4], "effici": [0, 3, 6, 14], "either": [6, 15, 16, 17, 18], "element": [2, 6], "els": 18, "empir": [0, 16, 17, 18], "emploi": 6, "empti": [0, 1, 3, 4, 6, 16, 17, 18, 19, 21, 22], "en": 11, "enabl": [16, 17], "encod": 12, "end": 15, "endian": 12, "enough": 1, "ensur": [6, 19, 20], "entir": [7, 15, 20], "entri": [1, 3, 4, 6], "entropi": 0, "ep": 16, "epsilon": [6, 16], "equal": [11, 15, 16, 17, 18, 19], "equival": [9, 16, 17, 19, 21], "error": [1, 3, 5, 6, 8, 11, 14, 15, 16, 17, 19, 21, 22], "estim": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 16, 17, 18, 21, 22, 23], "estimate_subset_sum": 21, "estimated_total_stream_weight": 6, "estimated_total_weight": 6, "evalu": [4, 10], "even": [0, 20], "everi": [3, 4, 5, 6], "exact": [6, 14, 20], "exactli": [19, 20], "exactly_equ": 9, "exampl": [4, 5, 6, 8, 10, 12, 17], "exce": [6, 18, 19], "except": [1, 16, 17, 18], "excess": [3, 4], "exclud": 6, "exclus": [16, 17, 18], "exist": [3, 4, 13], "expect": [9, 19], "expens": 6, "express": 18, "extend": [12, 13], "extens": [4, 18], "extern": 6, "extrem": [0, 6], "f688c8161a25582457b0a09deb4630a81406293b": 22, "f_x": 5, "factor": 18, "failur": 5, "fals": [0, 1, 3, 4, 5, 6, 9, 11, 16, 17, 18, 19, 21, 22], "famili": [1, 8, 11], "far": [6, 15, 16, 17, 18, 19], "fast": 0, "favor": [15, 17], "fed": 1, "feed": [19, 21], "few": 4, "fewer": [6, 19, 21], "field": 6, "filter": 4, "find": 6, "fit": [16, 17], "fix": 4, "flag": [16, 17], "flajolet": [1, 2], "flavor": [1, 6], "float": [0, 1, 3, 4, 5, 6, 9, 10, 11, 12, 15, 16, 17, 18, 19], "float32": [16, 17, 18], "float64": [16, 17], "fm85": 0, "follow": [6, 16, 18, 22], "footprint": 2, "form": [3, 4, 6, 11], "format": 12, "found": 6, "fraction": [3, 4, 16, 17, 19], "framework": 3, "frequenc": [5, 6, 17], "frequent": [5, 7, 14], "frequent_items_error_typ": 6, "frequent_items_sketch": [6, 7], "frequent_strings_sketch": [6, 7], "from": [2, 3, 4, 6, 7, 10, 11, 12, 16, 17, 18, 19, 20, 21, 22], "from_byt": 12, "full": [1, 5], "funciton": 10, "function": [0, 1, 3, 4, 5, 6, 8, 11, 14, 15, 16, 17, 18], "futur": 0, "g": 15, "gaussian": 10, "gaussiankernel": 10, "gde": 22, "gener": [6, 7, 10, 15, 16, 17, 18], "get": [16, 17], "get_apriori_error": 6, "get_cdf": [16, 17, 18], "get_compact_serialization_byt": 1, "get_epsilon_for_lg_s": 6, "get_estim": [0, 1, 3, 4, 5, 6, 22], "get_frequent_item": 6, "get_lower_bound": [0, 1, 3, 4, 5, 6], "get_max_updatable_serialization_byt": 1, "get_max_valu": [16, 17, 18], "get_min_valu": [16, 17, 18], "get_n": 17, "get_normalized_rank_error": [16, 17, 18], "get_pmf": [16, 17, 18], "get_quantil": [16, 17, 18], "get_rank": [16, 17, 18], "get_rank_lower_bound": 18, "get_rank_upper_bound": 18, "get_rel_err": 1, "get_relative_error": 5, "get_result": [0, 1, 3, 4, 19, 21], "get_rs": 18, "get_seed_hash": [3, 4], "get_serialized_size_byt": [5, 6, 19, 21], "get_siz": 12, "get_updatable_serialization_byt": 1, "get_upper_bound": [0, 1, 3, 4, 5, 6], "github": 22, "given": [0, 1, 3, 4, 5, 6, 10, 11, 12, 15, 16, 17, 18, 19, 21, 22], "global": [6, 15], "good": [2, 3], "graham": [5, 18], "gri": 6, "grow": 6, "guarante": [5, 6, 16, 17, 18], "ha": [1, 3, 4, 5, 7, 15, 16, 17, 18], "haa": 19, "handl": [3, 7, 19], "has_result": [3, 4], "hash": [0, 3, 4, 5, 6], "hat": 5, "have": [1, 6, 11, 16, 17, 18, 21], "heavi": [5, 6, 7, 14], "heaviest": 7, "help": [9, 18], "hentschel": 19, "here": 18, "hi": 0, "high": [0, 1, 15, 18], "higher": [1, 17], "highest": 1, "highli": 14, "hip": 0, "histogram": [15, 17], "histor": [0, 15], "hitter": [5, 6, 7, 14], "hll": [0, 2, 14], "hll_4": 1, "hll_6": 1, "hll_8": 1, "hll_sketch": [1, 2], "hll_union": 1, "hold": [1, 6], "how": [4, 7, 8, 13, 18], "howev": [6, 16, 18], "http": [5, 11, 18, 22], "hyper": 2, "hyperloglog": [0, 2, 3, 14], "hypothesi": 11, "hypothet": [16, 17, 18], "i": [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22], "icon": 0, "identifi": 7, "imag": 5, "implement": [0, 1, 4, 6, 7, 10, 12, 13, 16, 17, 18, 22], "improv": [1, 21], "includ": [15, 16, 17, 18, 19, 20, 21], "inclus": [1, 16, 17, 18, 20], "incom": [3, 4, 6], "increas": [16, 17, 18], "increment": 6, "independ": 16, "index": [9, 14, 16, 17], "indic": [1, 10], "inform": 19, "inherit": 10, "init_number_of_sect": 18, "initi": [1, 3, 4, 6, 18], "input": [0, 1, 3, 4, 6, 10, 11, 16, 17, 18, 20, 22, 23], "insert": [3, 5, 6], "inspir": 22, "instanc": [6, 16, 17, 18, 19, 21, 22], "instead": [17, 18], "insuffici": 11, "int": [0, 1, 3, 4, 5, 6, 9, 12, 16, 17, 18, 19, 21, 22], "int32": [16, 17, 18], "integ": [0, 5, 6, 12, 13, 15], "integr": [1, 3, 4], "intern": 6, "internet": 6, "interpret": 16, "intersect": [2, 3, 4, 13], "interv": [16, 17, 18], "introduc": 6, "invers": [0, 16], "involv": 7, "is_compact": 1, "is_empti": [0, 1, 3, 4, 5, 6, 16, 17, 18, 19, 21, 22], "is_estimation_mod": [3, 4, 16, 17, 18, 22], "is_hra": 18, "is_ord": [3, 4], "item": [1, 3, 4, 5, 7, 12, 14, 15, 16, 17, 18, 19, 20, 21, 22], "iter": 19, "its": [0, 12, 16, 17, 19], "itself": 6, "j": 19, "j_": 9, "jaccard": [3, 4, 8, 14], "java": [16, 17], "just": 16, "justin": 18, "k": [0, 1, 2, 3, 4, 6, 7, 16, 17, 18, 19, 21, 22], "kappa": 0, "karnin": [18, 22], "karnin19a": 22, "karp": 6, "keep": [1, 4, 19], "kei": [2, 4], "kept": 13, "kernel": [8, 14, 22, 23], "kernel_funct": 8, "kernel_sketch": 8, "kernelfunct": [10, 22], "kevin": 0, "kll": [14, 15, 17], "kll_doubles_sketch": [11, 16], "kll_floats_sketch": [11, 16], "kll_ints_sketch": [11, 16], "kll_items_sketch": [11, 16], "known": [0, 2, 6, 10, 14, 20], "kolmogorov": [8, 14], "ks_test": [8, 11], "kwarg": [0, 1, 3, 4, 5, 6, 10, 12, 13, 16, 17, 18, 19, 21, 22], "lang": 0, "languag": [12, 17], "larg": [1, 15, 16, 17], "larger": [2, 16, 19], "largest": 13, "last": [16, 17, 18], "lazi": 16, "lb": [6, 9], "le": 5, "learn": [10, 22], "least": [6, 8], "left": [16, 17, 18], "legaci": 6, "lemma": 18, "len": 12, "length": [6, 16, 17, 18, 19, 20, 21, 22], "less": [15, 16, 17, 18], "let": 16, "letter": 19, "level": [5, 18], "leverag": 1, "lg_config_k": 1, "lg_k": [0, 1, 3, 4], "lg_max_k": [1, 6], "lg_max_map_s": 6, "liberti": [18, 22], "librari": [2, 4, 6, 7, 10, 11, 15, 23], "like": [1, 7, 11, 16], "limit": [6, 19], "line": [16, 17, 18], "list": [5, 7, 9], "littl": 12, "load_factor": 6, "log": [1, 2], "log2": [1, 6], "logarithm": [0, 3, 4, 6], "logic": [6, 15], "longer": 2, "look": 6, "loos": 18, "lopez": 6, "low": [15, 18], "lower": [0, 1, 3, 4, 5, 6, 9, 16, 18, 21], "lower_bound": 9, "m": [6, 16, 17, 18], "machin": [10, 22], "mai": [5, 6, 14, 15, 16, 18, 19], "maintain": [3, 7], "make": 16, "mani": 3, "map": 6, "mapcap": 6, "mapsiz": 6, "margin": 19, "martin": 2, "mass": [15, 16, 17, 18], "mass_i": 16, "match": [0, 3, 4, 21], "mathemat": [10, 18], "max": [13, 16, 17, 18], "max_k": 21, "max_map_s": 6, "maximum": [1, 3, 4, 5, 6, 16, 17, 18, 19, 21], "maxintpolici": 13, "maxmapcap": 6, "maxmaps": 6, "mean": [4, 6, 16, 17, 19], "measur": [3, 4, 9, 16, 17, 18], "median": [6, 17], "member": [3, 6], "memori": [1, 2, 6], "merg": [0, 1, 4, 5, 6, 16, 17, 18, 19, 22], "method": [0, 1, 3, 4, 5, 6, 10, 12, 16, 17, 18, 19, 21, 22], "metwal": 6, "might": [6, 16], "million": 17, "min": [13, 16, 17, 18], "minim": 20, "minimum": [2, 3, 16, 17, 18, 21], "minintpolici": 13, "misra": 6, "miss": 6, "mlr": 22, "mode": [1, 3, 4, 16, 17, 18, 22], "modifi": [11, 18], "modul": [1, 6, 14], "monoton": [16, 17, 18], "more": [0, 6], "most": [7, 17], "much": [1, 6], "multipli": 17, "multiset": 6, "munro": 6, "must": [1, 3, 4, 10, 12, 13, 16, 17, 18], "muthukrishnan": 5, "n": [1, 16, 17, 18, 19, 21, 22], "name": [1, 6], "nan": [16, 17, 18], "natur": [16, 17], "ndarrai": [16, 17, 18], "nearli": [0, 16], "necessari": [16, 17, 18], "necessarili": 7, "need": [3, 5, 6, 13, 19, 20, 21], "network": 17, "never": [5, 6, 16, 18], "new": [0, 1, 6, 13, 17, 19, 21, 22], "newli": 0, "no_false_neg": 6, "no_false_posit": 6, "node": 17, "nomin": [3, 4, 18], "non": [0, 1, 3, 4, 5, 6, 16, 17, 18, 19, 21, 22], "none": [0, 1, 3, 4, 5, 6, 16, 17, 18, 19, 21, 22], "normal": [16, 17, 18], "normalized_rank_error": [16, 17], "note": [6, 9, 11, 16, 18], "novemb": 17, "now": 23, "null": [11, 12], "num_active_item": 6, "num_bucket": 5, "num_byt": 12, "num_hash": 5, "num_retain": [3, 4, 16, 17, 18, 22], "num_sampl": 21, "num_std_dev": 1, "number": [0, 1, 2, 3, 4, 5, 6, 12, 16, 17, 18, 19, 21, 22], "numer": [15, 19], "numpi": 10, "numsect": 18, "object": [0, 1, 3, 4, 5, 6, 7, 9, 10, 12, 13, 16, 17, 18, 19, 21, 22], "obtain": [5, 16, 17, 18], "occurr": 5, "off": [1, 2, 16, 17, 18], "offer": [1, 2, 7], "offest": 12, "offset": 12, "often": 7, "one": [2, 5, 6, 7, 8, 16, 17, 18, 22], "onli": [1, 6, 16, 17, 18, 23], "oper": [0, 2, 3, 4, 13, 16, 18], "opposit": 16, "opt": 21, "optim": [0, 14, 16, 20], "option": [0, 3, 4, 6, 16, 17, 18, 19, 21], "order": [3, 4, 5, 13, 15, 19], "org": [11, 18], "ortiz": 6, "other": [3, 4, 5, 16, 17], "otherwis": [0, 1, 3, 4, 5, 6, 9, 11, 16, 17, 18, 19, 21, 22], "our": 6, "output": 18, "outsid": 7, "over": [6, 15, 17], "overal": 17, "overestim": 5, "overload": [0, 1, 3, 4, 5, 11, 16, 17, 18], "overrid": [10, 12], "p": [3, 4, 11, 19], "packag": 3, "packet": [6, 17], "page": 14, "pair": [6, 8, 11], "papadimitri": 6, "paper": [0, 3, 5, 18, 22], "paramet": [0, 1, 3, 4, 5, 6, 10, 12, 13, 16, 17, 18, 19, 21, 22], "partial": 19, "particular": 18, "particularli": 10, "pass": [16, 17], "pattern": 10, "pavel": 18, "pdf": [5, 22], "per": [1, 16], "percentag": 7, "percentil": [16, 17], "perform": [0, 1, 2, 3, 4, 8, 10, 11, 16, 18], "permiss": 5, "phillip": 1, "physic": 6, "plot": 16, "plu": 6, "pmf": [15, 16, 17, 18], "point": [0, 1, 3, 4, 10, 12, 15, 16, 17, 18, 19, 22], "polici": [4, 8, 14], "portion": [15, 19], "posit": 6, "possibl": 0, "power": [6, 18], "pp": 19, "practic": [3, 6], "pre": 12, "precis": [16, 17, 19], "predic": [4, 20, 21], "present": 21, "press": 22, "print": [19, 21], "priori": [1, 6, 18], "probabilist": [1, 2, 5, 14, 15, 16, 17, 18], "probabilitii": [14, 20], "probabl": [0, 5, 6, 15, 16, 17, 18, 19, 20, 21], "problem": 14, "proceed": 22, "process": [19, 21], "produc": [0, 1, 3, 4, 5, 6, 16, 17, 18, 19, 21, 22], "project": [14, 17], "proof": 6, "properti": [0, 1, 2, 3, 4, 5, 6, 16, 17, 18, 19, 21, 22], "proport": [14, 20], "prototyp": 18, "proven": 15, "provid": [0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 15, 16, 17, 18, 21, 22, 23], "pub": 5, "purg": 6, "py": 22, "pydoublesserd": 12, "pyfloatsserd": 12, "pyintsserd": 12, "pylongsserd": 12, "pyobjectserd": [4, 6, 12, 16, 17, 18, 19, 21], "pystringsserd": 12, "python": [13, 18], "q": 16, "q_hi": 16, "q_lo": 16, "qualifi": 6, "qualnam": [1, 6], "quantil": [8, 16, 22], "quantiles_doubles_sketch": [11, 17], "quantiles_floats_sketch": [11, 17], "quantiles_ints_sketch": [11, 17], "quantiles_items_sketch": [11, 17], "queri": [5, 15, 16, 17, 21], "quickli": 14, "quit": [0, 4, 16], "r": 16, "r1": 16, "r2": 16, "r_": 16, "r_i": 16, "radial": 10, "random": [6, 19], "randomli": 20, "rang": 15, "rank": [15, 16, 17, 18], "rate": [3, 4], "reach": [1, 6], "read": [0, 1, 3, 4, 5, 6, 12, 19, 21, 22], "real": [16, 17, 18], "reason": 1, "rebuild": 6, "receiv": [1, 17], "recognit": 10, "recommend": 1, "reconstruct": 12, "redesign": 6, "rediscov": 6, "refer": [6, 8, 12, 16], "reflect": 11, "regardless": 7, "reject": 11, "rel": [1, 5, 7, 14, 15, 19, 20, 21], "relat": [7, 9, 19, 21], "relationship": 16, "relative_error": 5, "relev": 13, "reli": 10, "remain": 18, "remov": [3, 4, 6], "repeat": 6, "repres": [1, 17, 19], "req": [14, 15, 17], "req_floats_sketch": 18, "req_ints_sketch": 18, "req_items_sketch": 18, "requir": [4, 5, 6, 8, 16, 17, 18, 19, 21, 22], "reservoir": [19, 21], "reset": [1, 3, 4, 21], "respect": [16, 17], "result": [0, 3, 4, 6, 16, 17, 18, 20, 21], "retain": [3, 4, 6, 16, 17, 18, 22], "retun": 12, "return": [0, 1, 3, 4, 5, 6, 9, 10, 11, 12, 13, 16, 17, 18, 19, 21, 22], "right": [4, 16, 17, 18], "roughli": [0, 21], "round": 18, "row": 1, "rse": 18, "rule": 13, "run": 6, "runtimeerror": [16, 17, 18], "rutger": 5, "s1": 16, "s2": 16, "s_i": 16, "s_m": 16, "same": [1, 3, 11], "sampl": [3, 4, 16, 17, 18, 22], "satisfi": 5, "scheme": [12, 16], "score": 10, "search": 14, "section": 18, "section_s": 18, "secur": 0, "see": 16, "seed": [0, 3, 4, 5, 9], "seem": 16, "seen": [5, 6, 7, 15, 19], "select": 4, "self": [0, 1, 3, 4, 5, 6, 10, 12, 13, 16, 17, 18, 19, 21, 22], "semin": 2, "separ": [3, 9, 16, 17, 18], "serd": [4, 6, 8, 14, 16, 17, 18, 19, 21], "serial": [0, 1, 3, 4, 5, 6, 8, 14, 16, 17, 18, 19, 21, 22], "serialize_compact": 1, "serialize_updat": 1, "set": [2, 3, 4, 6, 13, 16, 17, 18, 22], "sever": [2, 3, 4, 6, 12], "shenker": 6, "should": [13, 16, 19], "shown": 16, "side": [16, 17], "significantli": 1, "similar": [2, 3, 4, 8, 10, 13, 14], "similarity_test": 9, "similarli": 17, "simpl": [2, 3, 6, 12], "simultan": 0, "sinc": [6, 18], "singl": [16, 17], "size": [1, 3, 4, 5, 6, 11, 12, 14, 16, 17, 18, 20, 21, 22], "sk_1": 11, "sk_2": 11, "skech": 18, "sketch": [0, 1, 2, 6, 8, 9, 11, 12, 19, 21], "sketch_a": 9, "sketch_b": 9, "slot": 1, "sm": 16, "small": [1, 6, 11], "smaller": [0, 1, 6, 16, 21], "smallest": 13, "smirnov": [8, 14], "snly": 7, "so": [0, 6, 15, 16, 17, 18, 19], "solut": 2, "some": [6, 8, 16], "sometim": 16, "somewhat": [2, 20], "sort": [3, 4, 16, 17, 18], "sourc": [3, 4], "sourch": 4, "space": [0, 1, 2, 3, 6], "special": 18, "specif": [6, 8, 10, 15, 16, 17], "specifi": [0, 1, 5, 6, 8, 12, 13, 16, 18], "speed": [0, 6], "split": [16, 17, 18], "split_point": [16, 17, 18], "sqrt": 18, "standard": [0, 1, 3, 4, 18], "start": [1, 6, 12, 18], "start_full_s": 1, "start_max_s": 1, "state": [1, 2, 3, 4, 6, 18, 21], "static": [0, 1, 3, 4, 5, 6, 16, 17, 18, 19, 21, 22], "stochast": [16, 17], "storag": [1, 12], "store": [2, 3, 6], "str": [0, 1, 3, 4, 5], "straightforward": 15, "stream": [0, 1, 3, 4, 5, 6, 7, 15, 16, 17, 18, 19, 20, 21, 22], "strictli": 19, "string": [0, 1, 3, 4, 5, 6, 7, 12, 16, 17, 18, 19, 21, 22], "string_cont": 12, "subset": [20, 21], "subtract": 16, "suggest": 5, "suggest_num_bucket": 5, "suggest_num_hash": 5, "sum": [6, 16, 17, 18, 20, 21], "summari": [0, 1, 3, 4, 5, 6, 8, 13, 16, 17, 18, 19, 21, 22], "support": [2, 6], "surviv": 0, "t": [16, 17], "tabl": [1, 6], "take": 11, "target": 1, "target_hll_typ": 1, "task": 2, "templat": [16, 17], "term": 1, "termin": 12, "test": [8, 9, 14], "tgt_hll_type": 1, "tgt_type": 1, "thaler": 18, "than": [0, 1, 2, 3, 6, 15, 16, 17, 18, 19], "thei": [4, 11, 15, 20], "them": 8, "theta": [1, 2, 4, 8, 9, 14], "theta64": [3, 4], "theta_a_not_b": 3, "theta_intersect": 3, "theta_jaccard_similar": [3, 9], "theta_sketch": [2, 3, 4, 9], "theta_union": 3, "thi": [0, 1, 4, 5, 6, 11, 12, 13, 14, 16, 17, 18, 19, 21, 22], "those": [7, 8], "thousand": [16, 17], "three": [1, 12, 15], "threshold": 9, "through": [3, 4, 6], "throw": [16, 17, 18], "thu": [16, 18], "tian": 19, "tight": 18, "time": [1, 6, 16, 17, 18], "to_byt": 12, "to_str": [0, 1, 3, 4, 5, 6, 16, 17, 18, 19, 21, 22], "too": [6, 11], "tool": 18, "top": [6, 7], "topk": 14, "total": [5, 17, 18, 19, 21], "total_weight": [5, 6], "track": 6, "trade": [1, 2, 16, 17, 18], "tradeoff": 0, "translat": 16, "trial": [16, 17], "trim": [3, 4], "true": [0, 1, 3, 4, 5, 6, 9, 11, 16, 17, 18, 19, 21, 22], "true_mass": 16, "true_rank": 16, "tupl": [2, 3, 8, 9, 12, 14], "tuple_a_not_b": [3, 4], "tuple_intersect": 4, "tuple_jaccard_similar": [4, 9], "tuple_polici": 8, "tuple_sketch": [2, 4, 8, 9, 13], "tuple_union": 4, "tuplepolici": [4, 13], "two": [0, 6, 7, 10, 11, 16, 18, 22], "type": [1, 2, 4, 6, 7, 10, 11, 12, 13, 15], "typic": 6, "u": 16, "ub": [6, 9], "under": 14, "underestim": 5, "underli": 11, "understand": [15, 18], "unequ": 19, "uniform": [15, 19, 21], "union": [0, 1, 3, 4, 13, 21], "uniqu": [0, 1, 2, 16, 17, 18], "unsurprisingli": 10, "up": [1, 6], "updat": [0, 1, 3, 4, 5, 6, 13, 16, 17, 18, 19, 21, 22], "update_summari": 13, "update_theta_sketch": 3, "update_tuple_sketch": 4, "upon": 19, "upper": [0, 1, 3, 4, 5, 6, 9, 16, 18, 21], "upper_bound": [1, 9], "us": [1, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 22], "usag": 6, "user": [0, 10, 18], "usual": 6, "v99": 22, "valid": [3, 4, 18], "valu": [0, 1, 2, 3, 4, 5, 6, 10, 11, 12, 13, 15, 16, 17, 18, 19, 21], "var": 21, "var_opt_sketch": [20, 21], "var_opt_union": 21, "variabl": [6, 18], "varianc": [14, 20], "variant": [3, 6, 7], "varopt": [14, 19, 20], "vector": [10, 16, 17, 18, 22], "veri": [4, 6, 16, 17], "version": [1, 6, 7, 12, 15, 16, 17, 18], "vesel\u00fd": 18, "via": 18, "view": 16, "visibl": 18, "w": 6, "warmup": 1, "we": [6, 11, 16, 18], "weight": [5, 6, 7, 16, 17, 18, 19, 20, 21], "well": [0, 2, 15, 21], "were": [2, 6, 16, 17], "what": [6, 15], "when": [0, 1, 3, 4, 5, 8, 13, 15, 16, 17, 18, 21], "where": [1, 6, 12, 13, 16, 19], "whether": [1, 3, 4, 18], "which": [2, 3, 4, 5, 6, 7, 10, 12, 15, 16, 17, 18], "while": [2, 3], "whose": 7, "wiki": 11, "wikipedia": 11, "win": 0, "within": [5, 8], "work": [2, 17, 18], "wors": 16, "worst": 6, "would": 6, "written": [12, 18], "x": [5, 16], "y": [16, 19], "year": 6, "yield": 16, "you": 17, "zero": 16, "zohar": [18, 22]}, "titles": ["Compressed Probabilistic Counting (CPC)", "HyperLogLog (HLL)", "Distinct Counting", "Theta Sketch", "Tuple Sketch", "CountMin Sketch", "Frequent Items", "Frequency Sketches", "Helper Classes", "Jaccard Similarity", "Kernel Function", "Kolmogorov-Smirnov Test", "Serialize/Deserialize (SerDe)", "Tuple Policy", "Apache DataSketches", "Quantiles Sketches", "KLL Sketch", "Quantiles Sketch (Deprecated)", "Relative Error Quantiles (REQ) Sketch", "Exact and Bounded, Probabilitiy Proportional to Size (EBPPS) Sampling", "Random Sampling Sketches", "Variance Optimal Sampling (VarOpt)", "Density Sketch", "Vector Sketches"], "titleterms": {"apach": 14, "bound": 19, "class": [8, 14], "compress": 0, "count": [0, 2, 14], "countmin": 5, "cpc": 0, "datasketch": 14, "densiti": 22, "deprec": 17, "deseri": 12, "distinct": [2, 14], "ebpp": 19, "error": 18, "estim": 14, "exact": 19, "frequenc": [7, 14], "frequent": 6, "function": 10, "helper": [8, 14], "hll": 1, "hyperloglog": 1, "indic": 14, "item": 6, "jaccard": 9, "kernel": 10, "kll": 16, "kolmogorov": 11, "optim": 21, "polici": 13, "probabilist": 0, "probabilitii": 19, "proport": 19, "quantil": [14, 15, 17, 18], "random": [14, 20], "rel": 18, "req": 18, "sampl": [14, 19, 20, 21], "serd": 12, "serial": 12, "similar": 9, "size": 19, "sketch": [3, 4, 5, 7, 14, 15, 16, 17, 18, 20, 22, 23], "smirnov": 11, "tabl": 14, "test": 11, "theta": 3, "tupl": [4, 13], "varianc": 21, "varopt": 21, "vector": [14, 23]}}) \ No newline at end of file diff --git a/docs/5.1.0/vector/density_sketch.html b/docs/5.1.0/vector/density_sketch.html new file mode 100644 index 00000000..51b650b1 --- /dev/null +++ b/docs/5.1.0/vector/density_sketch.html @@ -0,0 +1,248 @@ + + + + + + + Density Sketch — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Density Sketch

+

Builds a coreset from the given set of input points. +Provides density estimate at a given point.

+

Based on the following paper: Zohar Karnin, Edo Liberty +“Discrepancy, Coresets, and Sketches in Machine Learning” +https://proceedings.mlr.press/v99/karnin19a/karnin19a.pdf

+

Inspired by the following implementation: https://github.com/edoliberty/streaming-quantiles/blob/f688c8161a25582457b0a09deb4630a81406293b/gde.py

+

Requires the use of a KernelFunction to compute the distance between two vectors.

+
+
+class density_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, kernel: _datasketches.KernelFunction) _datasketches.density_sketch
+

Reads a bytes object and returns the corresponding density_sketch

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int, dim: int, kernel: _datasketches.KernelFunction) None
+

Creates a new density sketch

+
+
Parameters:
+
    +
  • k (int) – controls the size and error of the sketch

  • +
  • dim (int) – dimension of the input data

  • +
  • kernel (KernelFunction) – instance of a kernel

  • +
+
+
+
+ +
+
+property dim
+

The configured parameter dim

+
+ +
+
+get_estimate
+

Returns an approximate density at the given point

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Updates the sketch with the given vector

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.0/vector/index.html b/docs/5.1.0/vector/index.html new file mode 100644 index 00000000..808fefda --- /dev/null +++ b/docs/5.1.0/vector/index.html @@ -0,0 +1,135 @@ + + + + + + + Vector Sketches — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Vector Sketches

+

These sketches are designed to accept vector inputs. For now, the library provides only the +density_sketch for Kernel Density Estimation.

+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.1/.buildinfo b/docs/5.1.1/.buildinfo new file mode 100644 index 00000000..d6ebb969 --- /dev/null +++ b/docs/5.1.1/.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: 86d4b171ba47c51d1a3d7f924e02560f +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/docs/5.1.1/_sources/distinct_counting/cpc.rst.txt b/docs/5.1.1/_sources/distinct_counting/cpc.rst.txt new file mode 100644 index 00000000..6a28d387 --- /dev/null +++ b/docs/5.1.1/_sources/distinct_counting/cpc.rst.txt @@ -0,0 +1,32 @@ +Compressed Probabilistic Counting (CPC) +--------------------------------------- +High performance C++ implementation of Compressed Probabilistic Counting (CPC) Sketch. +This is a unique-counting sketch that implements the Compressed Probabilistic Counting (CPC, a.k.a FM85) algorithms developed by Kevin Lang in his paper +`Back to the Future: an Even More Nearly Optimal Cardinality Estimation Algorithm `_. +This sketch is extremely space-efficient when serialized. +In an apples-to-apples empirical comparison against compressed HyperLogLog sketches, this new algorithm simultaneously wins on the two dimensions of the space/accuracy tradeoff and produces sketches that are smaller than the entropy of HLL, so no possible implementation of compressed HLL can match its space efficiency for a given accuracy. As described in the paper this sketch implements a newly developed ICON estimator algorithm that survives unioning operations, another well-known estimator, the Historical Inverse Probability (HIP) estimator does not. +The update speed performance of this sketch is quite fast and is comparable to the speed of HLL. +The unioning (merging) capability of this sketch also allows for merging of sketches with different configurations of K. +For additional security this sketch can be configured with a user-specified hash seed. + + +.. autoclass:: _datasketches.cpc_sketch + :members: + :undoc-members: + :exclude-members: deserialize + + .. rubric:: Static Methods: + + .. automethod:: deserialize + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + + +.. autoclass:: _datasketches.cpc_union + :members: + :undoc-members: + :exclude-members: deserialize + + .. automethod:: __init__ diff --git a/docs/5.1.1/_sources/distinct_counting/hyper_log_log.rst.txt b/docs/5.1.1/_sources/distinct_counting/hyper_log_log.rst.txt new file mode 100644 index 00000000..287209b0 --- /dev/null +++ b/docs/5.1.1/_sources/distinct_counting/hyper_log_log.rst.txt @@ -0,0 +1,55 @@ +HyperLogLog (HLL) +----------------- +This is a high performance implementation of Phillipe Flajolet's HLL sketch but with significantly improved error behavior. + +If the ONLY use case for sketching is counting uniques and merging, the HLL sketch is a reasonable choice, although the highest performing in terms of accuracy for storage space consumed is CPC (Compressed Probabilistic Counting). For large enough counts, this HLL version (with HLL_4) can be 2 to 16 times smaller than the Theta sketch family for the same accuracy. + +This implementation offers three different types of HLL sketch, each with different trade-offs with accuracy, space and performance. +These types are specified with the target_hll_type parameter. + +In terms of accuracy, all three types, for the same lg_config_k, have the same error distribution as a function of ``n``, the number of unique values fed to the sketch. +The configuration parameter ``lg_config_k`` is the log-base-2 of ``k``, where ``k`` is the number of buckets or slots for the sketch. + +During warmup, when the sketch has only received a small number of unique items (up to about 10% of ``k``), this implementation leverages a new class of estimator algorithms with significantly better accuracy. + + +.. autoclass:: _datasketches.tgt_hll_type + + .. autoattribute:: HLL_4 + :annotation: : 4 bits per entry + + .. autoattribute:: HLL_6 + :annotation: : 6 bits per entry + + .. autoattribute:: HLL_8 + :annotation: : 8 bits per entry + + +.. autoclass:: _datasketches.hll_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_max_updatable_serialization_bytes, get_rel_err + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_max_updatable_serialization_bytes + .. automethod:: get_rel_err + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: _datasketches.hll_union + :members: + :undoc-members: + :exclude-members: get_rel_err + + .. rubric:: Static Methods: + + .. automethod:: get_rel_err + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + \ No newline at end of file diff --git a/docs/5.1.1/_sources/distinct_counting/index.rst.txt b/docs/5.1.1/_sources/distinct_counting/index.rst.txt new file mode 100644 index 00000000..f4038815 --- /dev/null +++ b/docs/5.1.1/_sources/distinct_counting/index.rst.txt @@ -0,0 +1,24 @@ +Distinct Counting +================= + +.. currentmodule:: datasketches + +Distinct counting is one of the earliest tasks to which sketches were applied. The concept is simple: +Provide an estimate of the number of unique elements in a set of data. One of the earliest solutions came +from Flajolet and Martin in 1985 with their seminal work +`Probabilistic counting Algorithms for Data Base Applications `_. + +The DataSketches library offers several types of distinct counting sketches, each with different properties. + + * :class:`hll_sketch`: Hyper Log Log, a well-known sketch for distinct counting but no longer state-of-the-art. + * :class:`cpc_sketch`: Provides a better accuracy-space trade-off than HLL, but with a somewhat larger footprint while in-memory. + * :class:`theta_sketch`: Theta sketch, a type of k-minimum value sketch, which provide good performance with intersection and set difference operations. + * :class:`tuple_sketch`: Tuple sketch, which is similar to a theta sketch but supports additional data stored with each key. + +.. toctree:: + :maxdepth: 1 + + hyper_log_log + cpc + theta + tuple \ No newline at end of file diff --git a/docs/5.1.1/_sources/distinct_counting/theta.rst.txt b/docs/5.1.1/_sources/distinct_counting/theta.rst.txt new file mode 100644 index 00000000..94951f96 --- /dev/null +++ b/docs/5.1.1/_sources/distinct_counting/theta.rst.txt @@ -0,0 +1,65 @@ +Theta Sketch +------------ + +.. currentmodule:: datasketches + +Theta sketches are used for distinct counting. + +The theta package contains the basic sketch classes that are members of the `Theta Sketch Framework `_. +There is a separate Tuple package for many of the sketches that are derived from the same algorithms defined in the Theta Sketch Framework paper. + +The *Theta Sketch* sketch is a space-efficient method for estimating cardinalities of sets. +It can also easily handle set operations (such as union, intersection, difference) while maintaining good accuracy. +Theta sketch is a practical variant of the K-Minimum Values sketch which avoids the need to sort the stored +hash values on every insertion to the sketch. +It has better error properties than the HyperLogLog sketch for set operations beyond the simple union. + +Set operations (union, intersection, A-not-B) are performed through the use of dedicated objects. + +Several `Jaccard similarity `_ +measures can be computed between theta sketches with the :class:`theta_jaccard_similarity` class. + +.. autoclass:: theta_sketch + :members: + :undoc-members: + +.. autoclass:: update_theta_sketch + :members: + :undoc-members: + + .. automethod:: __init__ + + +.. autoclass:: compact_theta_sketch + :members: + :undoc-members: + :exclude-members: deserialize + + .. rubric:: Static Methods: + + .. automethod:: deserialize + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + + +.. autoclass:: theta_union + :members: + :undoc-members: + + .. automethod:: __init__ + + +.. autoclass:: theta_intersection + :members: + :undoc-members: + + .. automethod:: __init__ + + +.. autoclass:: theta_a_not_b + :members: + :undoc-members: + + .. automethod:: __init__ diff --git a/docs/5.1.1/_sources/distinct_counting/tuple.rst.txt b/docs/5.1.1/_sources/distinct_counting/tuple.rst.txt new file mode 100644 index 00000000..e4a369f2 --- /dev/null +++ b/docs/5.1.1/_sources/distinct_counting/tuple.rst.txt @@ -0,0 +1,64 @@ +Tuple Sketch +------------ + +.. currentmodule:: datasketches + +Tuple sketches are an extension of Theta sketches, meaning they provide estimate of distinct counts, that +allow the keeping of arbitrary summaries associated with each retained key +(for example, a count for every key). The use of a :class:`tuple_sketch` requires a :class:`TuplePolicy` which +defines how summaries are created, updated, merged, or intersected. The library provides a few basic +examples of :class:`TuplePolicy` implementations, but the right custom summary and policy can allow very +complicated analysis to be performed quite easily. + +Set operations (union, intersection, A-not-B) are performed through the use of dedicated objects. + +Several `Jaccard similarity `_ +measures can be computed between theta sketches with the :class:`tuple_jaccard_similarity` class. + +.. note:: + Serializing and deserializing this sketch requires the use of a :class:`PyObjectSerDe`. + +.. autoclass:: tuple_sketch + :members: + :undoc-members: + +.. autoclass:: update_tuple_sketch + :members: + :undoc-members: + + .. automethod:: __init__ + + +.. autoclass:: compact_tuple_sketch + :members: + :undoc-members: + :exclude-members: deserialize + + .. rubric:: Static Methods: + + .. automethod:: deserialize + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + + +.. autoclass:: tuple_union + :members: + :undoc-members: + + .. automethod:: __init__ + + +.. autoclass:: tuple_intersection + :members: + :undoc-members: + + .. automethod:: __init__ + + +.. autoclass:: tuple_a_not_b + :members: + :undoc-members: + + .. automethod:: __init__ diff --git a/docs/5.1.1/_sources/frequency/count_min_sketch.rst.txt b/docs/5.1.1/_sources/frequency/count_min_sketch.rst.txt new file mode 100644 index 00000000..b53b02e4 --- /dev/null +++ b/docs/5.1.1/_sources/frequency/count_min_sketch.rst.txt @@ -0,0 +1,27 @@ +CountMin Sketch +--------------- + +The CountMin sketch, as described in Cormode and Muthukrishnan in +http://dimacs.rutgers.edu/~graham/pubs/papers/cm-full.pdf, +is used for approximate Frequency Estimation. +For an item :math:`x` with frequency :math:`f_x`, the sketch provides an estimate, :math:`\hat{f_x}`, +such that :math:`f_x \approx \hat{f_x}.` +The sketch guarantees that :math:`f_x \le \hat{f_x}` and provides a probabilistic upper bound which is dependent on the size parameters. +The sketch provides an estimate of the occurrence frequency for any queried item but, in contrast +to the Frequent Items Sketch, this sketch does not provide a list of +heavy hitters. + +.. currentmodule:: _datasketches + +.. autoclass:: count_min_sketch + :members: + :undoc-members: + :exclude-members: deserialize, suggest_num_buckets, suggest_num_hashes + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: suggest_num_buckets + .. automethod:: suggest_num_hashes + + .. rubric:: Non-static Methods: diff --git a/docs/5.1.1/_sources/frequency/frequent_items.rst.txt b/docs/5.1.1/_sources/frequency/frequent_items.rst.txt new file mode 100644 index 00000000..76d81f58 --- /dev/null +++ b/docs/5.1.1/_sources/frequency/frequent_items.rst.txt @@ -0,0 +1,120 @@ +Frequent Items +-------------- + +.. currentmodule:: datasketches + +This sketch is useful for tracking approximate frequencies of items (``object`` or ``string``) with optional associated +integer counts that are members of a multiset of such items. +The true frequency of an item is defined to be the sum of associated counts. + +This implementation provides the following capabilities: + +* Estimate the *frequency* of an item. +* Return *upper* and *lower bounds* of any item, such that the true frequency is always between the upper and lower bounds. +* Return a global *maximum error* that holds for all items in the stream. +* Return an array of frequent items that qualify either a *NO_FALSE_POSITIVES* or a *NO_FALSE_NEGATIVES* error type. +* *Merge* itself with another sketch object created from this class. +* *Serialize/Deserialize* to/from a byte array. + +**Space Usage** + +The sketch is initialized with a maximum map size, ``maxMapSize``, that specifies the maximum physical length of the internal hash map of the form ``(object item, int count)``. +The maximum map size is always a power of 2, defined through the variables ``lg_max_map_size``. + +The hash map starts at a very small size (8 entries) and grows as needed up to the specified maximum map size. + +Excluding external space required for the item objects, the internal memory space usage of this sketch is ``18 * mapSize`` bytes (assuming 8 bytes for each reference), +plus a small constant number of additional bytes. +The internal memory space usage of this sketch will never exceed ``18 * maxMapSize`` bytes, plus a small constant number of additional bytes. + +**Maximum Capacity of the Sketch** + +The ``LOAD_FACTOR`` for the hash map is internally set at :math:`75\%`, which means at any time the map capacity of ``(item, count)`` pairs is ``mapCap = 0.75 * mapSize``. +The maximum capacity of ``(item, count)`` pairs of the sketch is ``maxMapCap = 0.75 * maxMapSize``. + +**Updating the sketch with ``(item, count)`` pairs** + +If the item is found in the hash map, the mapped count field (the "counter") is incremented by the incoming count; otherwise, a new counter ``(item, count)`` pair is created. +If the number of tracked counters reaches the maximum capacity of the hash map, the sketch decrements all of the counters (by an approximately computed median) +and removes any non-positive counters. + +**Accuracy** + +If fewer than ``0.75 * maxMapSize`` different items are inserted into the sketch, the estimated frequencies returned by the sketch will be exact. + +The logic of the frequent items sketch is such that the stored counts and true counts are never too different. +More specifically, for any item, the sketch can return an estimate of the true frequency of item, along with upper and lower bounds on the frequency (that hold deterministically). + +For this implementation and for a specific active item, it is guaranteed that the true frequency will be between the Upper Bound (UB) and the Lower Bound (LB) computed for that item. +Specifically, ``(UB- LB) ≤ W * epsilon``, where :math:`W` denotes the sum of all item counts, and :math:`epsilon = 3.5/M`, where :math:`epsilon = M` is the maxMapSize. + +This is a worst-case guarantee that applies to arbitrary inputs. +For inputs typically seen in practice, ``(UB-LB)`` is usually much smaller. + +**Background** + +This code implements a variant of what is commonly known as the "Misra-Gries algorithm". +Variants of it were discovered and rediscovered and redesigned several times over the years: + +* *Finding repeated elements*, Misra, Gries, 1982 +* *Frequency estimation of Internet packet streams with limited space* Demaine, Lopez-Ortiz, Munro, 2002 +* *A simple algorithm for finding frequent elements in streams and bags* Karp, Shenker, Papadimitriou, 2003 +* *Efficient Computation of Frequent and Top-k Elements in Data Streams* Metwally, Agrawal, Abbadi, 2006 + + +For speed, we do employ some randomization that introduces a small probability that our proof of the worst-case bound might not apply to a given run. +However, we have ensured that this probability is extremely small. +For example, if the stream causes one table purge (rebuild), our proof of the worst-case bound applies with a probability of at least `1 - 1E-14`. +If the stream causes ``1E9`` purges, our proof applies with a probability of at least ``1 - 1E-5``. + +There are two flavors of Frequent Items Sketches, one with generic items (objects) and another specific to strings. +The string version is a legacy name from before the library supported generic objects and is retained +only for backwards compatibility. + +.. note:: + The :class:`frequent_items_sketch` uses an input object's ``__hash__`` and ``__eq__`` methods. + +.. note:: + Serializing and deserializing the :class:`frequent_items_sketch` requires the use of a :class:`PyObjectSerDe`. + +.. autoclass:: frequent_items_error_type + + .. autoattribute:: NO_FALSE_POSITIVES + :annotation: : Returns only true positives but may miss some heavy hitters. + + .. autoattribute:: NO_FALSE_NEGATIVES + :annotation: : Does not miss any heavy hitters but may return false positives. + + +.. autoclass:: frequent_items_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_epsilon_for_lg_size, get_apriori_error + :member-order: groupwise + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_epsilon_for_lg_size + .. automethod:: get_apriori_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + + +.. autoclass:: frequent_strings_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_epsilon_for_lg_size, get_apriori_error + :member-order: groupwise + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_epsilon_for_lg_size + .. automethod:: get_apriori_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ diff --git a/docs/5.1.1/_sources/frequency/index.rst.txt b/docs/5.1.1/_sources/frequency/index.rst.txt new file mode 100644 index 00000000..3cd3dfa5 --- /dev/null +++ b/docs/5.1.1/_sources/frequency/index.rst.txt @@ -0,0 +1,15 @@ +Frequency Sketches +================== + +Frequency estimation involves determining how often an item has been seen in a stream. The library currently +offers two types of sketches for frequency estimation, one of which has two closely-related variants. + + * :class:`frequent_items_sketch`: Identifies the *Top K* or *heavy hitters* in a stream, those items whose weight is above a certain percentage of the entire stream. Does not necessarily provide an estimate for most items outside the heavy hitters. + * :class:`frequent_strings_sketch`: Like the items version but containing snly strings (an implementation from before the library handled generic objects). + * :class:`count_min_sketch`: Provides an estimate for any item, regardless of relative weight, but does not maintain a list of the heaviest items. + +.. toctree:: + :maxdepth: 1 + + frequent_items + count_min_sketch \ No newline at end of file diff --git a/docs/5.1.1/_sources/helper/index.rst.txt b/docs/5.1.1/_sources/helper/index.rst.txt new file mode 100644 index 00000000..182b8e85 --- /dev/null +++ b/docs/5.1.1/_sources/helper/index.rst.txt @@ -0,0 +1,24 @@ +Helper Classes +============== + +.. currentmodule:: dataksetches + +These classes are required for certain sketches or specific +functionality within sketches. +Some of them are abstract base classes, but in those cases there is at +least one reference example of a concrete class. + + * :class:`serde` is used when serializing and deserializing sketches. + * :class:`jaccard` is used to compute the Jaccard similarity between pairs of theta or tuple sketches. + * :class:`tuple_policy` is required to use a :class:`tuple_sketch` by specifying how summaries are combined. + * :func:`ks_test` performs a Kolmogorov-Smirnov test on absolute-error quantiles family sketches. + * :class:`kernel_function` is required when using a :class:`kernel_sketch` for Kernel Density Estimation. + +.. toctree:: + :maxdepth: 1 + + serde + jaccard + tuple_policy + ks_test + kernel diff --git a/docs/5.1.1/_sources/helper/jaccard.rst.txt b/docs/5.1.1/_sources/helper/jaccard.rst.txt new file mode 100644 index 00000000..d3b9bfa3 --- /dev/null +++ b/docs/5.1.1/_sources/helper/jaccard.rst.txt @@ -0,0 +1,23 @@ +Jaccard Similarity +################## + +.. currentmodule:: datasketches + +These objects provide measures related to the `Jaccard similarity `_ +of :class:`theta_sketch` and :class:`tuple_sketch` objects. + +Note that there are separate classes to be used for theta and tuple sketches. + +.. autoclass:: theta_jaccard_similarity + + .. automethod:: jaccard + .. automethod:: exactly_equal + .. automethod:: similarity_test + .. automethod:: dissimilarity_test + +.. autoclass:: tuple_jaccard_similarity + + .. automethod:: jaccard + .. automethod:: exactly_equal + .. automethod:: similarity_test + .. automethod:: dissimilarity_test diff --git a/docs/5.1.1/_sources/helper/kernel.rst.txt b/docs/5.1.1/_sources/helper/kernel.rst.txt new file mode 100644 index 00000000..bdc2c729 --- /dev/null +++ b/docs/5.1.1/_sources/helper/kernel.rst.txt @@ -0,0 +1,21 @@ +Kernel Function +############### + +.. currentmodule:: datasketches + +A `kernel function `_ is a specific type of +mathematical funciton that is particularly useful in certain machine learning and pattern recognition +contexts. The :class:`density_sketch` performs approximate +`kernel density estimation `_ which, unsurprisingly, +relies on the use of such a kernel function. + +The library provides an abstract base class :class:`KernelFunction` and an example implementation of a +Gaussian (also known as a Radial Basis Function) kernel. Custom classes must override the base class +and provide a floating point value as a score indicating the similarity of two input vectors. + +.. autoclass:: KernelFunction + + .. automethod:: __call__ + +.. autoclass:: GaussianKernel + :show-inheritance: \ No newline at end of file diff --git a/docs/5.1.1/_sources/helper/ks_test.rst.txt b/docs/5.1.1/_sources/helper/ks_test.rst.txt new file mode 100644 index 00000000..c9bc19b0 --- /dev/null +++ b/docs/5.1.1/_sources/helper/ks_test.rst.txt @@ -0,0 +1,14 @@ +Kolmogorov-Smirnov Test +####################### + +.. currentmodule:: datasketches + +A `Kolmogorov-Smirnov Test `_` is +a test of equality of two distributions to determine if they are likely to have come from the same +underlying distribution. +The DataSketches library provides a modified form of the test that takes into account the error +in each underlying sketch in the analysis. + +Currently, the test assumes both input sketches are of the same family and data type. + +.. autofunction:: ks_test diff --git a/docs/5.1.1/_sources/helper/serde.rst.txt b/docs/5.1.1/_sources/helper/serde.rst.txt new file mode 100644 index 00000000..ccac1d84 --- /dev/null +++ b/docs/5.1.1/_sources/helper/serde.rst.txt @@ -0,0 +1,34 @@ +Serialize/Deserialize (SerDe) +############################# + +.. currentmodule:: datasketches + +A SerDe is a class used to serialize items sketches to a :class:`bytes` object in binary. +Several example SerDes are provided as references. + +The use of binary-compatible SerDes in different languages is critical for cross-language compatibility. + +Each implementation must extend the :class:`PyObjectSerDe` class and override all three of its methods. + +.. autoclass:: PyObjectSerDe + + .. automethod:: get_size + .. automethod:: to_bytes + .. automethod:: from_bytes + + +The provided SerDes are: + +.. autoclass:: PyStringsSerDe + :show-inheritance: + +.. autoclass:: PyIntsSerDe + :show-inheritance: + +.. autoclass:: PyLongsSerDe + :show-inheritance: + +.. autoclass:: PyFloatsSerDe + :show-inheritance: + +.. autoclass:: PyDoublesSerDe diff --git a/docs/5.1.1/_sources/helper/tuple_policy.rst.txt b/docs/5.1.1/_sources/helper/tuple_policy.rst.txt new file mode 100644 index 00000000..3f5781f2 --- /dev/null +++ b/docs/5.1.1/_sources/helper/tuple_policy.rst.txt @@ -0,0 +1,25 @@ +Tuple Policy +############ + +.. currentmodule:: datasketches + +A Tuple Policy is needed when using a :class:`tuple_sketch` in order to specify how the +summary values should be created, updated, combined, or intersected. A summary can consist of +any python object. + +Each implementation must extend the abstract base class :class:`TuplePolicy`. + +.. autoclass:: TuplePolicy + + .. automethod:: create_summary + .. automethod:: update_summary + .. automethod:: __call__ + +.. autoclass:: AccumulatorPolicy + :show-inheritance: + +.. autoclass:: MinIntPolicy + :show-inheritance: + +.. autoclass:: MaxIntPolicy + :show-inheritance: diff --git a/docs/5.1.1/_sources/index.rst.txt b/docs/5.1.1/_sources/index.rst.txt new file mode 100644 index 00000000..b683e1fd --- /dev/null +++ b/docs/5.1.1/_sources/index.rst.txt @@ -0,0 +1,73 @@ +.. datasketches documentation master file, created by + sphinx-quickstart on Tue Jul 25 11:04:59 2023. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Apache DataSketches +================================================= + +**DataSketches** are highly-efficient algorithms to analyze big data quickly. + + +Counting Distincts +################## +.. + maxdepth: 1 means only the heading is printed in the contents +.. toctree:: + :maxdepth: 2 + + distinct_counting/index + +Quantile Estimation +################### + +.. toctree:: + :maxdepth: 2 + + quantiles/index + +Frequency Sketches +################## +This problem may also be known as **heavy hitters** or **TopK** + +.. toctree:: + :maxdepth: 2 + + frequency/index + +Vector Sketches +############### + +.. toctree:: + :maxdepth: 2 + + vector/index + + +Random Sampling +############### + +.. toctree:: + :maxdepth: 2 + + sampling/index + +Helper Classes +############## + +.. toctree:: + :maxdepth: 2 + + helper/index + + +.. note:: + + This project is under active development. + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/docs/5.1.1/_sources/quantiles/index.rst.txt b/docs/5.1.1/_sources/quantiles/index.rst.txt new file mode 100644 index 00000000..b1928f67 --- /dev/null +++ b/docs/5.1.1/_sources/quantiles/index.rst.txt @@ -0,0 +1,26 @@ +Quantiles Sketches +================== + +Quantile estimation is useful for understanding the distribution of data values in a stream. The sketches currently +in the library are designed to answer queries about the `rank` of an item in the stream of items. That is, when +applying a global ordering on all the items, what is the portion of items seen so far that are less than (alternatively, +less-than-or-equal-to) the given item. Using straightforward logic, they can also estimate the item at a given rank +in the stream. + +These sketches may be used to compute approximate histograms, Probability Mass Functions (PMFs), or +Cumulative Distribution Functions (CDFs). + +The library provides three types of quantiles sketches, each of which has generic items as well as versions +specific to a given numeric type (e.g. integer or floating point values). All three types provide error +bounds on rank estimation with proven probabilistic error distributions. + + * KLL: Provides uniform rank estimation error over the entire range + * REQ: Provides relative rank error estimates, which decreases approaching either the high or low end values. + * Classic quantiles: Largely deprecated in favor of KLL, also provides uniform rank estimation error. Included largely for backwards compatibility with historic data. + +.. toctree:: + :maxdepth: 1 + + kll + req + quantiles_depr \ No newline at end of file diff --git a/docs/5.1.1/_sources/quantiles/kll.rst.txt b/docs/5.1.1/_sources/quantiles/kll.rst.txt new file mode 100644 index 00000000..0e54b443 --- /dev/null +++ b/docs/5.1.1/_sources/quantiles/kll.rst.txt @@ -0,0 +1,171 @@ +KLL Sketch +---------- + +.. currentmodule:: datasketches + +Implementation of a very compact quantiles sketch with lazy compaction scheme +and nearly optimal accuracy per retained item. +See `Optimal Quantile Approximation in Streams`. + +This is a stochastic streaming sketch that enables near real-time analysis of the +approximate distribution of items from a very large stream in a single pass, requiring only +that the items are comparable. +The analysis is obtained using `get_quantile()` function or the +inverse functions `get_rank()`, `get_pmf()` (Probability Mass Function), and `get_cdf()` +(Cumulative Distribution Function). + +As of May 2020, this implementation produces serialized sketches which are binary-compatible +with the equivalent Java implementation only when template parameter `T = float` +(32-bit single precision values). + +Given an input stream of `N` items, the `natural rank` of any specific +item is defined as its index `(1 to N)` in inclusive mode +or `(0 to N-1)` in exclusive mode +in the hypothetical sorted stream of all `N` input items. + +The `normalized rank` (`rank`) of any specific item is defined as its +`natural rank` divided by `N`. +Thus, the `normalized rank` is between zero and one. +In the documentation for this sketch `natural rank` is never used so any +reference to just `rank` should be interpreted to mean `normalized rank`. + +This sketch is configured with a parameter `k`, which affects the size of the sketch +and its estimation error. + +The estimation error is commonly called `epsilon` (or `eps`) and is a fraction +between zero and one. Larger values of `k` result in smaller values of `epsilon`. +Epsilon is always with respect to the rank and cannot be applied to the +corresponding items. + +The relationship between the `normalized rank` and the corresponding items can be viewed +as a two-dimensional monotonic plot with the `normalized rank` on one axis and the +corresponding items on the other axis. If the y-axis is specified as the item-axis and +the x-axis as the `normalized rank`, then `y = get_quantile(x)` is a monotonically +increasing function. + +The function `get_quantile(rank)` translates ranks into +corresponding quantiles. The functions `get_rank(item)`, +`get_cdf(...)` (Cumulative Distribution Function), and `get_pmf(...)` +(Probability Mass Function) perform the opposite operation and translate items into ranks. + +The `get_pmf(...)` function has about 13 to 47% worse rank error (depending +on `k`) than the other queries because the mass of each "bin" of the PMF has +"double-sided" error from the upper and lower edges of the bin as a result of a subtraction, +as the errors from the two edges can sometimes add. + +The default `k` of 200 yields a "single-sided" `epsilon` of about 1.33% and a +"double-sided" (PMF) `epsilon` of about 1.65%. + +A `get_quantile(rank)` query has the following guarantees: +- Let `q = get_quantile(r)` where `r` is the rank between zero and one. +- The quantile `q` will be an item from the input stream. +- Let `true_rank` be the true rank of `q` derived from the hypothetical sorted +stream of all `N` items. +- Let `eps = get_normalized_rank_error(false)`. +- Then `r - eps ≤ true_rank ≤ r + eps` with a confidence of 99%. Note that the +error is on the rank, not the quantile. + +A `get_rank(item)` query has the following guarantees: +- Let `r = get_rank(i)` where `i` is an item between the min and max items of +the input stream. +- Let `true_rank` be the true rank of `i` derived from the hypothetical sorted +stream of all `N` items. +- Let `eps = get_normalized_rank_error(false)`. +- Then `r - eps ≤ true_rank ≤ r + eps` with a confidence of 99%. + +A `get_pmf()` query has the following guarantees: +- Let `{r1, r2, ..., r(m+1)} = get_pmf(s1, s2, ..., sm)` where `s1, s2` are +split points (items from the input domain) between the min and max items of +the input stream. +- Let `mass_i = estimated mass between s_i and s_i+1`. +- Let `true_mass` be the true mass between the items of `s_i`, +`s_i+1` derived from the hypothetical sorted stream of all `N` items. +- Let `eps = get_normalized_rank_error(true)`. +- then `mass - eps ≤ true_mass ≤ mass + eps` with a confidence of 99%. +- `r(m+1)` includes the mass of all points larger than `s_m`. + +A `get_cdf(...)` query has the following guarantees; +- Let `{r1, r2, ..., r(m+1)} = get_cdf(s1, s2, ..., sm)` where `s1, s2, ...` are +split points (items from the input domain) between the min and max items of +the input stream. +- Let `mass_i = r_(i+1) - r_i`. +- Let `true_mass` be the true mass between the true ranks of `s_i`, +`s_i+1` derived from the hypothetical sorted stream of all `N` items. +- Let `eps = get_normalized_rank_error(true)`. +- then `mass - eps ≤ true_mass ≤ mass + eps` with a confidence of 99%. +- `1 - r(m+1)` includes the mass of all points larger than `s_m`. + +From the above, it might seem like we could make some estimates to bound the +`item` returned from a call to `get_quantile()`. The sketch, however, does not +let us derive error bounds or confidences around items. Because errors are independent, we +can approximately bracket a value as shown below, but there are no error estimates available. +Additionally, the interval may be quite large for certain distributions. +- Let `q = get_quantile(r)`, the estimated quantile of rank `r`. +- Let `eps = get_normalized_rank_error(false)`. +- Let `q_lo = estimated quantile of rank (r - eps)`. +- Let `q_hi = estimated quantile of rank (r + eps)`. +- Then `q_lo ≤ q ≤ q_hi`, with 99% confidence. + +.. note:: + For the :class:`kll_items_sketch`, objects must be comparable with ``__lt__``. + +.. note:: + Serializing and deserializing a :class:`kll_items_sketch` requires the use of a :class:`PyObjectSerDe`. + + +.. autoclass:: kll_ints_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_normalized_rank_error + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_normalized_rank_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: kll_floats_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_normalized_rank_error + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_normalized_rank_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: kll_doubles_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_normalized_rank_error + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_normalized_rank_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: kll_items_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_normalized_rank_error + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_normalized_rank_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + diff --git a/docs/5.1.1/_sources/quantiles/quantiles_depr.rst.txt b/docs/5.1.1/_sources/quantiles/quantiles_depr.rst.txt new file mode 100644 index 00000000..18dd5df6 --- /dev/null +++ b/docs/5.1.1/_sources/quantiles/quantiles_depr.rst.txt @@ -0,0 +1,106 @@ +Quantiles Sketch (Deprecated) +----------------------------- + +.. currentmodule:: datasketches + +This is a deprecated quantiles sketch that is included for cross-language compatibility. +Most new projects will favor the KLL sketch over this one, or the REQ sketch for higher accuracy +at the very edge of a distribution. + +This is a stochastic streaming sketch that enables near-real time analysis of the +approximate distribution from a very large stream in a single pass. +The analysis is obtained using `get_rank()` and `get_quantile()` functions, +the Probability Mass Function from `get_pmf()`` and the Cumulative Distribution Function from `get_cdf`. + +Consider a large stream of one million values such as packet sizes coming into a network node. +The natural rank of any specific size value is its index in the hypothetical sorted +array of values. +The normalized rank is the natural rank divided by the stream size, +in this case one million. +The value corresponding to the normalized rank of `0.5` represents the 50th percentile or median +value of the distribution, or `get_quantile(0.5)`. +Similarly, the 95th percentile is obtained from `get_quantile(0.95)`. + +From the min and max values, for example, 1 and 1000 bytes, +you can obtain the PMF from `get_pmf(100, 500, 900)` that will result in an array of +4 fractional values such as {.4, .3, .2, .1}, which means that +40% of the values were < 100, +30% of the values were ≥ 100 and < 500, +20% of the values were ≥ 500 and < 900, and +10% of the values were ≥ 900. +A frequency histogram can be obtained by multiplying these fractions by `get_n()`, +which is the total count of values received. +The `get_cdf()`` works similarly, but produces the cumulative distribution instead. + +As of November 2021, this implementation produces serialized sketches which are binary-compatible +with the equivalent Java implementation only when template parameter T = double +(64-bit double precision values). + +The accuracy of this sketch is a function of the configured value `k`, which also affects +the overall size of the sketch. Accuracy of this quantile sketch is always with respect to +the normalized rank. A `k` of 128 produces a normalized, rank error of about 1.7%. +For example, the median item returned from `get_quantile(0.5)` will be between the actual items +from the hypothetically sorted array of input items at normalized ranks of 0.483 and 0.517, with +a confidence of about 99%. + +.. note:: + For the :class:`quantiles_items_sketch`, objects must be comparable with ``__lt__``. + +.. note:: + Serializing and deserializing a :class:`quantiles_items_sketch` requires the use of a :class:`PyObjectSerDe`. + +.. autoclass:: quantiles_ints_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_normalized_rank_error + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_normalized_rank_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: quantiles_floats_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_normalized_rank_error + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_normalized_rank_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: quantiles_doubles_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_normalized_rank_error + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_normalized_rank_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: quantiles_items_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_normalized_rank_error + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_normalized_rank_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ diff --git a/docs/5.1.1/_sources/quantiles/req.rst.txt b/docs/5.1.1/_sources/quantiles/req.rst.txt new file mode 100644 index 00000000..3f63e01e --- /dev/null +++ b/docs/5.1.1/_sources/quantiles/req.rst.txt @@ -0,0 +1,79 @@ +Relative Error Quantiles (REQ) Sketch +------------------------------------- + +.. currentmodule:: datasketches + +This is an implementation based on the `paper `_ "Relative Error Streaming Quantiles" by Graham Cormode, Zohar Karnin, Edo Liberty, Justin Thaler, Pavel Veselý, and loosely derived from a Python prototype written by Pavel Veselý. + +This implementation differs from the algorithm described in the paper in the following: + +The algorithm requires no upper bound on the stream length. +Instead, each relative-compactor counts the number of compaction operations performed so far (via variable state). +Initially, the relative-compactor starts with `INIT_NUMBER_OF_SECTIONS`. +Each time the number of compactions `(variable state) exceeds 2^{numSections - 1}`, we double `numSections`. +Note that after merging the sketch with another one variable state may not correspond to the number of compactions performed at a particular level, however, +since the state variable never exceeds the number of compactions, the guarantees of the sketch remain valid. + +The size of each section (variable `k` and `section_size` in the code and parameter `k` in the paper) is +initialized with a number set by the user via variable `k`. +When the number of sections doubles, we decrease section_size by a factor of `sqrt(2)`. +This is applied at each level separately. +Thus, when we double the number of sections, the nominal compactor size increases by a factor of approx. `sqrt(2) (+/- rounding)`. + +The merge operation here does not perform "special compactions", which are used in the paper to allow for a tight mathematical analysis of the sketch. +This implementation provides a number of capabilities not discussed in the paper or provided in the Python prototype. + +The Python prototype only implemented high accuracy for low ranks. This implementation provides the user with the ability to +choose either high rank accuracy or low rank accuracy at the time of sketch construction. +The Python prototype only implemented a comparison criterion of `INCLUSIVE`. +This implementation allows the user to use both the `INCLUSIVE` criterion and the `EXCLUSIVE` criterion. +This implementation provides extensive debug visibility into the operation of the sketch with two levels of detail output. +This is not only useful for debugging, but is a powerful tool to help users understand how the sketch works. + +.. note:: + For the :class:`req_items_sketch`, objects must be comparable with ``__lt__``. + +.. note:: + Serializing and deserializing a :class:`req_items_sketch` requires the use of a :class:`PyObjectSerDe`. + +.. autoclass:: req_ints_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_RSE + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_RSE + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: req_floats_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_RSE + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_RSE + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: req_items_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_RSE + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_RSE + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ diff --git a/docs/5.1.1/_sources/sampling/ebpps.rst.txt b/docs/5.1.1/_sources/sampling/ebpps.rst.txt new file mode 100644 index 00000000..b2253209 --- /dev/null +++ b/docs/5.1.1/_sources/sampling/ebpps.rst.txt @@ -0,0 +1,33 @@ +Exact and Bounded, Probabilitiy Proportional to Size (EBPPS) Sampling +--------------------------------------------------------------------- + +.. currentmodule:: datasketches + +An EBPPS sketch produces a randome sample of data from a stream of items, ensuring that the probability +of including an item is always exactly equal to the item's size. The size of an item is defined as its +weight relative to the total weight of all items seen so far by the sketch. In contrast to VarOpt sampling, +this sketch may return fewer than `k` items in order to keep the probability of including an item strictly +proportional to its size. + +This sketch is based on: B. Hentschel, P. J. Haas, Y. Tian +"Exact PPS Sampling with Bounded Sample Size", +Information Processing Letters, 2023. + +EBPPS sampling is related to reservoir sampling, but handles unequal item weights. +Feeding the sketch items with a uniform weight value will produce a sample equivalent to reservoir sampling. + +.. note:: + Serializing and deserializing this sketch requires the use of a :class:`PyObjectSerDe`. + +.. autoclass:: ebpps_sketch + :members: + :undoc-members: + :exclude-members: deserialize + + .. rubric:: Static Methods: + + .. automethod:: deserialize + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ diff --git a/docs/5.1.1/_sources/sampling/index.rst.txt b/docs/5.1.1/_sources/sampling/index.rst.txt new file mode 100644 index 00000000..fca6c3ce --- /dev/null +++ b/docs/5.1.1/_sources/sampling/index.rst.txt @@ -0,0 +1,21 @@ +Random Sampling Sketches +======================== + +.. currentmodule:: datasketches + +These sketches are used to randomly sample items. The length of the input +stream does not need to be known in advance. + +Both VarOpt (Variance Optimal) and EBPPS (Exact and Bounded, +Probability Proportional to Size) sketches will include sample items based on +each item's weight relative to the weight of the entire stream but +they differ in details: + + * :class:`ebpps_sketch` ensures that the probability of including an item is always exactly proportional to the item's weight. + * :class:`var_opt_sketch` optimizes for applying a predicate to the resulting sample such that the variance of the subset sum after applying the predicate is minimized, even if the inclusion probability differs somewhat from being proportional to the item's weight. + +.. toctree:: + :maxdepth: 1 + + varopt + ebpps diff --git a/docs/5.1.1/_sources/sampling/varopt.rst.txt b/docs/5.1.1/_sources/sampling/varopt.rst.txt new file mode 100644 index 00000000..d837835e --- /dev/null +++ b/docs/5.1.1/_sources/sampling/varopt.rst.txt @@ -0,0 +1,42 @@ +Variance Optimal Sampling (VarOpt) +---------------------------------- + +.. currentmodule:: datasketches + +A VarOpt sketch samples data from a stream of items. The sketch is desinged for optimal (minimum) +variance when querying the sketch to estimate subset sums of items matching a provided predicate. +The sketch will produce a sample of size `k` (or smaller if fewer items have been presented), with +the probability of including an item roughly corresponding it the item's weight relative to the total +weight of all items presented to the sketch. + +VarOpt sampling is related to reservoir sampling, with improved error bounds for subset sum estimation. +Feeding the sketch items with a uniform weight value will produce a sample equivalent to reservoir sampling. + +.. note:: + Serializing and deserializing this sketch requires the use of a :class:`PyObjectSerDe`. + +.. autoclass:: var_opt_sketch + :members: + :undoc-members: + :exclude-members: deserialize + + .. rubric:: Static Methods: + + .. automethod:: deserialize + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: var_opt_union + :members: + :undoc-members: + :exclude-members: deserialize + + .. rubric:: Static Methods: + + .. automethod:: deserialize + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ diff --git a/docs/5.1.1/_sources/vector/density_sketch.rst.txt b/docs/5.1.1/_sources/vector/density_sketch.rst.txt new file mode 100644 index 00000000..07d83181 --- /dev/null +++ b/docs/5.1.1/_sources/vector/density_sketch.rst.txt @@ -0,0 +1,28 @@ +Density Sketch +-------------- + +.. currentmodule:: datasketches + +Builds a coreset from the given set of input points. +Provides density estimate at a given point. + +Based on the following paper: Zohar Karnin, Edo Liberty +"Discrepancy, Coresets, and Sketches in Machine Learning" +https://proceedings.mlr.press/v99/karnin19a/karnin19a.pdf + +Inspired by the following implementation: https://github.com/edoliberty/streaming-quantiles/blob/f688c8161a25582457b0a09deb4630a81406293b/gde.py + +Requires the use of a :class:`KernelFunction` to compute the distance between two vectors. + +.. autoclass:: density_sketch + :members: + :undoc-members: + :exclude-members: deserialize + + .. rubric:: Static Methods: + + .. automethod:: deserialize + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ diff --git a/docs/5.1.1/_sources/vector/index.rst.txt b/docs/5.1.1/_sources/vector/index.rst.txt new file mode 100644 index 00000000..1b83a43c --- /dev/null +++ b/docs/5.1.1/_sources/vector/index.rst.txt @@ -0,0 +1,12 @@ +Vector Sketches +================== + +.. currentmodule:: dataksetches + +These sketches are designed to accept vector inputs. For now, the library provides only the +:class:`density_sketch` for Kernel Density Estimation. + +.. toctree:: + :maxdepth: 1 + + density_sketch \ No newline at end of file diff --git a/docs/5.1.1/_static/_sphinx_javascript_frameworks_compat.js b/docs/5.1.1/_static/_sphinx_javascript_frameworks_compat.js new file mode 100644 index 00000000..81415803 --- /dev/null +++ b/docs/5.1.1/_static/_sphinx_javascript_frameworks_compat.js @@ -0,0 +1,123 @@ +/* Compatability shim for jQuery and underscores.js. + * + * Copyright Sphinx contributors + * Released under the two clause BSD licence + */ + +/** + * small helper function to urldecode strings + * + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL + */ +jQuery.urldecode = function(x) { + if (!x) { + return x + } + return decodeURIComponent(x.replace(/\+/g, ' ')); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s === 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node, addItems) { + if (node.nodeType === 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && + !jQuery(node.parentNode).hasClass(className) && + !jQuery(node.parentNode).hasClass("nohighlight")) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.className = className; + } + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + if (isInSVG) { + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + var bbox = node.parentElement.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": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} diff --git a/docs/5.1.1/_static/basic.css b/docs/5.1.1/_static/basic.css new file mode 100644 index 00000000..7ebbd6d0 --- /dev/null +++ b/docs/5.1.1/_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/docs/5.1.1/_static/css/badge_only.css b/docs/5.1.1/_static/css/badge_only.css new file mode 100644 index 00000000..88ba55b9 --- /dev/null +++ b/docs/5.1.1/_static/css/badge_only.css @@ -0,0 +1 @@ +.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions .rst-other-versions .rtd-current-item{font-weight:700}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}#flyout-search-form{padding:6px} \ No newline at end of file diff --git a/docs/5.1.1/_static/css/fonts/Roboto-Slab-Bold.woff b/docs/5.1.1/_static/css/fonts/Roboto-Slab-Bold.woff new file mode 100644 index 00000000..6cb60000 Binary files /dev/null and b/docs/5.1.1/_static/css/fonts/Roboto-Slab-Bold.woff differ diff --git a/docs/5.1.1/_static/css/fonts/Roboto-Slab-Bold.woff2 b/docs/5.1.1/_static/css/fonts/Roboto-Slab-Bold.woff2 new file mode 100644 index 00000000..7059e231 Binary files /dev/null and b/docs/5.1.1/_static/css/fonts/Roboto-Slab-Bold.woff2 differ diff --git a/docs/5.1.1/_static/css/fonts/Roboto-Slab-Regular.woff b/docs/5.1.1/_static/css/fonts/Roboto-Slab-Regular.woff new file mode 100644 index 00000000..f815f63f Binary files /dev/null and b/docs/5.1.1/_static/css/fonts/Roboto-Slab-Regular.woff differ diff --git a/docs/5.1.1/_static/css/fonts/Roboto-Slab-Regular.woff2 b/docs/5.1.1/_static/css/fonts/Roboto-Slab-Regular.woff2 new file mode 100644 index 00000000..f2c76e5b Binary files /dev/null and b/docs/5.1.1/_static/css/fonts/Roboto-Slab-Regular.woff2 differ diff --git a/docs/5.1.1/_static/css/fonts/fontawesome-webfont.eot b/docs/5.1.1/_static/css/fonts/fontawesome-webfont.eot new file mode 100644 index 00000000..e9f60ca9 Binary files /dev/null and b/docs/5.1.1/_static/css/fonts/fontawesome-webfont.eot differ diff --git a/docs/5.1.1/_static/css/fonts/fontawesome-webfont.svg b/docs/5.1.1/_static/css/fonts/fontawesome-webfont.svg new file mode 100644 index 00000000..855c845e --- /dev/null +++ b/docs/5.1.1/_static/css/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/5.1.1/_static/css/fonts/fontawesome-webfont.ttf b/docs/5.1.1/_static/css/fonts/fontawesome-webfont.ttf new file mode 100644 index 00000000..35acda2f Binary files /dev/null and b/docs/5.1.1/_static/css/fonts/fontawesome-webfont.ttf differ diff --git a/docs/5.1.1/_static/css/fonts/fontawesome-webfont.woff b/docs/5.1.1/_static/css/fonts/fontawesome-webfont.woff new file mode 100644 index 00000000..400014a4 Binary files /dev/null and b/docs/5.1.1/_static/css/fonts/fontawesome-webfont.woff differ diff --git a/docs/5.1.1/_static/css/fonts/fontawesome-webfont.woff2 b/docs/5.1.1/_static/css/fonts/fontawesome-webfont.woff2 new file mode 100644 index 00000000..4d13fc60 Binary files /dev/null and b/docs/5.1.1/_static/css/fonts/fontawesome-webfont.woff2 differ diff --git a/docs/5.1.1/_static/css/fonts/lato-bold-italic.woff b/docs/5.1.1/_static/css/fonts/lato-bold-italic.woff new file mode 100644 index 00000000..88ad05b9 Binary files /dev/null and b/docs/5.1.1/_static/css/fonts/lato-bold-italic.woff differ diff --git a/docs/5.1.1/_static/css/fonts/lato-bold-italic.woff2 b/docs/5.1.1/_static/css/fonts/lato-bold-italic.woff2 new file mode 100644 index 00000000..c4e3d804 Binary files /dev/null and b/docs/5.1.1/_static/css/fonts/lato-bold-italic.woff2 differ diff --git a/docs/5.1.1/_static/css/fonts/lato-bold.woff b/docs/5.1.1/_static/css/fonts/lato-bold.woff new file mode 100644 index 00000000..c6dff51f Binary files /dev/null and b/docs/5.1.1/_static/css/fonts/lato-bold.woff differ diff --git a/docs/5.1.1/_static/css/fonts/lato-bold.woff2 b/docs/5.1.1/_static/css/fonts/lato-bold.woff2 new file mode 100644 index 00000000..bb195043 Binary files /dev/null and b/docs/5.1.1/_static/css/fonts/lato-bold.woff2 differ diff --git a/docs/5.1.1/_static/css/fonts/lato-normal-italic.woff b/docs/5.1.1/_static/css/fonts/lato-normal-italic.woff new file mode 100644 index 00000000..76114bc0 Binary files /dev/null and b/docs/5.1.1/_static/css/fonts/lato-normal-italic.woff differ diff --git a/docs/5.1.1/_static/css/fonts/lato-normal-italic.woff2 b/docs/5.1.1/_static/css/fonts/lato-normal-italic.woff2 new file mode 100644 index 00000000..3404f37e Binary files /dev/null and b/docs/5.1.1/_static/css/fonts/lato-normal-italic.woff2 differ diff --git a/docs/5.1.1/_static/css/fonts/lato-normal.woff b/docs/5.1.1/_static/css/fonts/lato-normal.woff new file mode 100644 index 00000000..ae1307ff Binary files /dev/null and b/docs/5.1.1/_static/css/fonts/lato-normal.woff differ diff --git a/docs/5.1.1/_static/css/fonts/lato-normal.woff2 b/docs/5.1.1/_static/css/fonts/lato-normal.woff2 new file mode 100644 index 00000000..3bf98433 Binary files /dev/null and b/docs/5.1.1/_static/css/fonts/lato-normal.woff2 differ diff --git a/docs/5.1.1/_static/css/theme.css b/docs/5.1.1/_static/css/theme.css new file mode 100644 index 00000000..0f14f106 --- /dev/null +++ b/docs/5.1.1/_static/css/theme.css @@ -0,0 +1,4 @@ +html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden],audio:not([controls]){display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;text-decoration:none}ins,mark{color:#000}mark{background:#ff0;font-style:italic;font-weight:700}.rst-content code,.rst-content tt,code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:after,q:before{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,ol,ul{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure,form{margin:0}label{cursor:pointer}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{body,html,section{background:none!important}*{box-shadow:none!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}.rst-content .toctree-wrapper>p.caption,h2,h3,p{orphans:3;widows:3}.rst-content .toctree-wrapper>p.caption,h2,h3{page-break-after:avoid}}.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .eqno .headerlink:before,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .eqno .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a button.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-left.toctree-expand,.wy-menu-vertical li button.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .eqno .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a button.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-right.toctree-expand,.wy-menu-vertical li button.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .eqno .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a button.pull-left.toctree-expand,.wy-menu-vertical li.on a button.pull-left.toctree-expand,.wy-menu-vertical li button.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .eqno .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a button.pull-right.toctree-expand,.wy-menu-vertical li.on a button.pull-right.toctree-expand,.wy-menu-vertical li button.pull-right.toctree-expand{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li button.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content .eqno a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content p a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li a button.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content .eqno .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content p .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li button.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content .eqno .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a button.toctree-expand,.btn .wy-menu-vertical li.on a button.toctree-expand,.btn .wy-menu-vertical li button.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content .eqno .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a button.toctree-expand,.nav .wy-menu-vertical li.on a button.toctree-expand,.nav .wy-menu-vertical li button.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .eqno .btn .headerlink,.rst-content .eqno .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p .btn .headerlink,.rst-content p .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn button.toctree-expand,.wy-menu-vertical li.current>a .btn button.toctree-expand,.wy-menu-vertical li.current>a .nav button.toctree-expand,.wy-menu-vertical li .nav button.toctree-expand,.wy-menu-vertical li.on a .btn button.toctree-expand,.wy-menu-vertical li.on a .nav button.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .eqno .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li button.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .eqno .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li button.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .eqno .btn .fa-large.headerlink,.rst-content .eqno .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p .btn .fa-large.headerlink,.rst-content p .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn button.fa-large.toctree-expand,.wy-menu-vertical li .nav button.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .eqno .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li button.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .eqno .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li button.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .eqno .btn .fa-spin.headerlink,.rst-content .eqno .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p .btn .fa-spin.headerlink,.rst-content p .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn button.fa-spin.toctree-expand,.wy-menu-vertical li .nav button.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content .eqno .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li button.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content .eqno .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li button.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content .eqno .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li button.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content .eqno .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini button.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.rst-content section ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.rst-content section ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.rst-content section ul li p:last-child,.rst-content section ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.rst-content section ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.rst-content section ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.rst-content section ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content .section ol.arabic,.rst-content .toctree-wrapper ol,.rst-content .toctree-wrapper ol.arabic,.rst-content section ol,.rst-content section ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol.arabic li,.rst-content .section ol li,.rst-content .toctree-wrapper ol.arabic li,.rst-content .toctree-wrapper ol li,.rst-content section ol.arabic li,.rst-content section ol li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol.arabic li ul,.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content .toctree-wrapper ol.arabic li ul,.rst-content .toctree-wrapper ol li p:last-child,.rst-content .toctree-wrapper ol li ul,.rst-content section ol.arabic li ul,.rst-content section ol li p:last-child,.rst-content section ol li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol.arabic li ul li,.rst-content .section ol li ul li,.rst-content .toctree-wrapper ol.arabic li ul li,.rst-content .toctree-wrapper ol li ul li,.rst-content section ol.arabic li ul li,.rst-content section ol li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs>li{display:inline-block;padding-top:5px}.wy-breadcrumbs>li.wy-breadcrumbs-aside{float:right}.rst-content .wy-breadcrumbs>li code,.rst-content .wy-breadcrumbs>li tt,.wy-breadcrumbs>li .rst-content tt,.wy-breadcrumbs>li code{all:inherit;color:inherit}.breadcrumb-item:before{content:"/";color:#bbb;font-size:13px;padding:0 6px 0 3px}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li button.toctree-expand{display:block;float:left;margin-left:-1.2em;line-height:18px;color:#4d4d4d;border:none;background:none;padding:0}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover button.toctree-expand,.wy-menu-vertical li.on a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand{display:block;line-height:18px;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{padding:.4045em 1.618em .4045em 4.045em}.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{padding:.4045em 1.618em .4045em 5.663em}.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a{padding:.4045em 1.618em .4045em 7.281em}.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a{padding:.4045em 1.618em .4045em 8.899em}.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a{padding:.4045em 1.618em .4045em 10.517em}.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a{padding:.4045em 1.618em .4045em 12.135em}.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a{padding:.4045em 1.618em .4045em 13.753em}.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a{padding:.4045em 1.618em .4045em 15.371em}.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 1.618em .4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 button.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 button.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover button.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active button.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em;max-width:100%}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search .wy-dropdown>aactive,.wy-side-nav-search .wy-dropdown>afocus,.wy-side-nav-search>a:hover,.wy-side-nav-search>aactive,.wy-side-nav-search>afocus{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon,.wy-side-nav-search>a.icon{display:block}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.switch-menus{position:relative;display:block;margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-side-nav-search>div.switch-menus>div.language-switch,.wy-side-nav-search>div.switch-menus>div.version-switch{display:inline-block;padding:.2em}.wy-side-nav-search>div.switch-menus>div.language-switch select,.wy-side-nav-search>div.switch-menus>div.version-switch select{display:inline-block;margin-right:-2rem;padding-right:2rem;max-width:240px;text-align-last:center;background:none;border:none;border-radius:0;box-shadow:none;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-size:1em;font-weight:400;color:hsla(0,0%,100%,.3);cursor:pointer;appearance:none;-webkit-appearance:none;-moz-appearance:none}.wy-side-nav-search>div.switch-menus>div.language-switch select:active,.wy-side-nav-search>div.switch-menus>div.language-switch select:focus,.wy-side-nav-search>div.switch-menus>div.language-switch select:hover,.wy-side-nav-search>div.switch-menus>div.version-switch select:active,.wy-side-nav-search>div.switch-menus>div.version-switch select:focus,.wy-side-nav-search>div.switch-menus>div.version-switch select:hover{background:hsla(0,0%,100%,.1);color:hsla(0,0%,100%,.5)}.wy-side-nav-search>div.switch-menus>div.language-switch select option,.wy-side-nav-search>div.switch-menus>div.version-switch select option{color:#000}.wy-side-nav-search>div.switch-menus>div.language-switch:has(>select):after,.wy-side-nav-search>div.switch-menus>div.version-switch:has(>select):after{display:inline-block;width:1.5em;height:100%;padding:.1em;content:"\f0d7";font-size:1em;line-height:1.2em;font-family:FontAwesome;text-align:center;pointer-events:none;box-sizing:border-box}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .eqno .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content .eqno .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions .rst-other-versions .rtd-current-item{font-weight:700}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}#flyout-search-form{padding:6px}.rst-content .toctree-wrapper>p.caption,.rst-content h1,.rst-content h2,.rst-content h3,.rst-content h4,.rst-content h5,.rst-content h6{margin-bottom:24px}.rst-content img{max-width:100%;height:auto}.rst-content div.figure,.rst-content figure{margin-bottom:24px}.rst-content div.figure .caption-text,.rst-content figure .caption-text{font-style:italic}.rst-content div.figure p:last-child.caption,.rst-content figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center,.rst-content figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img,.rst-content section>a>img,.rst-content section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp,.rst-content div.highlight span.linenos{user-select:none;pointer-events:none}.rst-content div.highlight span.linenos{display:inline-block;padding-left:0;padding-right:12px;margin-right:12px;border-right:1px solid #e6e9ea}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li,.rst-content .toctree-wrapper ol.loweralpha,.rst-content .toctree-wrapper ol.loweralpha>li,.rst-content section ol.loweralpha,.rst-content section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li,.rst-content .toctree-wrapper ol.upperalpha,.rst-content .toctree-wrapper ol.upperalpha>li,.rst-content section ol.upperalpha,.rst-content section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*,.rst-content .toctree-wrapper ol li>*,.rst-content .toctree-wrapper ul li>*,.rst-content section ol li>*,.rst-content section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child,.rst-content .toctree-wrapper ol li>:first-child,.rst-content .toctree-wrapper ul li>:first-child,.rst-content section ol li>:first-child,.rst-content section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child,.rst-content .toctree-wrapper ol li>p,.rst-content .toctree-wrapper ol li>p:last-child,.rst-content .toctree-wrapper ul li>p,.rst-content .toctree-wrapper ul li>p:last-child,.rst-content section ol li>p,.rst-content section ol li>p:last-child,.rst-content section ul li>p,.rst-content section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child,.rst-content .toctree-wrapper ol li>p:only-child,.rst-content .toctree-wrapper ol li>p:only-child:last-child,.rst-content .toctree-wrapper ul li>p:only-child,.rst-content .toctree-wrapper ul li>p:only-child:last-child,.rst-content section ol li>p:only-child,.rst-content section ol li>p:only-child:last-child,.rst-content section ul li>p:only-child,.rst-content section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul,.rst-content .toctree-wrapper ol li>ol,.rst-content .toctree-wrapper ol li>ul,.rst-content .toctree-wrapper ul li>ol,.rst-content .toctree-wrapper ul li>ul,.rst-content section ol li>ol,.rst-content section ol li>ul,.rst-content section ul li>ol,.rst-content section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul,.rst-content .toctree-wrapper ol.simple li>*,.rst-content .toctree-wrapper ol.simple li ol,.rst-content .toctree-wrapper ol.simple li ul,.rst-content .toctree-wrapper ul.simple li>*,.rst-content .toctree-wrapper ul.simple li ol,.rst-content .toctree-wrapper ul.simple li ul,.rst-content section ol.simple li>*,.rst-content section ol.simple li ol,.rst-content section ol.simple li ul,.rst-content section ul.simple li>*,.rst-content section ul.simple li ol,.rst-content section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink{opacity:0;font-size:14px;font-family:FontAwesome;margin-left:.5em}.rst-content .code-block-caption .headerlink:focus,.rst-content .code-block-caption:hover .headerlink,.rst-content .eqno .headerlink:focus,.rst-content .eqno:hover .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink:focus,.rst-content .toctree-wrapper>p.caption:hover .headerlink,.rst-content dl dt .headerlink:focus,.rst-content dl dt:hover .headerlink,.rst-content h1 .headerlink:focus,.rst-content h1:hover .headerlink,.rst-content h2 .headerlink:focus,.rst-content h2:hover .headerlink,.rst-content h3 .headerlink:focus,.rst-content h3:hover .headerlink,.rst-content h4 .headerlink:focus,.rst-content h4:hover .headerlink,.rst-content h5 .headerlink:focus,.rst-content h5:hover .headerlink,.rst-content h6 .headerlink:focus,.rst-content h6:hover .headerlink,.rst-content p.caption .headerlink:focus,.rst-content p.caption:hover .headerlink,.rst-content p .headerlink:focus,.rst-content p:hover .headerlink,.rst-content table>caption .headerlink:focus,.rst-content table>caption:hover .headerlink{opacity:1}.rst-content p a{overflow-wrap:anywhere}.rst-content .wy-table td p,.rst-content .wy-table td ul,.rst-content .wy-table th p,.rst-content .wy-table th ul,.rst-content table.docutils td p,.rst-content table.docutils td ul,.rst-content table.docutils th p,.rst-content table.docutils th ul,.rst-content table.field-list td p,.rst-content table.field-list td ul,.rst-content table.field-list th p,.rst-content table.field-list th ul{font-size:inherit}.rst-content .btn:focus{outline:2px solid}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .citation-reference>span.fn-bracket,.rst-content .footnote-reference>span.fn-bracket{display:none}.rst-content .hlist{width:100%}.rst-content dl dt span.classifier:before{content:" : "}.rst-content dl dt span.classifier-delimiter{display:none!important}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:auto minmax(80%,95%)}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{display:inline-grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{display:grid;grid-template-columns:auto auto minmax(.65rem,auto) minmax(40%,95%)}html.writer-html5 .rst-content aside.citation>span.label,html.writer-html5 .rst-content aside.footnote>span.label,html.writer-html5 .rst-content div.citation>span.label{grid-column-start:1;grid-column-end:2}html.writer-html5 .rst-content aside.citation>span.backrefs,html.writer-html5 .rst-content aside.footnote>span.backrefs,html.writer-html5 .rst-content div.citation>span.backrefs{grid-column-start:2;grid-column-end:3;grid-row-start:1;grid-row-end:3}html.writer-html5 .rst-content aside.citation>p,html.writer-html5 .rst-content aside.footnote>p,html.writer-html5 .rst-content div.citation>p{grid-column-start:4;grid-column-end:5}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{margin-bottom:24px}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.citation>dt>span.brackets:before,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.citation>dt>span.brackets:after,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a{word-break:keep-all}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a:not(:first-child):before,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.citation>dd p,html.writer-html5 .rst-content dl.footnote>dd p{font-size:.9rem}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{padding-left:1rem;padding-right:1rem;font-size:.9rem;line-height:1.2rem}html.writer-html5 .rst-content aside.citation p,html.writer-html5 .rst-content aside.footnote p,html.writer-html5 .rst-content div.citation p{font-size:.9rem;line-height:1.2rem;margin-bottom:12px}html.writer-html5 .rst-content aside.citation span.backrefs,html.writer-html5 .rst-content aside.footnote span.backrefs,html.writer-html5 .rst-content div.citation span.backrefs{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content aside.citation span.backrefs>a,html.writer-html5 .rst-content aside.footnote span.backrefs>a,html.writer-html5 .rst-content div.citation span.backrefs>a{word-break:keep-all}html.writer-html5 .rst-content aside.citation span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content aside.footnote span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content div.citation span.backrefs>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content aside.citation span.label,html.writer-html5 .rst-content aside.footnote span.label,html.writer-html5 .rst-content div.citation span.label{line-height:1.2rem}html.writer-html5 .rst-content aside.citation-list,html.writer-html5 .rst-content aside.footnote-list,html.writer-html5 .rst-content div.citation-list{margin-bottom:24px}html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content aside.footnote-list aside.footnote,html.writer-html5 .rst-content div.citation-list>div.citation,html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content aside.footnote-list aside.footnote code,html.writer-html5 .rst-content aside.footnote-list aside.footnote tt,html.writer-html5 .rst-content aside.footnote code,html.writer-html5 .rst-content aside.footnote tt,html.writer-html5 .rst-content div.citation-list>div.citation code,html.writer-html5 .rst-content div.citation-list>div.citation tt,html.writer-html5 .rst-content dl.citation code,html.writer-html5 .rst-content dl.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c;white-space:normal}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040;overflow-wrap:normal}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}.rst-content dl dd>ol:last-child,.rst-content dl dd>p:last-child,.rst-content dl dd>table:last-child,.rst-content dl dd>ul:last-child{margin-bottom:0}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px;max-width:100%}html.writer-html4 .rst-content dl:not(.docutils) .k,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .k{font-style:italic}html.writer-html4 .rst-content dl:not(.docutils) .descclassname,html.writer-html4 .rst-content dl:not(.docutils) .descname,html.writer-html4 .rst-content dl:not(.docutils) .sig-name,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .sig-name{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#000}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel,.rst-content .menuselection{font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .guilabel,.rst-content .menuselection{border:1px solid #7fbbe3;background:#e7f2fa}.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>.kbd,.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>kbd{color:inherit;font-size:80%;background-color:#fff;border:1px solid #a6a6a6;border-radius:4px;box-shadow:0 2px grey;padding:2.4px 6px;margin:auto 0}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block} \ No newline at end of file diff --git a/docs/5.1.1/_static/doctools.js b/docs/5.1.1/_static/doctools.js new file mode 100644 index 00000000..0398ebb9 --- /dev/null +++ b/docs/5.1.1/_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/docs/5.1.1/_static/documentation_options.js b/docs/5.1.1/_static/documentation_options.js new file mode 100644 index 00000000..e21c068c --- /dev/null +++ b/docs/5.1.1/_static/documentation_options.js @@ -0,0 +1,13 @@ +const DOCUMENTATION_OPTIONS = { + VERSION: '0.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/docs/5.1.1/_static/file.png b/docs/5.1.1/_static/file.png new file mode 100644 index 00000000..a858a410 Binary files /dev/null and b/docs/5.1.1/_static/file.png differ diff --git a/docs/5.1.1/_static/fonts/Lato/lato-bold.eot b/docs/5.1.1/_static/fonts/Lato/lato-bold.eot new file mode 100644 index 00000000..3361183a Binary files /dev/null and b/docs/5.1.1/_static/fonts/Lato/lato-bold.eot differ diff --git a/docs/5.1.1/_static/fonts/Lato/lato-bold.ttf b/docs/5.1.1/_static/fonts/Lato/lato-bold.ttf new file mode 100644 index 00000000..29f691d5 Binary files /dev/null and b/docs/5.1.1/_static/fonts/Lato/lato-bold.ttf differ diff --git a/docs/5.1.1/_static/fonts/Lato/lato-bold.woff b/docs/5.1.1/_static/fonts/Lato/lato-bold.woff new file mode 100644 index 00000000..c6dff51f Binary files /dev/null and b/docs/5.1.1/_static/fonts/Lato/lato-bold.woff differ diff --git a/docs/5.1.1/_static/fonts/Lato/lato-bold.woff2 b/docs/5.1.1/_static/fonts/Lato/lato-bold.woff2 new file mode 100644 index 00000000..bb195043 Binary files /dev/null and b/docs/5.1.1/_static/fonts/Lato/lato-bold.woff2 differ diff --git a/docs/5.1.1/_static/fonts/Lato/lato-bolditalic.eot b/docs/5.1.1/_static/fonts/Lato/lato-bolditalic.eot new file mode 100644 index 00000000..3d415493 Binary files /dev/null and b/docs/5.1.1/_static/fonts/Lato/lato-bolditalic.eot differ diff --git a/docs/5.1.1/_static/fonts/Lato/lato-bolditalic.ttf b/docs/5.1.1/_static/fonts/Lato/lato-bolditalic.ttf new file mode 100644 index 00000000..f402040b Binary files /dev/null and b/docs/5.1.1/_static/fonts/Lato/lato-bolditalic.ttf differ diff --git a/docs/5.1.1/_static/fonts/Lato/lato-bolditalic.woff b/docs/5.1.1/_static/fonts/Lato/lato-bolditalic.woff new file mode 100644 index 00000000..88ad05b9 Binary files /dev/null and b/docs/5.1.1/_static/fonts/Lato/lato-bolditalic.woff differ diff --git a/docs/5.1.1/_static/fonts/Lato/lato-bolditalic.woff2 b/docs/5.1.1/_static/fonts/Lato/lato-bolditalic.woff2 new file mode 100644 index 00000000..c4e3d804 Binary files /dev/null and b/docs/5.1.1/_static/fonts/Lato/lato-bolditalic.woff2 differ diff --git a/docs/5.1.1/_static/fonts/Lato/lato-italic.eot b/docs/5.1.1/_static/fonts/Lato/lato-italic.eot new file mode 100644 index 00000000..3f826421 Binary files /dev/null and b/docs/5.1.1/_static/fonts/Lato/lato-italic.eot differ diff --git a/docs/5.1.1/_static/fonts/Lato/lato-italic.ttf b/docs/5.1.1/_static/fonts/Lato/lato-italic.ttf new file mode 100644 index 00000000..b4bfc9b2 Binary files /dev/null and b/docs/5.1.1/_static/fonts/Lato/lato-italic.ttf differ diff --git a/docs/5.1.1/_static/fonts/Lato/lato-italic.woff b/docs/5.1.1/_static/fonts/Lato/lato-italic.woff new file mode 100644 index 00000000..76114bc0 Binary files /dev/null and b/docs/5.1.1/_static/fonts/Lato/lato-italic.woff differ diff --git a/docs/5.1.1/_static/fonts/Lato/lato-italic.woff2 b/docs/5.1.1/_static/fonts/Lato/lato-italic.woff2 new file mode 100644 index 00000000..3404f37e Binary files /dev/null and b/docs/5.1.1/_static/fonts/Lato/lato-italic.woff2 differ diff --git a/docs/5.1.1/_static/fonts/Lato/lato-regular.eot b/docs/5.1.1/_static/fonts/Lato/lato-regular.eot new file mode 100644 index 00000000..11e3f2a5 Binary files /dev/null and b/docs/5.1.1/_static/fonts/Lato/lato-regular.eot differ diff --git a/docs/5.1.1/_static/fonts/Lato/lato-regular.ttf b/docs/5.1.1/_static/fonts/Lato/lato-regular.ttf new file mode 100644 index 00000000..74decd9e Binary files /dev/null and b/docs/5.1.1/_static/fonts/Lato/lato-regular.ttf differ diff --git a/docs/5.1.1/_static/fonts/Lato/lato-regular.woff b/docs/5.1.1/_static/fonts/Lato/lato-regular.woff new file mode 100644 index 00000000..ae1307ff Binary files /dev/null and b/docs/5.1.1/_static/fonts/Lato/lato-regular.woff differ diff --git a/docs/5.1.1/_static/fonts/Lato/lato-regular.woff2 b/docs/5.1.1/_static/fonts/Lato/lato-regular.woff2 new file mode 100644 index 00000000..3bf98433 Binary files /dev/null and b/docs/5.1.1/_static/fonts/Lato/lato-regular.woff2 differ diff --git a/docs/5.1.1/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot b/docs/5.1.1/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot new file mode 100644 index 00000000..79dc8efe Binary files /dev/null and b/docs/5.1.1/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot differ diff --git a/docs/5.1.1/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf b/docs/5.1.1/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf new file mode 100644 index 00000000..df5d1df2 Binary files /dev/null and b/docs/5.1.1/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf differ diff --git a/docs/5.1.1/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff b/docs/5.1.1/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff new file mode 100644 index 00000000..6cb60000 Binary files /dev/null and b/docs/5.1.1/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff differ diff --git a/docs/5.1.1/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2 b/docs/5.1.1/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2 new file mode 100644 index 00000000..7059e231 Binary files /dev/null and b/docs/5.1.1/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2 differ diff --git a/docs/5.1.1/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot b/docs/5.1.1/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot new file mode 100644 index 00000000..2f7ca78a Binary files /dev/null and b/docs/5.1.1/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot differ diff --git a/docs/5.1.1/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf b/docs/5.1.1/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf new file mode 100644 index 00000000..eb52a790 Binary files /dev/null and b/docs/5.1.1/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf differ diff --git a/docs/5.1.1/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff b/docs/5.1.1/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff new file mode 100644 index 00000000..f815f63f Binary files /dev/null and b/docs/5.1.1/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff differ diff --git a/docs/5.1.1/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2 b/docs/5.1.1/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2 new file mode 100644 index 00000000..f2c76e5b Binary files /dev/null and b/docs/5.1.1/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2 differ diff --git a/docs/5.1.1/_static/jquery.js b/docs/5.1.1/_static/jquery.js new file mode 100644 index 00000000..c4c6022f --- /dev/null +++ b/docs/5.1.1/_static/jquery.js @@ -0,0 +1,2 @@ +/*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0"),n("table.docutils.footnote").wrap("
"),n("table.docutils.citation").wrap("
"),n(".wy-menu-vertical ul").not(".simple").siblings("a").each((function(){var t=n(this);expand=n(''),expand.on("click",(function(n){return e.toggleCurrent(t),n.stopPropagation(),!1})),t.prepend(expand)}))},reset:function(){var n=encodeURI(window.location.hash)||"#";try{var e=$(".wy-menu-vertical"),t=e.find('[href="'+n+'"]');if(0===t.length){var i=$('.document [id="'+n.substring(1)+'"]').closest("div.section");0===(t=e.find('[href="#'+i.attr("id")+'"]')).length&&(t=e.find('[href="#"]'))}if(t.length>0){$(".wy-menu-vertical .current").removeClass("current").attr("aria-expanded","false"),t.addClass("current").attr("aria-expanded","true"),t.closest("li.toctree-l1").parent().addClass("current").attr("aria-expanded","true");for(let n=1;n<=10;n++)t.closest("li.toctree-l"+n).addClass("current").attr("aria-expanded","true");t[0].scrollIntoView()}}catch(n){console.log("Error expanding nav for anchor",n)}},onScroll:function(){this.winScroll=!1;var n=this.win.scrollTop(),e=n+this.winHeight,t=this.navBar.scrollTop()+(n-this.winPosition);n<0||e>this.docHeight||(this.navBar.scrollTop(t),this.winPosition=n)},onResize:function(){this.winResize=!1,this.winHeight=this.win.height(),this.docHeight=$(document).height()},hashChange:function(){this.linkScroll=!0,this.win.one("hashchange",(function(){this.linkScroll=!1}))},toggleCurrent:function(n){var e=n.closest("li");e.siblings("li.current").removeClass("current").attr("aria-expanded","false"),e.siblings().find("li.current").removeClass("current").attr("aria-expanded","false");var t=e.find("> ul li");t.length&&(t.removeClass("current").attr("aria-expanded","false"),e.toggleClass("current").attr("aria-expanded",(function(n,e){return"true"==e?"false":"true"})))}},"undefined"!=typeof window&&(window.SphinxRtdTheme={Navigation:n.exports.ThemeNav,StickyNav:n.exports.ThemeNav}),function(){for(var n=0,e=["ms","moz","webkit","o"],t=0;t a.language.name.localeCompare(b.language.name)); + + const languagesHTML = ` +
+
Languages
+ ${languages + .map( + (translation) => ` +
+ ${translation.language.code} +
+ `, + ) + .join("\n")} +
+ `; + return languagesHTML; + } + + function renderVersions(config) { + if (!config.versions.active.length) { + return ""; + } + const versionsHTML = ` +
+
Versions
+ ${config.versions.active + .map( + (version) => ` +
+ ${version.slug} +
+ `, + ) + .join("\n")} +
+ `; + return versionsHTML; + } + + function renderDownloads(config) { + if (!Object.keys(config.versions.current.downloads).length) { + return ""; + } + const downloadsNameDisplay = { + pdf: "PDF", + epub: "Epub", + htmlzip: "HTML", + }; + + const downloadsHTML = ` +
+
Downloads
+ ${Object.entries(config.versions.current.downloads) + .map( + ([name, url]) => ` +
+ ${downloadsNameDisplay[name]} +
+ `, + ) + .join("\n")} +
+ `; + return downloadsHTML; + } + + document.addEventListener("readthedocs-addons-data-ready", function (event) { + const config = event.detail.data(); + + const flyout = ` +
+ + Read the Docs + v: ${config.versions.current.slug} + + +
+
+ ${renderLanguages(config)} + ${renderVersions(config)} + ${renderDownloads(config)} +
+
On Read the Docs
+
+ Project Home +
+
+ Builds +
+
+ Downloads +
+
+
+
Search
+
+
+ +
+
+
+
+ + Hosted by Read the Docs + +
+
+ `; + + // Inject the generated flyout into the body HTML element. + document.body.insertAdjacentHTML("beforeend", flyout); + + // Trigger the Read the Docs Addons Search modal when clicking on the "Search docs" input from inside the flyout. + document + .querySelector("#flyout-search-form") + .addEventListener("focusin", () => { + const event = new CustomEvent("readthedocs-search-show"); + document.dispatchEvent(event); + }); + }) +} + +if (themeLanguageSelector || themeVersionSelector) { + function onSelectorSwitch(event) { + const option = event.target.selectedIndex; + const item = event.target.options[option]; + window.location.href = item.dataset.url; + } + + document.addEventListener("readthedocs-addons-data-ready", function (event) { + const config = event.detail.data(); + + const versionSwitch = document.querySelector( + "div.switch-menus > div.version-switch", + ); + if (themeVersionSelector) { + let versions = config.versions.active; + if (config.versions.current.hidden || config.versions.current.type === "external") { + versions.unshift(config.versions.current); + } + const versionSelect = ` + + `; + + versionSwitch.innerHTML = versionSelect; + versionSwitch.firstElementChild.addEventListener("change", onSelectorSwitch); + } + + const languageSwitch = document.querySelector( + "div.switch-menus > div.language-switch", + ); + + if (themeLanguageSelector) { + if (config.projects.translations.length) { + // Add the current language to the options on the selector + let languages = config.projects.translations.concat( + config.projects.current, + ); + languages = languages.sort((a, b) => + a.language.name.localeCompare(b.language.name), + ); + + const languageSelect = ` + + `; + + languageSwitch.innerHTML = languageSelect; + languageSwitch.firstElementChild.addEventListener("change", onSelectorSwitch); + } + else { + languageSwitch.remove(); + } + } + }); +} + +document.addEventListener("readthedocs-addons-data-ready", function (event) { + // Trigger the Read the Docs Addons Search modal when clicking on "Search docs" input from the topnav. + document + .querySelector("[role='search'] input") + .addEventListener("focusin", () => { + const event = new CustomEvent("readthedocs-search-show"); + document.dispatchEvent(event); + }); +}); \ No newline at end of file diff --git a/docs/5.1.1/_static/language_data.js b/docs/5.1.1/_static/language_data.js new file mode 100644 index 00000000..c7fe6c6f --- /dev/null +++ b/docs/5.1.1/_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/docs/5.1.1/_static/minus.png b/docs/5.1.1/_static/minus.png new file mode 100644 index 00000000..d96755fd Binary files /dev/null and b/docs/5.1.1/_static/minus.png differ diff --git a/docs/5.1.1/_static/plus.png b/docs/5.1.1/_static/plus.png new file mode 100644 index 00000000..7107cec9 Binary files /dev/null and b/docs/5.1.1/_static/plus.png differ diff --git a/docs/5.1.1/_static/pygments.css b/docs/5.1.1/_static/pygments.css new file mode 100644 index 00000000..84ab3030 --- /dev/null +++ b/docs/5.1.1/_static/pygments.css @@ -0,0 +1,75 @@ +pre { line-height: 125%; } +td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +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: #3D7B7B; font-style: italic } /* Comment */ +.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .k { color: #008000; font-weight: bold } /* Keyword */ +.highlight .o { color: #666666 } /* Operator */ +.highlight .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */ +.highlight .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #9C6500 } /* Comment.Preproc */ +.highlight .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */ +.highlight .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */ +.highlight .gr { color: #E40000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #008400 } /* Generic.Inserted */ +.highlight .go { color: #717171 } /* Generic.Output */ +.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #0044DD } /* Generic.Traceback */ +.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #008000 } /* Keyword.Pseudo */ +.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #B00040 } /* Keyword.Type */ +.highlight .m { color: #666666 } /* Literal.Number */ +.highlight .s { color: #BA2121 } /* Literal.String */ +.highlight .na { color: #687822 } /* Name.Attribute */ +.highlight .nb { color: #008000 } /* Name.Builtin */ +.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */ +.highlight .no { color: #880000 } /* Name.Constant */ +.highlight .nd { color: #AA22FF } /* Name.Decorator */ +.highlight .ni { color: #717171; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #0000FF } /* Name.Function */ +.highlight .nl { color: #767600 } /* Name.Label */ +.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #19177C } /* Name.Variable */ +.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mb { color: #666666 } /* Literal.Number.Bin */ +.highlight .mf { color: #666666 } /* Literal.Number.Float */ +.highlight .mh { color: #666666 } /* Literal.Number.Hex */ +.highlight .mi { color: #666666 } /* Literal.Number.Integer */ +.highlight .mo { color: #666666 } /* Literal.Number.Oct */ +.highlight .sa { color: #BA2121 } /* Literal.String.Affix */ +.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */ +.highlight .sc { color: #BA2121 } /* Literal.String.Char */ +.highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */ +.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #BA2121 } /* Literal.String.Double */ +.highlight .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */ +.highlight .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */ +.highlight .sx { color: #008000 } /* Literal.String.Other */ +.highlight .sr { color: #A45A77 } /* Literal.String.Regex */ +.highlight .s1 { color: #BA2121 } /* Literal.String.Single */ +.highlight .ss { color: #19177C } /* Literal.String.Symbol */ +.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */ +.highlight .fm { color: #0000FF } /* Name.Function.Magic */ +.highlight .vc { color: #19177C } /* Name.Variable.Class */ +.highlight .vg { color: #19177C } /* Name.Variable.Global */ +.highlight .vi { color: #19177C } /* Name.Variable.Instance */ +.highlight .vm { color: #19177C } /* Name.Variable.Magic */ +.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/docs/5.1.1/_static/searchtools.js b/docs/5.1.1/_static/searchtools.js new file mode 100644 index 00000000..2c774d17 --- /dev/null +++ b/docs/5.1.1/_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/docs/5.1.1/_static/sphinx_highlight.js b/docs/5.1.1/_static/sphinx_highlight.js new file mode 100644 index 00000000..8a96c69a --- /dev/null +++ b/docs/5.1.1/_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/docs/5.1.1/distinct_counting/cpc.html b/docs/5.1.1/distinct_counting/cpc.html new file mode 100644 index 00000000..1b755f31 --- /dev/null +++ b/docs/5.1.1/distinct_counting/cpc.html @@ -0,0 +1,268 @@ + + + + + + + + + Compressed Probabilistic Counting (CPC) — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Compressed Probabilistic Counting (CPC)

+

High performance C++ implementation of Compressed Probabilistic Counting (CPC) Sketch. +This is a unique-counting sketch that implements the Compressed Probabilistic Counting (CPC, a.k.a FM85) algorithms developed by Kevin Lang in his paper +Back to the Future: an Even More Nearly Optimal Cardinality Estimation Algorithm. +This sketch is extremely space-efficient when serialized. +In an apples-to-apples empirical comparison against compressed HyperLogLog sketches, this new algorithm simultaneously wins on the two dimensions of the space/accuracy tradeoff and produces sketches that are smaller than the entropy of HLL, so no possible implementation of compressed HLL can match its space efficiency for a given accuracy. As described in the paper this sketch implements a newly developed ICON estimator algorithm that survives unioning operations, another well-known estimator, the Historical Inverse Probability (HIP) estimator does not. +The update speed performance of this sketch is quite fast and is comparable to the speed of HLL. +The unioning (merging) capability of this sketch also allows for merging of sketches with different configurations of K. +For additional security this sketch can be configured with a user-specified hash seed.

+
+
+class cpc_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.cpc_sketch
+

Reads a bytes object and returns the corresponding cpc_sketch

+
+ +

Non-static Methods:

+
+
+__init__(self, lg_k: int = 11, seed: int = 9001) None
+

Creates a new CPC sketch

+
+
Parameters:
+
    +
  • lg_k (int, optional) – base 2 logarithm of the number of bins in the sketch

  • +
  • seed (int, optional) – seed value for the hash function

  • +
+
+
+
+ +
+
+get_estimate
+

Estimate of the distinct count of the input stream

+
+ +
+
+get_lower_bound
+

Returns an approximate lower bound on the estimate for kappa values in {1, 2, 3}, roughly corresponding to standard deviations

+
+ +
+
+get_upper_bound
+

Returns an approximate upper bound on the estimate for kappa values in {1, 2, 3}, roughly corresponding to standard deviations

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+property lg_k
+

Configured lg_k of this sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, datum: int) -> None

  2. +
+

Updates the sketch with the given 64-bit integer value

+
    +
  1. update(self, datum: float) -> None

  2. +
+

Updates the sketch with the given 64-bit floating point

+
    +
  1. update(self, datum: str) -> None

  2. +
+

Updates the sketch with the given string

+
+ +
+ +
+
+class cpc_union(*args, **kwargs)
+
+
+__init__(self, lg_k: int, seed: int = 9001) None
+
+ +
+
+get_result
+

Returns a CPC sketch with the result of the union

+
+ +
+
+update
+

Updates the union with the provided CPC sketch

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.1/distinct_counting/hyper_log_log.html b/docs/5.1.1/distinct_counting/hyper_log_log.html new file mode 100644 index 00000000..515e5d05 --- /dev/null +++ b/docs/5.1.1/distinct_counting/hyper_log_log.html @@ -0,0 +1,424 @@ + + + + + + + + + HyperLogLog (HLL) — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

HyperLogLog (HLL)

+

This is a high performance implementation of Phillipe Flajolet’s HLL sketch but with significantly improved error behavior.

+

If the ONLY use case for sketching is counting uniques and merging, the HLL sketch is a reasonable choice, although the highest performing in terms of accuracy for storage space consumed is CPC (Compressed Probabilistic Counting). For large enough counts, this HLL version (with HLL_4) can be 2 to 16 times smaller than the Theta sketch family for the same accuracy.

+

This implementation offers three different types of HLL sketch, each with different trade-offs with accuracy, space and performance. +These types are specified with the target_hll_type parameter.

+

In terms of accuracy, all three types, for the same lg_config_k, have the same error distribution as a function of n, the number of unique values fed to the sketch. +The configuration parameter lg_config_k is the log-base-2 of k, where k is the number of buckets or slots for the sketch.

+

During warmup, when the sketch has only received a small number of unique items (up to about 10% of k), this implementation leverages a new class of estimator algorithms with significantly better accuracy.

+
+
+class tgt_hll_type(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
+

Target HLL flavor

+
+
+HLL_4 : 4 bits per entry
+
+ +
+
+HLL_6 : 6 bits per entry
+
+ +
+
+HLL_8 : 8 bits per entry
+
+ +
+ +
+
+class hll_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.hll_sketch
+

Reads a bytes object and returns the corresponding hll_sketch

+
+ +
+
+get_max_updatable_serialization_bytes(lg_k: int, tgt_type: _datasketches.tgt_hll_type) int
+

Provides a likely upper bound on serialization size for the given parameters

+
+ +
+
+get_rel_err(upper_bound: bool, unioned: bool, lg_k: int, num_std_devs: int) float
+

Returns the a priori relative error bound for the given parameters

+
+ +

Non-static Methods:

+
+
+__init__(self, lg_k: int, tgt_type: _datasketches.tgt_hll_type = tgt_hll_type.HLL_8, start_max_size: bool = False) None
+

Constructs a new HLL sketch

+
+
Parameters:
+
    +
  • lg_config_k (int) – A full sketch can hold 2^lg_config_k rows. Must be between 7 and 21, inclusive,

  • +
  • tgt_type (tgt_hll_type) – The HLL mode to use, if/when the sketch reaches estimation mode

  • +
  • start_full_size (bool) – Indicates whether to start in HLL mode, keeping memory use constant (if HLL_6 or HLL_8) at the cost of much higher initial memory use. Default (and recommended) is False.

  • +
+
+
+
+ +
+
+get_compact_serialization_bytes
+

Returns the size of the serialized sketch when compressing the exception table if HLL_4

+
+ +
+
+get_estimate
+

Estimate of the distinct count of the input stream

+
+ +
+
+get_lower_bound
+

Returns the approximate lower error bound given the specified number of standard deviations in {1, 2, 3}

+
+ +
+
+get_updatable_serialization_bytes
+

Returns the size of the serialized sketch

+
+ +
+
+get_upper_bound
+

Returns the approximate upper error bound given the specified number of standard deviations in {1, 2, 3}

+
+ +
+
+is_compact
+

True if the sketch is compact, otherwise False

+
+ +
+
+is_empty
+

True if the sketch is empty, otherwise False

+
+ +
+
+property lg_config_k
+

Configured lg_k value for the sketch

+
+ +
+
+reset
+

Resets the sketch to the empty state in coupon collection mode

+
+ +
+
+serialize_compact
+

Serializes the sketch into a bytes object, compressing the exception table if HLL_4

+
+ +
+
+serialize_updatable
+

Serializes the sketch into a bytes object

+
+ +
+
+property tgt_type
+

The HLL type (4, 6, or 8) when in estimation mode

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, datum: int) -> None

  2. +
+

Updates the sketch with the given integral value

+
    +
  1. update(self, datum: float) -> None

  2. +
+

Updates the sketch with the given floating point value

+
    +
  1. update(self, datum: str) -> None

  2. +
+

Updates the sketch with the given string value

+
+ +
+ +
+
+class hll_union(*args, **kwargs)
+

Static Methods:

+
+
+get_rel_err(upper_bound: bool, unioned: bool, lg_k: int, num_std_devs: int) float
+

Returns the a priori relative error bound for the given parameters

+
+ +

Non-static Methods:

+
+
+__init__(self, lg_max_k: int) None
+

Construct an hll_union object if the given size.

+
+
Parameters:
+

lg_max_k (int) – The maximum size, in log2, of k. Must be between 7 and 21, inclusive.

+
+
+
+ +
+
+get_estimate
+

Estimate of the distinct count of the input stream

+
+ +
+
+get_lower_bound
+

Returns the approximate lower error bound given the specified number of standard deviations in {1, 2, 3}

+
+ +
+
+get_result
+

Returns a sketch of the target type representing the current union state

+
+ +
+
+get_upper_bound
+

Returns the approximate upper error bound given the specified number of standard deviations in {1, 2, 3}

+
+ +
+
+is_empty
+

True if the union is empty, otherwise False

+
+ +
+
+property lg_config_k
+

Configured lg_k value for the union

+
+ +
+
+reset
+

Resets the union to the empty state

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, sketch: _datasketches.hll_sketch) -> None

  2. +
+

Updates the union with the given HLL sketch

+
    +
  1. update(self, datum: int) -> None

  2. +
+

Updates the union with the given integral value

+
    +
  1. update(self, datum: float) -> None

  2. +
+

Updates the union with the given floating point value

+
    +
  1. update(self, datum: str) -> None

  2. +
+

Updates the union with the given string value

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.1/distinct_counting/index.html b/docs/5.1.1/distinct_counting/index.html new file mode 100644 index 00000000..759fa8ba --- /dev/null +++ b/docs/5.1.1/distinct_counting/index.html @@ -0,0 +1,150 @@ + + + + + + + + + Distinct Counting — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Distinct Counting

+

Distinct counting is one of the earliest tasks to which sketches were applied. The concept is simple: +Provide an estimate of the number of unique elements in a set of data. One of the earliest solutions came +from Flajolet and Martin in 1985 with their seminal work +Probabilistic counting Algorithms for Data Base Applications.

+

The DataSketches library offers several types of distinct counting sketches, each with different properties.

+
+
    +
  • hll_sketch: Hyper Log Log, a well-known sketch for distinct counting but no longer state-of-the-art.

  • +
  • cpc_sketch: Provides a better accuracy-space trade-off than HLL, but with a somewhat larger footprint while in-memory.

  • +
  • theta_sketch: Theta sketch, a type of k-minimum value sketch, which provide good performance with intersection and set difference operations.

  • +
  • tuple_sketch: Tuple sketch, which is similar to a theta sketch but supports additional data stored with each key.

  • +
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.1/distinct_counting/theta.html b/docs/5.1.1/distinct_counting/theta.html new file mode 100644 index 00000000..2869114d --- /dev/null +++ b/docs/5.1.1/distinct_counting/theta.html @@ -0,0 +1,438 @@ + + + + + + + + + Theta Sketch — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Theta Sketch

+

Theta sketches are used for distinct counting.

+

The theta package contains the basic sketch classes that are members of the Theta Sketch Framework. +There is a separate Tuple package for many of the sketches that are derived from the same algorithms defined in the Theta Sketch Framework paper.

+

The Theta Sketch sketch is a space-efficient method for estimating cardinalities of sets. +It can also easily handle set operations (such as union, intersection, difference) while maintaining good accuracy. +Theta sketch is a practical variant of the K-Minimum Values sketch which avoids the need to sort the stored +hash values on every insertion to the sketch. +It has better error properties than the HyperLogLog sketch for set operations beyond the simple union.

+

Set operations (union, intersection, A-not-B) are performed through the use of dedicated objects.

+

Several Jaccard similarity +measures can be computed between theta sketches with the theta_jaccard_similarity class.

+
+
+class theta_sketch
+

An abstract base class for theta sketches

+
+
+get_estimate
+

Estimate of the distinct count of the input stream

+
+ +
+
+get_lower_bound
+

Returns an approximate lower bound on the estimate at standard deviations in {1, 2, 3}

+
+ +
+
+get_seed_hash
+

Returns a hash of the seed used in the sketch

+
+ +
+
+get_upper_bound
+

Returns an approximate upper bound on the estimate at standard deviations in {1, 2, 3}

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if sketch is in estimation mode, otherwise False

+
+ +
+
+is_ordered
+

Returns True if the sketch entries are sorted, otherwise False

+
+ +
+
+property num_retained
+

The number of items currently in the sketch

+
+ +
+
+property theta
+

Theta (effective sampling rate) as a fraction from 0 to 1

+
+ +
+
+property theta64
+

Theta as 64-bit value

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+ +
+
+class update_theta_sketch(*args, **kwargs)
+
+
+__init__(self, lg_k: int = 12, p: float = 1.0, seed: int = 9001) None
+

Creates an update_theta_sketch using the provided parameters

+
+
Parameters:
+
    +
  • lg_k (int, optional) – base 2 logarithm of the maximum size of the sketch. Default 12.

  • +
  • p (float, optional) – an initial sampling rate to use. Default 1.0

  • +
  • seed (int, optional) – the seed to use when hashing values

  • +
+
+
+
+ +
+
+compact
+

Returns a compacted form of the sketch, optionally sorting it

+
+ +
+
+reset
+

Resets the sketch to the initial empty state

+
+ +
+
+trim
+

Removes retained entries in excess of the nominal size k (if any)

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, datum: int) -> None

  2. +
+

Updates the sketch with the given integral value

+
    +
  1. update(self, datum: float) -> None

  2. +
+

Updates the sketch with the given floating point value

+
    +
  1. update(self, datum: str) -> None

  2. +
+

Updates the sketch with the given string

+
+ +
+ +
+
+class compact_theta_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, seed: int = 9001) _datasketches.compact_theta_sketch
+

Reads a bytes object and returns the corresponding compact_theta_sketch

+
+ +

Non-static Methods:

+
+
+__init__(self, arg0: _datasketches.theta_sketch, arg1: bool, /) None
+

Creates a compact_theta_sketch from an existing theta_sketch.

+
+
Parameters:
+
    +
  • other (theta_sketch) – a source theta_sketch

  • +
  • ordered (bool) – whether the incoming sketch entries are sorted. Default True

  • +
+
+
+
+ +
+
+serialize
+

Serializes the sketch into a bytes object, optionally compressing the data

+
+ +
+ +
+
+class theta_union(*args, **kwargs)
+
+
+__init__(self, lg_k: int = 12, p: float = 1.0, seed: int = 9001) None
+

Creates a theta_union using the provided parameters

+
+
Parameters:
+
    +
  • lg_k (int, optional) – base 2 logarithm of the maximum size of the union. Default 12.

  • +
  • p (float, optional) – an initial sampling rate to use. Default 1.0

  • +
  • seed (int, optional) – the seed to use when hashing values. Must match all sketch seeds.

  • +
+
+
+
+ +
+
+get_result
+

Returns the sketch corresponding to the union result

+
+ +
+
+update
+

Updates the union with the given sketch

+
+ +
+ +
+
+class theta_intersection(*args, **kwargs)
+
+
+__init__(self, seed: int = 9001) None
+

Creates a theta_intersection using the provided parameters

+
+
Parameters:
+

seed (int, optional) – the seed to use when hashing values. Must match all sketch seeds

+
+
+
+ +
+
+get_result
+

Returns the sketch corresponding to the intersection result

+
+ +
+
+has_result
+

Returns True if the intersection has a valid result, otherwise False

+
+ +
+
+update
+

Intersections the provided sketch with the current intersection state

+
+ +
+ +
+
+class theta_a_not_b(*args, **kwargs)
+
+
+__init__(self, seed: int = 9001) None
+

Creates a tuple_a_not_b object

+
+
Parameters:
+

seed (int, optional) – the seed to use when hashing values. Must match all sketch seeds.

+
+
+
+ +
+
+compute
+

Returns a sketch with the result of applying the A-not-B operation on the given inputs

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.1/distinct_counting/tuple.html b/docs/5.1.1/distinct_counting/tuple.html new file mode 100644 index 00000000..3c060fe2 --- /dev/null +++ b/docs/5.1.1/distinct_counting/tuple.html @@ -0,0 +1,512 @@ + + + + + + + + + Tuple Sketch — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Tuple Sketch

+

Tuple sketches are an extension of Theta sketches, meaning they provide estimate of distinct counts, that +allow the keeping of arbitrary summaries associated with each retained key +(for example, a count for every key). The use of a tuple_sketch requires a TuplePolicy which +defines how summaries are created, updated, merged, or intersected. The library provides a few basic +examples of TuplePolicy implementations, but the right custom summary and policy can allow very +complicated analysis to be performed quite easily.

+

Set operations (union, intersection, A-not-B) are performed through the use of dedicated objects.

+

Several Jaccard similarity +measures can be computed between theta sketches with the tuple_jaccard_similarity class.

+
+

Note

+

Serializing and deserializing this sketch requires the use of a PyObjectSerDe.

+
+
+
+class tuple_sketch
+

An abstract base class for tuple sketches.

+
+
+DEFAULT_SEED = 9001
+
+ +
+
+get_estimate
+

Estimate of the distinct count of the input stream

+
+ +
+
+get_lower_bound
+

Returns an approximate lower bound on the estimate at standard deviations in {1, 2, 3}

+
+ +
+
+get_seed_hash
+

Returns a hash of the seed used in the sketch

+
+ +
+
+get_upper_bound
+

Returns an approximate upper bound on the estimate at standard deviations in {1, 2, 3}

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if sketch is in estimation mode, otherwise False

+
+ +
+
+is_ordered
+

Returns True if the sketch entries are sorted, otherwise False

+
+ +
+
+property num_retained
+

The number of items currently in the sketch

+
+ +
+
+property theta
+

Theta (effective sampling rate) as a fraction from 0 to 1

+
+ +
+
+property theta64
+

Theta as 64-bit value

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+ +
+
+class update_tuple_sketch(*args, **kwargs)
+
+
+__init__(self, policy: _datasketches.TuplePolicy, lg_k: int = 12, p: float = 1.0, seed: int = 9001) None
+

Creates an update_tuple_sketch using the provided parameters

+
+
Parameters:
+
    +
  • policy (TuplePolicy) – a policy to use when updating

  • +
  • lg_k (int, optional) – base 2 logarithm of the maximum size of the sketch. Default 12.

  • +
  • p (float, optional) – an initial sampling rate to use. Default 1.0

  • +
  • seed (int, optional) – the seed to use when hashing values

  • +
+
+
+
+ +
+
+compact
+

Returns a compacted form of the sketch, optionally sorting it

+
+ +
+
+filter
+

Produces a compact_tuple_sketch from the given sketch by applying a predicate to the summary in each entry.

+
+
Parameters:
+

predicate – A function returning true or value evaluated on each tuple summary

+
+
Returns:
+

A compact_tuple_sketch with the selected entries

+
+
Return type:
+

compact_tuple_sketch

+
+
+
+ +
+
+reset
+

Resets the sketch to the initial empty state

+
+ +
+
+trim
+

Removes retained entries in excess of the nominal size k (if any)

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, datum: int, value: object) -> None

  2. +
+

Updates the sketch with the given integral item and summary value

+
    +
  1. update(self, datum: float, value: object) -> None

  2. +
+

Updates the sketch with the given floating point item and summary value

+
    +
  1. update(self, datum: str, value: object) -> None

  2. +
+

Updates the sketch with the given string item and summary value

+
+ +
+ +
+
+class compact_tuple_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe, seed: int = 9001) _datasketches.compact_tuple_sketch
+

Reads a bytes object and returns the corresponding compact_tuple_sketch

+
+ +

Non-static Methods:

+
+
+__init__(self, other: _datasketches.tuple_sketch, ordered: bool = True) None
+
+__init__(self, other: _datasketches.theta_sketch, summary: object) None
+

Overloaded function.

+
    +
  1. __init__(self, other: _datasketches.tuple_sketch, ordered: bool = True) -> None

  2. +
+

Creates a compact_tuple_sketch from an existing tuple_sketch.

+
+
Parameters:
+
    +
  • other (tuple_sketch) – a sourch tuple_sketch

  • +
  • ordered (bool, optional) – whether the incoming sketch entries are sorted. Default True

  • +
+
+
+
    +
  1. __init__(self, other: _datasketches.theta_sketch, summary: object) -> None

  2. +
+

Creates a compact_tuple_sketch from a theta_sketch using a fixed summary value.

+
+
Parameters:
+
    +
  • other (theta_sketch) – a source theta sketch

  • +
  • summary (object) – a summary to use for every sketch entry

  • +
+
+
+
+ +
+
+filter
+

Produces a compact_tuple_sketch from the given sketch by applying a predicate to the summary in each entry.

+
+
Parameters:
+

predicate – A function returning true or value evaluated on each tuple summary

+
+
Returns:
+

A compact_tuple_sketch with the selected entries

+
+
Return type:
+

compact_tuple_sketch

+
+
+
+ +
+
+serialize
+

Serializes the sketch into a bytes object

+
+ +
+ +
+
+class tuple_union(*args, **kwargs)
+
+
+__init__(self, policy: _datasketches.TuplePolicy, lg_k: int = 12, p: float = 1.0, seed: int = 9001) None
+

Creates a tuple_union using the provided parameters

+
+
Parameters:
+
    +
  • policy (TuplePolicy) – a policy to use when unioning entries

  • +
  • lg_k (int, optional) – base 2 logarithm of the maximum size of the union. Default 12.

  • +
  • p (float, optional) – an initial sampling rate to use. Default 1.0

  • +
  • seed (int, optional) – the seed to use when hashing values. Must match any sketch seeds.

  • +
+
+
+
+ +
+
+get_result
+

Returns the sketch corresponding to the union result

+
+ +
+
+reset
+

Resets the sketch to the initial empty

+
+ +
+
+update
+

Updates the union with the given sketch

+
+ +
+ +
+
+class tuple_intersection(*args, **kwargs)
+
+
+__init__(self, policy: _datasketches.TuplePolicy, seed: int = 9001) None
+

Creates a tuple_intersection using the provided parameters

+
+
Parameters:
+
    +
  • policy (TuplePolicy) – a policy to use when intersecting entries

  • +
  • seed (int, optional) – the seed to use when hashing values. Must match any sketch seeds

  • +
+
+
+
+ +
+
+get_result
+

Returns the sketch corresponding to the intersection result

+
+ +
+
+has_result
+

Returns True if the intersection has a valid result, otherwise False

+
+ +
+
+update
+

Intersects the provided sketch with the current intersection state

+
+ +
+ +
+
+class tuple_a_not_b(*args, **kwargs)
+
+
+__init__(self, seed: int = 9001) None
+

Creates a tuple_a_not_b object

+
+
Parameters:
+

seed (int, optional) – the seed to use when hashing values. Must match any sketch seeds.

+
+
+
+ +
+
+compute
+

Returns a sketch with the result of applying the A-not-B operation on the given inputs

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.1/frequency/count_min_sketch.html b/docs/5.1.1/frequency/count_min_sketch.html new file mode 100644 index 00000000..8f7f51d9 --- /dev/null +++ b/docs/5.1.1/frequency/count_min_sketch.html @@ -0,0 +1,301 @@ + + + + + + + + + CountMin Sketch — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

CountMin Sketch

+

The CountMin sketch, as described in Cormode and Muthukrishnan in +http://dimacs.rutgers.edu/~graham/pubs/papers/cm-full.pdf, +is used for approximate Frequency Estimation. +For an item \(x\) with frequency \(f_x\), the sketch provides an estimate, \(\hat{f_x}\), +such that \(f_x \approx \hat{f_x}.\) +The sketch guarantees that \(f_x \le \hat{f_x}\) and provides a probabilistic upper bound which is dependent on the size parameters. +The sketch provides an estimate of the occurrence frequency for any queried item but, in contrast +to the Frequent Items Sketch, this sketch does not provide a list of +heavy hitters.

+
+
+class count_min_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.count_min_sketch
+

Reads a bytes object and returns the corresponding count_min_sketch

+
+ +
+
+suggest_num_buckets(relative_error: float) int
+

Suggests the number of buckets needed to achieve an accuracy within the provided relative_error. For example, when relative_error = 0.05, the returned frequency estimates satisfy the ‘relative_error’ guarantee that never overestimates the weights but may underestimate the weights by 5% of the total weight in the sketch. Returns the number of hash buckets at every level of the sketch required in order to obtain the specified relative error.

+
+ +
+
+suggest_num_hashes(confidence: float) int
+

Suggests the number of hashes needed to achieve the provided confidence. For example, with 95% confidence, frequency estimates satisfy the ‘relative_error’ guarantee. Returns the number of hash functions that are required in order to achieve the specified confidence of the sketch. confidence = 1 - delta, with delta denoting the sketch failure probability.

+
+ +

Non-static Methods:

+
+
+get_estimate
+

Overloaded function.

+
    +
  1. get_estimate(self, item: int) -> float

  2. +
+

Returns an estimate of the frequency of the provided 64-bit integer value

+
    +
  1. get_estimate(self, item: str) -> float

  2. +
+

Returns an estimate of the frequency of the provided string

+
+ +
+
+get_lower_bound
+

Overloaded function.

+
    +
  1. get_lower_bound(self, item: int) -> float

  2. +
+

Returns a lower bound on the estimate for the given 64-bit integer value

+
    +
  1. get_lower_bound(self, item: str) -> float

  2. +
+

Returns a lower bound on the estimate for the provided string

+
+ +
+
+get_relative_error
+

Returns the maximum permissible error for any frequency estimate query

+
+ +
+
+get_serialized_size_bytes
+

Returns the size in bytes of the serialized image of the sketch

+
+ +
+
+get_upper_bound
+

Overloaded function.

+
    +
  1. get_upper_bound(self, item: int) -> float

  2. +
+

Returns an upper bound on the estimate for the given 64-bit integer value

+
    +
  1. get_upper_bound(self, item: str) -> float

  2. +
+

Returns an upper bound on the estimate for the provided string

+
+ +
+
+is_empty
+

Returns True if the sketch has seen no items, otherwise False

+
+ +
+
+merge
+

Merges the provided other sketch into this one

+
+ +
+
+property num_buckets
+

The configured number of buckets for the sketch

+
+ +
+
+property num_hashes
+

The configured number of hashes for the sketch

+
+ +
+
+property seed
+

The base hash seed for the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+property total_weight
+

The total weight currently inserted into the stream

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: int, weight: float = 1.0) -> None

  2. +
+

Updates the sketch with the given 64-bit integer value

+
    +
  1. update(self, item: str, weight: float = 1.0) -> None

  2. +
+

Updates the sketch with the given string

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.1/frequency/frequent_items.html b/docs/5.1.1/frequency/frequent_items.html new file mode 100644 index 00000000..fd61d837 --- /dev/null +++ b/docs/5.1.1/frequency/frequent_items.html @@ -0,0 +1,477 @@ + + + + + + + + + Frequent Items — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Frequent Items

+

This sketch is useful for tracking approximate frequencies of items (object or string) with optional associated +integer counts that are members of a multiset of such items. +The true frequency of an item is defined to be the sum of associated counts.

+

This implementation provides the following capabilities:

+
    +
  • Estimate the frequency of an item.

  • +
  • Return upper and lower bounds of any item, such that the true frequency is always between the upper and lower bounds.

  • +
  • Return a global maximum error that holds for all items in the stream.

  • +
  • Return an array of frequent items that qualify either a NO_FALSE_POSITIVES or a NO_FALSE_NEGATIVES error type.

  • +
  • Merge itself with another sketch object created from this class.

  • +
  • Serialize/Deserialize to/from a byte array.

  • +
+

Space Usage

+

The sketch is initialized with a maximum map size, maxMapSize, that specifies the maximum physical length of the internal hash map of the form (object item, int count). +The maximum map size is always a power of 2, defined through the variables lg_max_map_size.

+

The hash map starts at a very small size (8 entries) and grows as needed up to the specified maximum map size.

+

Excluding external space required for the item objects, the internal memory space usage of this sketch is 18 * mapSize bytes (assuming 8 bytes for each reference), +plus a small constant number of additional bytes. +The internal memory space usage of this sketch will never exceed 18 * maxMapSize bytes, plus a small constant number of additional bytes.

+

Maximum Capacity of the Sketch

+

The LOAD_FACTOR for the hash map is internally set at \(75\%\), which means at any time the map capacity of (item, count) pairs is mapCap = 0.75 * mapSize. +The maximum capacity of (item, count) pairs of the sketch is maxMapCap = 0.75 * maxMapSize.

+

Updating the sketch with ``(item, count)`` pairs

+

If the item is found in the hash map, the mapped count field (the “counter”) is incremented by the incoming count; otherwise, a new counter (item, count) pair is created. +If the number of tracked counters reaches the maximum capacity of the hash map, the sketch decrements all of the counters (by an approximately computed median) +and removes any non-positive counters.

+

Accuracy

+

If fewer than 0.75 * maxMapSize different items are inserted into the sketch, the estimated frequencies returned by the sketch will be exact.

+

The logic of the frequent items sketch is such that the stored counts and true counts are never too different. +More specifically, for any item, the sketch can return an estimate of the true frequency of item, along with upper and lower bounds on the frequency (that hold deterministically).

+

For this implementation and for a specific active item, it is guaranteed that the true frequency will be between the Upper Bound (UB) and the Lower Bound (LB) computed for that item. +Specifically, (UB- LB) W * epsilon, where \(W\) denotes the sum of all item counts, and \(epsilon = 3.5/M\), where \(epsilon = M\) is the maxMapSize.

+

This is a worst-case guarantee that applies to arbitrary inputs. +For inputs typically seen in practice, (UB-LB) is usually much smaller.

+

Background

+

This code implements a variant of what is commonly known as the “Misra-Gries algorithm”. +Variants of it were discovered and rediscovered and redesigned several times over the years:

+
    +
  • Finding repeated elements, Misra, Gries, 1982

  • +
  • Frequency estimation of Internet packet streams with limited space Demaine, Lopez-Ortiz, Munro, 2002

  • +
  • A simple algorithm for finding frequent elements in streams and bags Karp, Shenker, Papadimitriou, 2003

  • +
  • Efficient Computation of Frequent and Top-k Elements in Data Streams Metwally, Agrawal, Abbadi, 2006

  • +
+

For speed, we do employ some randomization that introduces a small probability that our proof of the worst-case bound might not apply to a given run. +However, we have ensured that this probability is extremely small. +For example, if the stream causes one table purge (rebuild), our proof of the worst-case bound applies with a probability of at least 1 - 1E-14. +If the stream causes 1E9 purges, our proof applies with a probability of at least 1 - 1E-5.

+

There are two flavors of Frequent Items Sketches, one with generic items (objects) and another specific to strings. +The string version is a legacy name from before the library supported generic objects and is retained +only for backwards compatibility.

+
+

Note

+

The frequent_items_sketch uses an input object’s __hash__ and __eq__ methods.

+
+
+

Note

+

Serializing and deserializing the frequent_items_sketch requires the use of a PyObjectSerDe.

+
+
+
+class frequent_items_error_type(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
+
+
+NO_FALSE_POSITIVES : Returns only true positives but may miss some heavy hitters.
+
+ +
+
+NO_FALSE_NEGATIVES : Does not miss any heavy hitters but may return false positives.
+
+ +
+ +
+
+class frequent_items_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe) _datasketches.frequent_items_sketch
+

Reads a bytes object using the provided serde and returns the corresponding frequent_strings_sketch.

+
+ +
+
+get_epsilon_for_lg_size(lg_max_map_size: int) float
+

Returns the epsilon value used to compute a priori error for a given log2(max_map_size)

+
+ +
+
+get_apriori_error(lg_max_map_size: int, estimated_total_weight: int) float
+

Returns the estimated a priori error given the max_map_size for the sketch and the estimated_total_stream_weight.

+
+ +

Non-static Methods:

+
+
+__init__(self, lg_max_k: int) None
+

Creates an instance of the sketch

+
+
Parameters:
+

lg_max_k (int) – base 2 logarithm of the maximum size of the internal hash map of the sketch. Maximum capacity is 0.75 of this value, which is the maximum number of distinct items the sketch can contain.

+
+
+
+ +
+
+property epsilon
+

The epsilon value used by the sketch to compute error

+
+ +
+
+get_estimate
+

Returns the estimate of the weight (frequency) of the given item. +Note: The true frequency of a item would be the sum of the counts as a result of the two update functions.

+
+ +
+
+get_frequent_items
+
+ +
+
+get_lower_bound
+

Returns the guaranteed lower bound weight (frequency) of the given item.

+
+ +
+
+get_serialized_size_bytes
+

Computes the size needed to serialize the current state of the sketch using the provided serde. This can be expensive since every item needs to be looked at.

+
+ +
+
+get_upper_bound
+

Returns the guaranteed upper bound weight (frequency) of the given item.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+merge
+

Merges the given sketch into this one

+
+ +
+
+property num_active_items
+

The number of active items in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object using the provided serde.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+property total_weight
+

The sum of the weights (frequencies) in the stream seen so far by the sketch

+
+ +
+
+update
+

Updates the sketch with the given string and, optionally, a weight

+
+ +
+ +
+
+class frequent_strings_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.frequent_strings_sketch
+

Reads a bytes object and returns the corresponding frequent_strings_sketch.

+
+ +
+
+get_epsilon_for_lg_size(lg_max_map_size: int) float
+

Returns the epsilon value used to compute a priori error for a given log2(max_map_size)

+
+ +
+
+get_apriori_error(lg_max_map_size: int, estimated_total_weight: int) float
+

Returns the estimated a priori error given the max_map_size for the sketch and the estimated_total_stream_weight.

+
+ +

Non-static Methods:

+
+
+__init__(self, lg_max_k: int) None
+

Creates an instance of the sketch

+
+
Parameters:
+

lg_max_k (int) – base 2 logarithm of the maximum size of the internal hash map of the sketch. Maximum capacity is 0.75 of this value, which is the maximum number of distinct items the sketch can contain.

+
+
+
+ +
+
+property epsilon
+

The epsilon value used by the sketch to compute error

+
+ +
+
+get_estimate
+

Returns the estimate of the weight (frequency) of the given item. +Note: The true frequency of a item would be the sum of the counts as a result of the two update functions.

+
+ +
+
+get_frequent_items
+
+ +
+
+get_lower_bound
+

Returns the guaranteed lower bound weight (frequency) of the given item.

+
+ +
+
+get_serialized_size_bytes
+

Computes the size needed to serialize the current state of the sketch. This can be expensive since every item needs to be looked at.

+
+ +
+
+get_upper_bound
+

Returns the guaranteed upper bound weight (frequency) of the given item.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+merge
+

Merges the given sketch into this one

+
+ +
+
+property num_active_items
+

The number of active items in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+property total_weight
+

The sum of the weights (frequencies) in the stream seen so far by the sketch

+
+ +
+
+update
+

Updates the sketch with the given string and, optionally, a weight

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.1/frequency/index.html b/docs/5.1.1/frequency/index.html new file mode 100644 index 00000000..0f2d425e --- /dev/null +++ b/docs/5.1.1/frequency/index.html @@ -0,0 +1,143 @@ + + + + + + + + + Frequency Sketches — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Frequency Sketches

+

Frequency estimation involves determining how often an item has been seen in a stream. The library currently +offers two types of sketches for frequency estimation, one of which has two closely-related variants.

+
+
    +
  • frequent_items_sketch: Identifies the Top K or heavy hitters in a stream, those items whose weight is above a certain percentage of the entire stream. Does not necessarily provide an estimate for most items outside the heavy hitters.

  • +
  • frequent_strings_sketch: Like the items version but containing snly strings (an implementation from before the library handled generic objects).

  • +
  • count_min_sketch: Provides an estimate for any item, regardless of relative weight, but does not maintain a list of the heaviest items.

  • +
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.1/genindex.html b/docs/5.1.1/genindex.html new file mode 100644 index 00000000..ade0a896 --- /dev/null +++ b/docs/5.1.1/genindex.html @@ -0,0 +1,1388 @@ + + + + + + + + Index — datasketches 0.1 documentation + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ + +

Index

+ +
+ _ + | A + | C + | D + | E + | F + | G + | H + | I + | J + | K + | L + | M + | N + | P + | Q + | R + | S + | T + | U + | V + +
+

_

+ + +
+ +

A

+ + +
+ +

C

+ + + +
+ +

D

+ + + +
+ +

E

+ + + +
+ +

F

+ + + +
+ +

G

+ + + +
+ +

H

+ + + +
+ +

I

+ + + +
+ +

J

+ + +
+ +

K

+ + + +
+ +

L

+ + + +
+ +

M

+ + + +
+ +

N

+ + + +
+ +

P

+ + + +
+ +

Q

+ + + +
+ +

R

+ + +
+ +

S

+ + + +
+ +

T

+ + + +
+ +

U

+ + + +
+ +

V

+ + + +
+ + + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.1/helper/index.html b/docs/5.1.1/helper/index.html new file mode 100644 index 00000000..70a0b1a0 --- /dev/null +++ b/docs/5.1.1/helper/index.html @@ -0,0 +1,152 @@ + + + + + + + + + Helper Classes — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Helper Classes

+

These classes are required for certain sketches or specific +functionality within sketches. +Some of them are abstract base classes, but in those cases there is at +least one reference example of a concrete class.

+
+
    +
  • serde is used when serializing and deserializing sketches.

  • +
  • jaccard is used to compute the Jaccard similarity between pairs of theta or tuple sketches.

  • +
  • tuple_policy is required to use a tuple_sketch by specifying how summaries are combined.

  • +
  • ks_test() performs a Kolmogorov-Smirnov test on absolute-error quantiles family sketches.

  • +
  • kernel_function is required when using a kernel_sketch for Kernel Density Estimation.

  • +
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.1/helper/jaccard.html b/docs/5.1.1/helper/jaccard.html new file mode 100644 index 00000000..35b7d22a --- /dev/null +++ b/docs/5.1.1/helper/jaccard.html @@ -0,0 +1,210 @@ + + + + + + + + + Jaccard Similarity — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Jaccard Similarity

+

These objects provide measures related to the Jaccard similarity +of theta_sketch and tuple_sketch objects.

+

Note that there are separate classes to be used for theta and tuple sketches.

+
+
+class theta_jaccard_similarity
+

An object to help compute Jaccard similarity between theta sketches.

+
+
+jaccard(sketch_a: _datasketches.theta_sketch, sketch_b: _datasketches.theta_sketch, seed: int = 9001) list[float]
+

Returns a list with {lower_bound, estimate, upper_bound} of the Jaccard similarity between sketches

+
+ +
+
+exactly_equal(sketch_a: _datasketches.theta_sketch, sketch_b: _datasketches.theta_sketch, seed: int = 9001) bool
+

Returns True if sketch_a and sketch_b are equivalent, otherwise False

+
+ +
+
+similarity_test(actual: _datasketches.theta_sketch, expected: _datasketches.theta_sketch, threshold: float, seed: int = 9001) bool
+

Tests similarity of an actual sketch against an expected sketch. Computers the lower bound of the Jaccard index J_{LB} of the actual and expected sketches. If J_{LB} >= threshold, then the sketches are considered to be similar with a confidence of 97.7% and returns True, otherwise False.

+
+ +
+
+dissimilarity_test(actual: _datasketches.theta_sketch, expected: _datasketches.theta_sketch, threshold: float, seed: int = 9001) bool
+

Tests dissimilarity of an actual sketch against an expected sketch. Computers the lower bound of the Jaccard index J_{UB} of the actual and expected sketches. If J_{UB} <= threshold, then the sketches are considered to be dissimilar with a confidence of 97.7% and returns True, otherwise False.

+
+ +
+ +
+
+class tuple_jaccard_similarity
+

An object to help compute Jaccard similarity between tuple sketches.

+
+
+jaccard(sketch_a: _datasketches.tuple_sketch, sketch_b: _datasketches.tuple_sketch, seed: int = 9001) list[float]
+

Returns a list with {lower_bound, estimate, upper_bound} of the Jaccard similarity between sketches

+
+ +
+
+exactly_equal(sketch_a: _datasketches.tuple_sketch, sketch_b: _datasketches.tuple_sketch, seed: int = 9001) bool
+

Returns True if sketch_a and sketch_b are equivalent, otherwise False

+
+ +
+
+similarity_test(actual: _datasketches.tuple_sketch, expected: _datasketches.tuple_sketch, threshold: float, seed: int = 9001) bool
+

Tests similarity of an actual sketch against an expected sketch. Computes the lower bound of the Jaccard index J_{LB} of the actual and expected sketches. If J_{LB} >= threshold, then the sketches are considered to be similar with a confidence of 97.7% and returns True, otherwise False.

+
+ +
+
+dissimilarity_test(actual: _datasketches.tuple_sketch, expected: _datasketches.tuple_sketch, threshold: float, seed: int = 9001) bool
+

Tests dissimilarity of an actual sketch against an expected sketch. Computes the upper bound of the Jaccard index J_{UB} of the actual and expected sketches. If J_{UB} <= threshold, then the sketches are considered to be dissimilar with a confidence of 97.7% and returns True, otherwise False.

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.1/helper/kernel.html b/docs/5.1.1/helper/kernel.html new file mode 100644 index 00000000..dd69805b --- /dev/null +++ b/docs/5.1.1/helper/kernel.html @@ -0,0 +1,182 @@ + + + + + + + + + Kernel Function — datasketches 0.1 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Kernel Function

+

A kernel function is a specific type of +mathematical funciton that is particularly useful in certain machine learning and pattern recognition +contexts. The density_sketch performs approximate +kernel density estimation which, unsurprisingly, +relies on the use of such a kernel function.

+

The library provides an abstract base class KernelFunction and an example implementation of a +Gaussian (also known as a Radial Basis Function) kernel. Custom classes must override the base class +and provide a floating point value as a score indicating the similarity of two input vectors.

+
+
+class KernelFunction(*args, **kwargs)
+

A generic base class from which user-defined kernels must inherit.

+
+
+__call__(self, a: object, b: object) float
+

A method to evaluate a kernel with given inputs a and b.

+
+
Parameters:
+
    +
  • a (numpy array) – An input vector

  • +
  • b (numpy array) – An input vector

  • +
+
+
Returns:
+

A vector similarity score

+
+
Return type:
+

float

+
+
+
+ +
+ +
+
+class GaussianKernel(bandwidth: float = 1.0)
+

Bases: KernelFunction

+

Implements a basic Gaussian kernel

+
+
Parameters:
+

bandwidth (float) – The kernel bandwidth, default 1.0

+
+
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.1/helper/ks_test.html b/docs/5.1.1/helper/ks_test.html new file mode 100644 index 00000000..32cda6da --- /dev/null +++ b/docs/5.1.1/helper/ks_test.html @@ -0,0 +1,208 @@ + + + + + + + + + Kolmogorov-Smirnov Test — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Kolmogorov-Smirnov Test

+

A Kolmogorov-Smirnov Test <https://en.wikipedia.org/wiki/Kolmogorov%E2%80%93Smirnov_test>`_ is +a test of equality of two distributions to determine if they are likely to have come from the same +underlying distribution. +The DataSketches library provides a modified form of the test that takes into account the error +in each underlying sketch in the analysis.

+

Currently, the test assumes both input sketches are of the same family and data type.

+
+
+ks_test(sk_1: _datasketches.kll_ints_sketch, sk_2: _datasketches.kll_ints_sketch, p: float) bool
+
+ks_test(sk_1: _datasketches.kll_floats_sketch, sk_2: _datasketches.kll_floats_sketch, p: float) bool
+
+ks_test(sk_1: _datasketches.kll_doubles_sketch, sk_2: _datasketches.kll_doubles_sketch, p: float) bool
+
+ks_test(sk_1: _datasketches.kll_items_sketch, sk_2: _datasketches.kll_items_sketch, p: float) bool
+
+ks_test(sk_1: _datasketches.quantiles_ints_sketch, sk_2: _datasketches.quantiles_ints_sketch, p: float) bool
+
+ks_test(sk_1: _datasketches.quantiles_floats_sketch, sk_2: _datasketches.quantiles_floats_sketch, p: float) bool
+
+ks_test(sk_1: _datasketches.quantiles_doubles_sketch, sk_2: _datasketches.quantiles_doubles_sketch, p: float) bool
+
+ks_test(sk_1: _datasketches.quantiles_items_sketch, sk_2: _datasketches.quantiles_items_sketch, p: float) bool
+

Overloaded function.

+
    +
  1. ks_test(sk_1: _datasketches.kll_ints_sketch, sk_2: _datasketches.kll_ints_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for kll_ints_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
    +
  1. ks_test(sk_1: _datasketches.kll_floats_sketch, sk_2: _datasketches.kll_floats_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for kll_floats_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
    +
  1. ks_test(sk_1: _datasketches.kll_doubles_sketch, sk_2: _datasketches.kll_doubles_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for kll_doubles_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
    +
  1. ks_test(sk_1: _datasketches.kll_items_sketch, sk_2: _datasketches.kll_items_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for kll_items_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
    +
  1. ks_test(sk_1: _datasketches.quantiles_ints_sketch, sk_2: _datasketches.quantiles_ints_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for quantiles_ints_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
    +
  1. ks_test(sk_1: _datasketches.quantiles_floats_sketch, sk_2: _datasketches.quantiles_floats_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for quantiles_floats_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +:Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
    +
  1. ks_test(sk_1: _datasketches.quantiles_doubles_sketch, sk_2: _datasketches.quantiles_doubles_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for quantiles_doubles_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
    +
  1. ks_test(sk_1: _datasketches.quantiles_items_sketch, sk_2: _datasketches.quantiles_items_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for quantiles_items_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.1/helper/serde.html b/docs/5.1.1/helper/serde.html new file mode 100644 index 00000000..5820b427 --- /dev/null +++ b/docs/5.1.1/helper/serde.html @@ -0,0 +1,251 @@ + + + + + + + + + Serialize/Deserialize (SerDe) — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Serialize/Deserialize (SerDe)

+

A SerDe is a class used to serialize items sketches to a bytes object in binary. +Several example SerDes are provided as references.

+

The use of binary-compatible SerDes in different languages is critical for cross-language compatibility.

+

Each implementation must extend the PyObjectSerDe class and override all three of its methods.

+
+
+class PyObjectSerDe(*args, **kwargs)
+

An abstract base class for serde objects. All custom serdes must extend this class.

+
+
+get_size(self, item: object) int
+

Returns the size in bytes of an item

+
+
Parameters:
+

item (object) – The specified object

+
+
Returns:
+

The size of the item in bytes

+
+
Return type:
+

int

+
+
+
+ +
+
+to_bytes(self, item: object) bytes
+

Retuns a bytes object with a serialized version of an item

+
+
Parameters:
+

item (object) – The specified object

+
+
Returns:
+

A bytes object with the serialized object

+
+
Return type:
+

bytes

+
+
+
+ +
+
+from_bytes(self, data: bytes, offset: int) tuple
+

Reads a bytes object starting from the given offest and returns a tuple of the reconstructed object and the number of additional bytes read

+
+
Parameters:
+
    +
  • data (bytes) – A bytes object from which to deserialize

  • +
  • offset (int) – The offset, in bytes, at which to start reading

  • +
+
+
Returns:
+

A tuple with the reconstructed object and the number of bytes read

+
+
Return type:
+

tuple(object, int)

+
+
+
+ +
+ +

The provided SerDes are:

+
+
+class PyStringsSerDe(*args, **kwargs)
+

Bases: PyObjectSerDe

+

Implements a simple string-encoding scheme where a string is +written as <num_bytes> <string_contents>, with no null termination. +This format allows pre-allocating each string, at the cost of +additional storage. Using this format, the serialized string consumes +4 + len(item) bytes.

+
+ +
+
+class PyIntsSerDe(*args, **kwargs)
+

Bases: PyObjectSerDe

+

Implements an integer encoding scheme where each integer is written +as a 32-bit (4 byte) little-endian value.

+
+ +
+
+class PyLongsSerDe(*args, **kwargs)
+

Bases: PyObjectSerDe

+

Implements an integer encoding scheme where each integer is written +as a 64-bit (8 byte) little-endian value.

+
+ +
+
+class PyFloatsSerDe(*args, **kwargs)
+

Bases: PyObjectSerDe

+

Implements a floating point encoding scheme where each value is written +as a 32-bit floating point value.

+
+ +
+
+class PyDoublesSerDe(*args, **kwargs)
+

Implements a floating point encoding scheme where each value is written +as a 64-bit floating point value.

+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.1/helper/tuple_policy.html b/docs/5.1.1/helper/tuple_policy.html new file mode 100644 index 00000000..81ccdd37 --- /dev/null +++ b/docs/5.1.1/helper/tuple_policy.html @@ -0,0 +1,228 @@ + + + + + + + + + Tuple Policy — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Tuple Policy

+

A Tuple Policy is needed when using a tuple_sketch in order to specify how the +summary values should be created, updated, combined, or intersected. A summary can consist of +any python object.

+

Each implementation must extend the abstract base class TuplePolicy.

+
+
+class TuplePolicy(*args, **kwargs)
+

An abstract base class for Tuple Policy objects. All custom policies must extend this class.

+
+
+create_summary(self) object
+

Creates a new Summary object

+
+
Returns:
+

a Summary object

+
+
Return type:
+

object

+
+
+
+ +
+
+update_summary(self, summary: object, update: object) object
+

Applies the relevant policy to update the provided summary with the data in update.

+
+
Parameters:
+
    +
  • summary (object) – An existing Summary

  • +
  • update (object) – An update to apply to the Summary

  • +
+
+
Returns:
+

The updated Summary

+
+
Return type:
+

object

+
+
+
+ +
+
+__call__(self, summary: object, update: object) object
+

Similar to update_summary but allows a different implementation for set operations (union and intersection)

+
+
Parameters:
+
    +
  • summary (object) – An existing Summary

  • +
  • update (object) – An update to apply to the Summary

  • +
+
+
Returns:
+

The updated Summary

+
+
Return type:
+

object

+
+
+
+ +
+ +
+
+class AccumulatorPolicy
+

Bases: TuplePolicy

+

Implements an accumulatory summary policy, where new values +are added to the existing value.

+
+ +
+
+class MinIntPolicy
+

Bases: TuplePolicy

+

Implements a MIN rule, where the smallest integer value is always kept.

+
+ +
+
+class MaxIntPolicy
+

Bases: TuplePolicy

+

Implements a MAX rule, where the largest integer value is always kept.

+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.1/index.html b/docs/5.1.1/index.html new file mode 100644 index 00000000..a95e41a0 --- /dev/null +++ b/docs/5.1.1/index.html @@ -0,0 +1,213 @@ + + + + + + + + + Apache DataSketches — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Apache DataSketches

+

DataSketches are highly-efficient algorithms to analyze big data quickly.

+
+

Counting Distincts

+ +
+
+

Quantile Estimation

+ +
+
+

Frequency Sketches

+

This problem may also be known as heavy hitters or TopK

+ +
+
+

Vector Sketches

+ +
+
+

Random Sampling

+ +
+
+

Helper Classes

+ +
+

Note

+

This project is under active development.

+
+
+
+
+

Indices and tables

+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.1/objects.inv b/docs/5.1.1/objects.inv new file mode 100644 index 00000000..3eb72db6 Binary files /dev/null and b/docs/5.1.1/objects.inv differ diff --git a/docs/5.1.1/quantiles/index.html b/docs/5.1.1/quantiles/index.html new file mode 100644 index 00000000..be6fdc80 --- /dev/null +++ b/docs/5.1.1/quantiles/index.html @@ -0,0 +1,152 @@ + + + + + + + + + Quantiles Sketches — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Quantiles Sketches

+

Quantile estimation is useful for understanding the distribution of data values in a stream. The sketches currently +in the library are designed to answer queries about the rank of an item in the stream of items. That is, when +applying a global ordering on all the items, what is the portion of items seen so far that are less than (alternatively, +less-than-or-equal-to) the given item. Using straightforward logic, they can also estimate the item at a given rank +in the stream.

+

These sketches may be used to compute approximate histograms, Probability Mass Functions (PMFs), or +Cumulative Distribution Functions (CDFs).

+

The library provides three types of quantiles sketches, each of which has generic items as well as versions +specific to a given numeric type (e.g. integer or floating point values). All three types provide error +bounds on rank estimation with proven probabilistic error distributions.

+
+
    +
  • KLL: Provides uniform rank estimation error over the entire range

  • +
  • REQ: Provides relative rank error estimates, which decreases approaching either the high or low end values.

  • +
  • Classic quantiles: Largely deprecated in favor of KLL, also provides uniform rank estimation error. Included largely for backwards compatibility with historic data.

  • +
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.1/quantiles/kll.html b/docs/5.1.1/quantiles/kll.html new file mode 100644 index 00000000..66e5bb62 --- /dev/null +++ b/docs/5.1.1/quantiles/kll.html @@ -0,0 +1,962 @@ + + + + + + + + + KLL Sketch — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

KLL Sketch

+

Implementation of a very compact quantiles sketch with lazy compaction scheme +and nearly optimal accuracy per retained item. +See Optimal Quantile Approximation in Streams.

+

This is a stochastic streaming sketch that enables near real-time analysis of the +approximate distribution of items from a very large stream in a single pass, requiring only +that the items are comparable. +The analysis is obtained using get_quantile() function or the +inverse functions get_rank(), get_pmf() (Probability Mass Function), and get_cdf() +(Cumulative Distribution Function).

+

As of May 2020, this implementation produces serialized sketches which are binary-compatible +with the equivalent Java implementation only when template parameter T = float +(32-bit single precision values).

+

Given an input stream of N items, the natural rank of any specific +item is defined as its index (1 to N) in inclusive mode +or (0 to N-1) in exclusive mode +in the hypothetical sorted stream of all N input items.

+

The normalized rank (rank) of any specific item is defined as its +natural rank divided by N. +Thus, the normalized rank is between zero and one. +In the documentation for this sketch natural rank is never used so any +reference to just rank should be interpreted to mean normalized rank.

+

This sketch is configured with a parameter k, which affects the size of the sketch +and its estimation error.

+

The estimation error is commonly called epsilon (or eps) and is a fraction +between zero and one. Larger values of k result in smaller values of epsilon. +Epsilon is always with respect to the rank and cannot be applied to the +corresponding items.

+

The relationship between the normalized rank and the corresponding items can be viewed +as a two-dimensional monotonic plot with the normalized rank on one axis and the +corresponding items on the other axis. If the y-axis is specified as the item-axis and +the x-axis as the normalized rank, then y = get_quantile(x) is a monotonically +increasing function.

+

The function get_quantile(rank) translates ranks into +corresponding quantiles. The functions get_rank(item), +get_cdf(…) (Cumulative Distribution Function), and get_pmf(…) +(Probability Mass Function) perform the opposite operation and translate items into ranks.

+

The get_pmf(…) function has about 13 to 47% worse rank error (depending +on k) than the other queries because the mass of each “bin” of the PMF has +“double-sided” error from the upper and lower edges of the bin as a result of a subtraction, +as the errors from the two edges can sometimes add.

+

The default k of 200 yields a “single-sided” epsilon of about 1.33% and a +“double-sided” (PMF) epsilon of about 1.65%.

+

A get_quantile(rank) query has the following guarantees: +- Let q = get_quantile(r) where r is the rank between zero and one. +- The quantile q will be an item from the input stream. +- Let true_rank be the true rank of q derived from the hypothetical sorted +stream of all N items. +- Let eps = get_normalized_rank_error(false). +- Then r - eps ≤ true_rank ≤ r + eps with a confidence of 99%. Note that the +error is on the rank, not the quantile.

+

A get_rank(item) query has the following guarantees: +- Let r = get_rank(i) where i is an item between the min and max items of +the input stream. +- Let true_rank be the true rank of i derived from the hypothetical sorted +stream of all N items. +- Let eps = get_normalized_rank_error(false). +- Then r - eps ≤ true_rank ≤ r + eps with a confidence of 99%.

+

A get_pmf() query has the following guarantees: +- Let {r1, r2, …, r(m+1)} = get_pmf(s1, s2, …, sm) where s1, s2 are +split points (items from the input domain) between the min and max items of +the input stream. +- Let mass_i = estimated mass between s_i and s_i+1. +- Let true_mass be the true mass between the items of s_i, +s_i+1 derived from the hypothetical sorted stream of all N items. +- Let eps = get_normalized_rank_error(true). +- then mass - eps ≤ true_mass ≤ mass + eps with a confidence of 99%. +- r(m+1) includes the mass of all points larger than s_m.

+

A get_cdf(…) query has the following guarantees; +- Let {r1, r2, …, r(m+1)} = get_cdf(s1, s2, …, sm) where s1, s2, … are +split points (items from the input domain) between the min and max items of +the input stream. +- Let mass_i = r_(i+1) - r_i. +- Let true_mass be the true mass between the true ranks of s_i, +s_i+1 derived from the hypothetical sorted stream of all N items. +- Let eps = get_normalized_rank_error(true). +- then mass - eps ≤ true_mass ≤ mass + eps with a confidence of 99%. +- 1 - r(m+1) includes the mass of all points larger than s_m.

+

From the above, it might seem like we could make some estimates to bound the +item returned from a call to get_quantile(). The sketch, however, does not +let us derive error bounds or confidences around items. Because errors are independent, we +can approximately bracket a value as shown below, but there are no error estimates available. +Additionally, the interval may be quite large for certain distributions. +- Let q = get_quantile(r), the estimated quantile of rank r. +- Let eps = get_normalized_rank_error(false). +- Let q_lo = estimated quantile of rank (r - eps). +- Let q_hi = estimated quantile of rank (r + eps). +- Then q_lo ≤ q ≤ q_hi, with 99% confidence.

+
+

Note

+

For the kll_items_sketch, objects must be comparable with __lt__.

+
+
+

Note

+

Serializing and deserializing a kll_items_sketch requires the use of a PyObjectSerDe.

+
+
+
+class kll_ints_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.kll_ints_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 200) None
+

Creates a KLL sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 200.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given normalized rank in a hypothetical sorted version of the input stream so far. +For kll_floats_sketch: if the sketch is empty this returns nan. For kll_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: int) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=int32]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class kll_floats_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.kll_floats_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 200) None
+

Creates a KLL sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 200.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given normalized rank in a hypothetical sorted version of the input stream so far. +For kll_floats_sketch: if the sketch is empty this returns nan. For kll_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: float) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=float32]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class kll_doubles_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.kll_doubles_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 200) None
+

Creates a KLL sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 200.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given normalized rank in a hypothetical sorted version of the input stream so far. +For kll_floats_sketch: if the sketch is empty this returns nan. For kll_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: float) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=float64]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class kll_items_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe) _datasketches.kll_items_sketch
+

Deserializes the sketch from a bytes object using the provided serde.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 200) None
+

Creates a KLL sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 200.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given normalized rank in a hypothetical sorted version of the input stream so far. +For kll_floats_sketch: if the sketch is empty this returns nan. For kll_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object using the provided serde.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Updates the sketch with the given value

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.1/quantiles/quantiles_depr.html b/docs/5.1.1/quantiles/quantiles_depr.html new file mode 100644 index 00000000..774cfa19 --- /dev/null +++ b/docs/5.1.1/quantiles/quantiles_depr.html @@ -0,0 +1,901 @@ + + + + + + + + + Quantiles Sketch (Deprecated) — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Quantiles Sketch (Deprecated)

+

This is a deprecated quantiles sketch that is included for cross-language compatibility. +Most new projects will favor the KLL sketch over this one, or the REQ sketch for higher accuracy +at the very edge of a distribution.

+

This is a stochastic streaming sketch that enables near-real time analysis of the +approximate distribution from a very large stream in a single pass. +The analysis is obtained using get_rank() and get_quantile() functions, +the Probability Mass Function from get_pmf()` and the Cumulative Distribution Function from get_cdf.

+

Consider a large stream of one million values such as packet sizes coming into a network node. +The natural rank of any specific size value is its index in the hypothetical sorted +array of values. +The normalized rank is the natural rank divided by the stream size, +in this case one million. +The value corresponding to the normalized rank of 0.5 represents the 50th percentile or median +value of the distribution, or get_quantile(0.5). +Similarly, the 95th percentile is obtained from get_quantile(0.95).

+

From the min and max values, for example, 1 and 1000 bytes, +you can obtain the PMF from get_pmf(100, 500, 900) that will result in an array of +4 fractional values such as {.4, .3, .2, .1}, which means that +40% of the values were < 100, +30% of the values were ≥ 100 and < 500, +20% of the values were ≥ 500 and < 900, and +10% of the values were ≥ 900. +A frequency histogram can be obtained by multiplying these fractions by get_n(), +which is the total count of values received. +The get_cdf()` works similarly, but produces the cumulative distribution instead.

+

As of November 2021, this implementation produces serialized sketches which are binary-compatible +with the equivalent Java implementation only when template parameter T = double +(64-bit double precision values).

+

The accuracy of this sketch is a function of the configured value k, which also affects +the overall size of the sketch. Accuracy of this quantile sketch is always with respect to +the normalized rank. A k of 128 produces a normalized, rank error of about 1.7%. +For example, the median item returned from get_quantile(0.5) will be between the actual items +from the hypothetically sorted array of input items at normalized ranks of 0.483 and 0.517, with +a confidence of about 99%.

+
+

Note

+

For the quantiles_items_sketch, objects must be comparable with __lt__.

+
+
+

Note

+

Serializing and deserializing a quantiles_items_sketch requires the use of a PyObjectSerDe.

+
+
+
+class quantiles_ints_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.quantiles_ints_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 128) None
+

Creates a classic quantiles sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 128.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given rank in a hypothetical sorted version of the input stream so far. +For quantiles_floats_sketch: if the sketch is empty this returns nan. For quantiles_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: int) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=int32]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class quantiles_floats_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.quantiles_floats_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 128) None
+

Creates a classic quantiles sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 128.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given rank in a hypothetical sorted version of the input stream so far. +For quantiles_floats_sketch: if the sketch is empty this returns nan. For quantiles_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: float) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=float32]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class quantiles_doubles_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.quantiles_doubles_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 128) None
+

Creates a classic quantiles sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 128.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given rank in a hypothetical sorted version of the input stream so far. +For quantiles_floats_sketch: if the sketch is empty this returns nan. For quantiles_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: float) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=float64]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class quantiles_items_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe) _datasketches.quantiles_items_sketch
+

Deserializes the sketch from a bytes object using the provided serde.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 128) None
+

Creates a classic quantiles sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 128.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given rank in a hypothetical sorted version of the input stream so far. +For quantiles_floats_sketch: if the sketch is empty this returns nan. For quantiles_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object using the provided serde.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Updates the sketch with the given value

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.1/quantiles/req.html b/docs/5.1.1/quantiles/req.html new file mode 100644 index 00000000..ca04c6cd --- /dev/null +++ b/docs/5.1.1/quantiles/req.html @@ -0,0 +1,752 @@ + + + + + + + + + Relative Error Quantiles (REQ) Sketch — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Relative Error Quantiles (REQ) Sketch

+

This is an implementation based on the paper “Relative Error Streaming Quantiles” by Graham Cormode, Zohar Karnin, Edo Liberty, Justin Thaler, Pavel Veselý, and loosely derived from a Python prototype written by Pavel Veselý.

+

This implementation differs from the algorithm described in the paper in the following:

+

The algorithm requires no upper bound on the stream length. +Instead, each relative-compactor counts the number of compaction operations performed so far (via variable state). +Initially, the relative-compactor starts with INIT_NUMBER_OF_SECTIONS. +Each time the number of compactions (variable state) exceeds 2^{numSections - 1}, we double numSections. +Note that after merging the sketch with another one variable state may not correspond to the number of compactions performed at a particular level, however, +since the state variable never exceeds the number of compactions, the guarantees of the sketch remain valid.

+

The size of each section (variable k and section_size in the code and parameter k in the paper) is +initialized with a number set by the user via variable k. +When the number of sections doubles, we decrease section_size by a factor of sqrt(2). +This is applied at each level separately. +Thus, when we double the number of sections, the nominal compactor size increases by a factor of approx. sqrt(2) (+/- rounding).

+

The merge operation here does not perform “special compactions”, which are used in the paper to allow for a tight mathematical analysis of the sketch. +This implementation provides a number of capabilities not discussed in the paper or provided in the Python prototype.

+

The Python prototype only implemented high accuracy for low ranks. This implementation provides the user with the ability to +choose either high rank accuracy or low rank accuracy at the time of sketch construction. +The Python prototype only implemented a comparison criterion of INCLUSIVE. +This implementation allows the user to use both the INCLUSIVE criterion and the EXCLUSIVE criterion. +This implementation provides extensive debug visibility into the operation of the sketch with two levels of detail output. +This is not only useful for debugging, but is a powerful tool to help users understand how the sketch works.

+
+

Note

+

For the req_items_sketch, objects must be comparable with __lt__.

+
+
+

Note

+

Serializing and deserializing a req_items_sketch requires the use of a PyObjectSerDe.

+
+
+
+class req_ints_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.req_ints_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_RSE(k: int, rank: float, is_hra: bool, n: int) float
+

Returns an a priori estimate of relative standard error (RSE, expressed as a number in [0,1]). Derived from Lemma 12 in http://arxiv.org/abs/2004.01668v2, but the constant factors have been modified based on empirical measurements, for a given value of parameter k. +Normalized rank must be a value between 0.0 and 1.0 (inclusive). If is_hra is True, uses high rank accuracy mode, else low rank accuracy. N is an estimate of the total number of points provided to the sketch.

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 12, is_hra: bool = True) None
+

Creates an REQ sketch instance with the given value of k.

+
+
Parameters:
+
    +
  • k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 12.

  • +
  • is_hra (bool, optional) – Specifies whether the skech has High Rank Accuracy (True) or Low Rank Accuracy. Default True.

  • +
+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, req_floats_sketch returns nan; req_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, req_floats_sketch returns nan; req_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given normalized rank in a hypothetical sorted version of the input stream so far. +For req_floats_sketch: if the sketch is empty this returns nan. For req_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+get_rank_lower_bound
+

Returns an approximate lower bound on the given normalized rank. +Normalized rank must be a value between 0.0 and 1.0 (inclusive); the number of standard deviations must be 1, 2, or 3.

+
+ +
+
+get_rank_upper_bound
+

Returns an approximate upper bound on the given normalized rank. +Normalized rank must be a value between 0.0 and 1.0 (inclusive); the number of standard deviations must be 1, 2, or 3.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+is_hra
+

Returns True if the sketch is in High Rank Accuracy mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: int) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=int32]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class req_floats_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.req_floats_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_RSE(k: int, rank: float, is_hra: bool, n: int) float
+

Returns an a priori estimate of relative standard error (RSE, expressed as a number in [0,1]). Derived from Lemma 12 in http://arxiv.org/abs/2004.01668v2, but the constant factors have been modified based on empirical measurements, for a given value of parameter k. +Normalized rank must be a value between 0.0 and 1.0 (inclusive). If is_hra is True, uses high rank accuracy mode, else low rank accuracy. N is an estimate of the total number of points provided to the sketch.

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 12, is_hra: bool = True) None
+

Creates an REQ sketch instance with the given value of k.

+
+
Parameters:
+
    +
  • k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 12.

  • +
  • is_hra (bool, optional) – Specifies whether the skech has High Rank Accuracy (True) or Low Rank Accuracy. Default True.

  • +
+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, req_floats_sketch returns nan; req_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, req_floats_sketch returns nan; req_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given normalized rank in a hypothetical sorted version of the input stream so far. +For req_floats_sketch: if the sketch is empty this returns nan. For req_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+get_rank_lower_bound
+

Returns an approximate lower bound on the given normalized rank. +Normalized rank must be a value between 0.0 and 1.0 (inclusive); the number of standard deviations must be 1, 2, or 3.

+
+ +
+
+get_rank_upper_bound
+

Returns an approximate upper bound on the given normalized rank. +Normalized rank must be a value between 0.0 and 1.0 (inclusive); the number of standard deviations must be 1, 2, or 3.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+is_hra
+

Returns True if the sketch is in High Rank Accuracy mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: float) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=float32]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class req_items_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe) _datasketches.req_items_sketch
+

Deserializes the sketch from a bytes object using the provided serde.

+
+ +
+
+get_RSE(k: int, rank: float, is_hra: bool, n: int) float
+

Returns an a priori estimate of relative standard error (RSE, expressed as a number in [0,1]). Derived from Lemma 12 in http://arxiv.org/abs/2004.01668v2, but the constant factors have been modified based on empirical measurements, for a given value of parameter k. +Normalized rank must be a value between 0.0 and 1.0 (inclusive). If is_hra is True, uses high rank accuracy mode, else low rank accuracy. N is an estimate of the total number of points provided to the sketch.

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 12, is_hra: bool = True) None
+

Creates an REQ sketch instance with the given value of k.

+
+
Parameters:
+
    +
  • k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 12.

  • +
  • is_hra (bool, optional) – Specifies whether the skech has High Rank Accuracy (True) or Low Rank Accuracy. Default True.

  • +
+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, req_floats_sketch returns nan; req_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, req_floats_sketch returns nan; req_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given normalized rank in a hypothetical sorted version of the input stream so far. +For req_floats_sketch: if the sketch is empty this returns nan. For req_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+get_rank_lower_bound
+

Returns an approximate lower bound on the given normalized rank. +Normalized rank must be a value between 0.0 and 1.0 (inclusive); the number of standard deviations must be 1, 2, or 3.

+
+ +
+
+get_rank_upper_bound
+

Returns an approximate upper bound on the given normalized rank. +Normalized rank must be a value between 0.0 and 1.0 (inclusive); the number of standard deviations must be 1, 2, or 3.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+is_hra
+

Returns True if the sketch is in High Rank Accuracy mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object using the provided serde.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Updates the sketch with the given value

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.1/sampling/ebpps.html b/docs/5.1.1/sampling/ebpps.html new file mode 100644 index 00000000..b8540b75 --- /dev/null +++ b/docs/5.1.1/sampling/ebpps.html @@ -0,0 +1,236 @@ + + + + + + + + + Exact and Bounded, Probabilitiy Proportional to Size (EBPPS) Sampling — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Exact and Bounded, Probabilitiy Proportional to Size (EBPPS) Sampling

+

An EBPPS sketch produces a randome sample of data from a stream of items, ensuring that the probability +of including an item is always exactly equal to the item’s size. The size of an item is defined as its +weight relative to the total weight of all items seen so far by the sketch. In contrast to VarOpt sampling, +this sketch may return fewer than k items in order to keep the probability of including an item strictly +proportional to its size.

+

This sketch is based on: B. Hentschel, P. J. Haas, Y. Tian +“Exact PPS Sampling with Bounded Sample Size”, +Information Processing Letters, 2023.

+

EBPPS sampling is related to reservoir sampling, but handles unequal item weights. +Feeding the sketch items with a uniform weight value will produce a sample equivalent to reservoir sampling.

+
+

Note

+

Serializing and deserializing this sketch requires the use of a PyObjectSerDe.

+
+
+
+class ebpps_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe) _datasketches.ebpps_sketch
+

Reads a bytes object and returns the corresponding ebpps_sketch

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int) None
+

Creates a new EBPPS sketch instance

+
+
Parameters:
+

k (int) – Maximum number of samples in the sketch

+
+
+
+ +
+
+property c
+

The expected number of samples returned upon a call to get_result() or the creation of an iterator. The number is a floating point value, where the fractional portion represents the probability of including a “partial item” from the sample. The value C should be no larger than the sketch’s configured value of k, although numerical precision limitations mean it may exceed k by double precision floating point error margins in certain cases.

+
+ +
+
+get_serialized_size_bytes
+

Computes the size in bytes needed to serialize the current sketch

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+property k
+

The sketch’s maximum configured sample size

+
+ +
+
+merge
+

Merges the sketch with the given sketch

+
+ +
+
+property n
+

The total stream length

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object

+
+ +
+
+to_string
+

Produces a string summary of the sketch and optionally prints the items

+
+ +
+
+update
+

Updates the sketch with the given value and weight

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.1/sampling/index.html b/docs/5.1.1/sampling/index.html new file mode 100644 index 00000000..9897f1cb --- /dev/null +++ b/docs/5.1.1/sampling/index.html @@ -0,0 +1,145 @@ + + + + + + + + + Random Sampling Sketches — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Random Sampling Sketches

+

These sketches are used to randomly sample items. The length of the input +stream does not need to be known in advance.

+

Both VarOpt (Variance Optimal) and EBPPS (Exact and Bounded, +Probability Proportional to Size) sketches will include sample items based on +each item’s weight relative to the weight of the entire stream but +they differ in details:

+
+
    +
  • ebpps_sketch ensures that the probability of including an item is always exactly proportional to the item’s weight.

  • +
  • var_opt_sketch optimizes for applying a predicate to the resulting sample such that the variance of the subset sum after applying the predicate is minimized, even if the inclusion probability differs somewhat from being proportional to the item’s weight.

  • +
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.1/sampling/varopt.html b/docs/5.1.1/sampling/varopt.html new file mode 100644 index 00000000..53afc9e5 --- /dev/null +++ b/docs/5.1.1/sampling/varopt.html @@ -0,0 +1,298 @@ + + + + + + + + + Variance Optimal Sampling (VarOpt) — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Variance Optimal Sampling (VarOpt)

+

A VarOpt sketch samples data from a stream of items. The sketch is desinged for optimal (minimum) +variance when querying the sketch to estimate subset sums of items matching a provided predicate. +The sketch will produce a sample of size k (or smaller if fewer items have been presented), with +the probability of including an item roughly corresponding it the item’s weight relative to the total +weight of all items presented to the sketch.

+

VarOpt sampling is related to reservoir sampling, with improved error bounds for subset sum estimation. +Feeding the sketch items with a uniform weight value will produce a sample equivalent to reservoir sampling.

+
+

Note

+

Serializing and deserializing this sketch requires the use of a PyObjectSerDe.

+
+
+
+class var_opt_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe) _datasketches.var_opt_sketch
+

Reads a bytes object and returns the corresponding var opt sketch

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int) None
+

Creates a new Var Opt sketch instance

+
+
Parameters:
+

k (int) – Maximum number of samples in the sketch

+
+
+
+ +
+
+estimate_subset_sum
+

Applies a provided predicate to the sketch and returns the estimated total weight matching the predicate, as well as upper and lower bounds on the estimate and the total weight processed by the sketch

+
+ +
+
+get_serialized_size_bytes
+

Computes the size in bytes needed to serialize the current sketch

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+property k
+

Returns the sketch’s maximum configured sample size

+
+ +
+
+property n
+

Returns the total stream length

+
+ +
+
+property num_samples
+

Returns the number of samples currently in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object

+
+ +
+
+to_string
+

Produces a string summary of the sketch and optionally prints the items

+
+ +
+
+update
+

Updates the sketch with the given value and weight

+
+ +
+ +
+
+class var_opt_union(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe) _datasketches.var_opt_union
+

Constructs a var opt union from the given bytes using the provided serde

+
+ +

Non-static Methods:

+
+
+__init__(self, max_k: int) None
+
+ +
+
+get_result
+

Returns a sketch corresponding to the union result

+
+ +
+
+get_serialized_size_bytes
+

Computes the size in bytes needed to serialize the current union

+
+ +
+
+reset
+

Resets the union to the empty state

+
+ +
+
+serialize
+

Serializes the union into a bytes object with the provided serde

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Updates the union with the given sketch

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.1/search.html b/docs/5.1.1/search.html new file mode 100644 index 00000000..46fb1b6d --- /dev/null +++ b/docs/5.1.1/search.html @@ -0,0 +1,134 @@ + + + + + + + + Search — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ + + + +
+ +
+ +
+
+ +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/docs/5.1.1/searchindex.js b/docs/5.1.1/searchindex.js new file mode 100644 index 00000000..8efec656 --- /dev/null +++ b/docs/5.1.1/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"alltitles": {"Apache DataSketches": [[14, null]], "Compressed Probabilistic Counting (CPC)": [[0, null]], "CountMin Sketch": [[5, null]], "Counting Distincts": [[14, "counting-distincts"]], "Density Sketch": [[22, null]], "Distinct Counting": [[2, null]], "Exact and Bounded, Probabilitiy Proportional to Size (EBPPS) Sampling": [[19, null]], "Frequency Sketches": [[7, null], [14, "frequency-sketches"]], "Frequent Items": [[6, null]], "Helper Classes": [[8, null], [14, "helper-classes"]], "HyperLogLog (HLL)": [[1, null]], "Indices and tables": [[14, "indices-and-tables"]], "Jaccard Similarity": [[9, null]], "KLL Sketch": [[16, null]], "Kernel Function": [[10, null]], "Kolmogorov-Smirnov Test": [[11, null]], "Quantile Estimation": [[14, "quantile-estimation"]], "Quantiles Sketch (Deprecated)": [[17, null]], "Quantiles Sketches": [[15, null]], "Random Sampling": [[14, "random-sampling"]], "Random Sampling Sketches": [[20, null]], "Relative Error Quantiles (REQ) Sketch": [[18, null]], "Serialize/Deserialize (SerDe)": [[12, null]], "Theta Sketch": [[3, null]], "Tuple Policy": [[13, null]], "Tuple Sketch": [[4, null]], "Variance Optimal Sampling (VarOpt)": [[21, null]], "Vector Sketches": [[14, "vector-sketches"], [23, null]]}, "docnames": ["distinct_counting/cpc", "distinct_counting/hyper_log_log", "distinct_counting/index", "distinct_counting/theta", "distinct_counting/tuple", "frequency/count_min_sketch", "frequency/frequent_items", "frequency/index", "helper/index", "helper/jaccard", "helper/kernel", "helper/ks_test", "helper/serde", "helper/tuple_policy", "index", "quantiles/index", "quantiles/kll", "quantiles/quantiles_depr", "quantiles/req", "sampling/ebpps", "sampling/index", "sampling/varopt", "vector/density_sketch", "vector/index"], "envversion": {"sphinx": 64, "sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2}, "filenames": ["distinct_counting/cpc.rst", "distinct_counting/hyper_log_log.rst", "distinct_counting/index.rst", "distinct_counting/theta.rst", "distinct_counting/tuple.rst", "frequency/count_min_sketch.rst", "frequency/frequent_items.rst", "frequency/index.rst", "helper/index.rst", "helper/jaccard.rst", "helper/kernel.rst", "helper/ks_test.rst", "helper/serde.rst", "helper/tuple_policy.rst", "index.rst", "quantiles/index.rst", "quantiles/kll.rst", "quantiles/quantiles_depr.rst", "quantiles/req.rst", "sampling/ebpps.rst", "sampling/index.rst", "sampling/varopt.rst", "vector/density_sketch.rst", "vector/index.rst"], "indexentries": {"__call__() (kernelfunction method)": [[10, "datasketches.KernelFunction.__call__", false]], "__call__() (tuplepolicy method)": [[13, "datasketches.TuplePolicy.__call__", false]], "__init__() (compact_theta_sketch method)": [[3, "datasketches.compact_theta_sketch.__init__", false]], "__init__() (compact_tuple_sketch method)": [[4, "datasketches.compact_tuple_sketch.__init__", false]], "__init__() (cpc_sketch method)": [[0, "datasketches.cpc_sketch.__init__", false]], "__init__() (cpc_union method)": [[0, "datasketches.cpc_union.__init__", false]], "__init__() (density_sketch method)": [[22, "datasketches.density_sketch.__init__", false]], "__init__() (ebpps_sketch method)": [[19, "datasketches.ebpps_sketch.__init__", false]], "__init__() (frequent_items_sketch method)": [[6, "datasketches.frequent_items_sketch.__init__", false]], "__init__() (frequent_strings_sketch method)": [[6, "datasketches.frequent_strings_sketch.__init__", false]], "__init__() (hll_sketch method)": [[1, "datasketches.hll_sketch.__init__", false]], "__init__() (hll_union method)": [[1, "datasketches.hll_union.__init__", false]], "__init__() (kll_doubles_sketch method)": [[16, "datasketches.kll_doubles_sketch.__init__", false]], "__init__() (kll_floats_sketch method)": [[16, "datasketches.kll_floats_sketch.__init__", false]], "__init__() (kll_ints_sketch method)": [[16, "datasketches.kll_ints_sketch.__init__", false]], "__init__() (kll_items_sketch method)": [[16, "datasketches.kll_items_sketch.__init__", false]], "__init__() (quantiles_doubles_sketch method)": [[17, "datasketches.quantiles_doubles_sketch.__init__", false]], "__init__() (quantiles_floats_sketch method)": [[17, "datasketches.quantiles_floats_sketch.__init__", false]], "__init__() (quantiles_ints_sketch method)": [[17, "datasketches.quantiles_ints_sketch.__init__", false]], "__init__() (quantiles_items_sketch method)": [[17, "datasketches.quantiles_items_sketch.__init__", false]], "__init__() (req_floats_sketch method)": [[18, "datasketches.req_floats_sketch.__init__", false]], "__init__() (req_ints_sketch method)": [[18, "datasketches.req_ints_sketch.__init__", false]], "__init__() (req_items_sketch method)": [[18, "datasketches.req_items_sketch.__init__", false]], "__init__() (theta_a_not_b method)": [[3, "datasketches.theta_a_not_b.__init__", false]], "__init__() (theta_intersection method)": [[3, "datasketches.theta_intersection.__init__", false]], "__init__() (theta_union method)": [[3, "datasketches.theta_union.__init__", false]], "__init__() (tuple_a_not_b method)": [[4, "datasketches.tuple_a_not_b.__init__", false]], "__init__() (tuple_intersection method)": [[4, "datasketches.tuple_intersection.__init__", false]], "__init__() (tuple_union method)": [[4, "datasketches.tuple_union.__init__", false]], "__init__() (update_theta_sketch method)": [[3, "datasketches.update_theta_sketch.__init__", false]], "__init__() (update_tuple_sketch method)": [[4, "datasketches.update_tuple_sketch.__init__", false]], "__init__() (var_opt_sketch method)": [[21, "datasketches.var_opt_sketch.__init__", false]], "__init__() (var_opt_union method)": [[21, "datasketches.var_opt_union.__init__", false]], "accumulatorpolicy (class in datasketches)": [[13, "datasketches.AccumulatorPolicy", false]], "c (ebpps_sketch property)": [[19, "datasketches.ebpps_sketch.c", false]], "compact (update_theta_sketch attribute)": [[3, "datasketches.update_theta_sketch.compact", false]], "compact (update_tuple_sketch attribute)": [[4, "datasketches.update_tuple_sketch.compact", false]], "compact_theta_sketch (class in datasketches)": [[3, "datasketches.compact_theta_sketch", false]], "compact_tuple_sketch (class in datasketches)": [[4, "datasketches.compact_tuple_sketch", false]], "compute (theta_a_not_b attribute)": [[3, "datasketches.theta_a_not_b.compute", false]], "compute (tuple_a_not_b attribute)": [[4, "datasketches.tuple_a_not_b.compute", false]], "count_min_sketch (class in _datasketches)": [[5, "datasketches.count_min_sketch", false]], "cpc_sketch (class in _datasketches)": [[0, "datasketches.cpc_sketch", false]], "cpc_union (class in _datasketches)": [[0, "datasketches.cpc_union", false]], "create_summary() (tuplepolicy method)": [[13, "datasketches.TuplePolicy.create_summary", false]], "default_seed (tuple_sketch attribute)": [[4, "datasketches.tuple_sketch.DEFAULT_SEED", false]], "density_sketch (class in datasketches)": [[22, "datasketches.density_sketch", false]], "deserialize() (compact_theta_sketch method)": [[3, "datasketches.compact_theta_sketch.deserialize", false]], "deserialize() (compact_tuple_sketch method)": [[4, "datasketches.compact_tuple_sketch.deserialize", false]], "deserialize() (count_min_sketch method)": [[5, "datasketches.count_min_sketch.deserialize", false]], "deserialize() (cpc_sketch method)": [[0, "datasketches.cpc_sketch.deserialize", false]], "deserialize() (density_sketch method)": [[22, "datasketches.density_sketch.deserialize", false]], "deserialize() (ebpps_sketch method)": [[19, "datasketches.ebpps_sketch.deserialize", false]], "deserialize() (frequent_items_sketch method)": [[6, "datasketches.frequent_items_sketch.deserialize", false]], "deserialize() (frequent_strings_sketch method)": [[6, "datasketches.frequent_strings_sketch.deserialize", false]], "deserialize() (hll_sketch method)": [[1, "datasketches.hll_sketch.deserialize", false]], "deserialize() (kll_doubles_sketch method)": [[16, "datasketches.kll_doubles_sketch.deserialize", false]], "deserialize() (kll_floats_sketch method)": [[16, "datasketches.kll_floats_sketch.deserialize", false]], "deserialize() (kll_ints_sketch method)": [[16, "datasketches.kll_ints_sketch.deserialize", false]], "deserialize() (kll_items_sketch method)": [[16, "datasketches.kll_items_sketch.deserialize", false]], "deserialize() (quantiles_doubles_sketch method)": [[17, "datasketches.quantiles_doubles_sketch.deserialize", false]], "deserialize() (quantiles_floats_sketch method)": [[17, "datasketches.quantiles_floats_sketch.deserialize", false]], "deserialize() (quantiles_ints_sketch method)": [[17, "datasketches.quantiles_ints_sketch.deserialize", false]], "deserialize() (quantiles_items_sketch method)": [[17, "datasketches.quantiles_items_sketch.deserialize", false]], "deserialize() (req_floats_sketch method)": [[18, "datasketches.req_floats_sketch.deserialize", false]], "deserialize() (req_ints_sketch method)": [[18, "datasketches.req_ints_sketch.deserialize", false]], "deserialize() (req_items_sketch method)": [[18, "datasketches.req_items_sketch.deserialize", false]], "deserialize() (var_opt_sketch method)": [[21, "datasketches.var_opt_sketch.deserialize", false]], "deserialize() (var_opt_union method)": [[21, "datasketches.var_opt_union.deserialize", false]], "dim (density_sketch property)": [[22, "datasketches.density_sketch.dim", false]], "dissimilarity_test() (theta_jaccard_similarity method)": [[9, "datasketches.theta_jaccard_similarity.dissimilarity_test", false]], "dissimilarity_test() (tuple_jaccard_similarity method)": [[9, "datasketches.tuple_jaccard_similarity.dissimilarity_test", false]], "ebpps_sketch (class in datasketches)": [[19, "datasketches.ebpps_sketch", false]], "epsilon (frequent_items_sketch property)": [[6, "datasketches.frequent_items_sketch.epsilon", false]], "epsilon (frequent_strings_sketch property)": [[6, "datasketches.frequent_strings_sketch.epsilon", false]], "estimate_subset_sum (var_opt_sketch attribute)": [[21, "datasketches.var_opt_sketch.estimate_subset_sum", false]], "exactly_equal() (theta_jaccard_similarity method)": [[9, "datasketches.theta_jaccard_similarity.exactly_equal", false]], "exactly_equal() (tuple_jaccard_similarity method)": [[9, "datasketches.tuple_jaccard_similarity.exactly_equal", false]], "filter (compact_tuple_sketch attribute)": [[4, "datasketches.compact_tuple_sketch.filter", false]], "filter (update_tuple_sketch attribute)": [[4, "datasketches.update_tuple_sketch.filter", false]], "frequent_items_error_type (class in datasketches)": [[6, "datasketches.frequent_items_error_type", false]], "frequent_items_sketch (class in datasketches)": [[6, "datasketches.frequent_items_sketch", false]], "frequent_strings_sketch (class in datasketches)": [[6, "datasketches.frequent_strings_sketch", false]], "from_bytes() (pyobjectserde method)": [[12, "datasketches.PyObjectSerDe.from_bytes", false]], "gaussiankernel (class in datasketches)": [[10, "datasketches.GaussianKernel", false]], "get_apriori_error() (frequent_items_sketch method)": [[6, "datasketches.frequent_items_sketch.get_apriori_error", false]], "get_apriori_error() (frequent_strings_sketch method)": [[6, "datasketches.frequent_strings_sketch.get_apriori_error", false]], "get_cdf (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.get_cdf", false]], "get_cdf (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.get_cdf", false]], "get_cdf (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.get_cdf", false]], "get_cdf (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.get_cdf", false]], "get_cdf (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.get_cdf", false]], "get_cdf (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.get_cdf", false]], "get_cdf (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.get_cdf", false]], "get_cdf (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.get_cdf", false]], "get_cdf (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.get_cdf", false]], "get_cdf (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.get_cdf", false]], "get_cdf (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.get_cdf", false]], "get_compact_serialization_bytes (hll_sketch attribute)": [[1, "datasketches.hll_sketch.get_compact_serialization_bytes", false]], "get_epsilon_for_lg_size() (frequent_items_sketch method)": [[6, "datasketches.frequent_items_sketch.get_epsilon_for_lg_size", false]], "get_epsilon_for_lg_size() (frequent_strings_sketch method)": [[6, "datasketches.frequent_strings_sketch.get_epsilon_for_lg_size", false]], "get_estimate (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.get_estimate", false]], "get_estimate (cpc_sketch attribute)": [[0, "datasketches.cpc_sketch.get_estimate", false]], "get_estimate (density_sketch attribute)": [[22, "datasketches.density_sketch.get_estimate", false]], "get_estimate (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.get_estimate", false]], "get_estimate (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.get_estimate", false]], "get_estimate (hll_sketch attribute)": [[1, "datasketches.hll_sketch.get_estimate", false]], "get_estimate (hll_union attribute)": [[1, "datasketches.hll_union.get_estimate", false]], "get_estimate (theta_sketch attribute)": [[3, "datasketches.theta_sketch.get_estimate", false]], "get_estimate (tuple_sketch attribute)": [[4, "datasketches.tuple_sketch.get_estimate", false]], "get_frequent_items (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.get_frequent_items", false]], "get_frequent_items (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.get_frequent_items", false]], "get_lower_bound (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.get_lower_bound", false]], "get_lower_bound (cpc_sketch attribute)": [[0, "datasketches.cpc_sketch.get_lower_bound", false]], "get_lower_bound (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.get_lower_bound", false]], "get_lower_bound (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.get_lower_bound", false]], "get_lower_bound (hll_sketch attribute)": [[1, "datasketches.hll_sketch.get_lower_bound", false]], "get_lower_bound (hll_union attribute)": [[1, "datasketches.hll_union.get_lower_bound", false]], "get_lower_bound (theta_sketch attribute)": [[3, "datasketches.theta_sketch.get_lower_bound", false]], "get_lower_bound (tuple_sketch attribute)": [[4, "datasketches.tuple_sketch.get_lower_bound", false]], "get_max_updatable_serialization_bytes() (hll_sketch method)": [[1, "datasketches.hll_sketch.get_max_updatable_serialization_bytes", false]], "get_max_value (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.get_max_value", false]], "get_max_value (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.get_max_value", false]], "get_max_value (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.get_max_value", false]], "get_max_value (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.get_max_value", false]], "get_max_value (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.get_max_value", false]], "get_max_value (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.get_max_value", false]], "get_max_value (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.get_max_value", false]], "get_max_value (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.get_max_value", false]], "get_max_value (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.get_max_value", false]], "get_max_value (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.get_max_value", false]], "get_max_value (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.get_max_value", false]], "get_min_value (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.get_min_value", false]], "get_min_value (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.get_min_value", false]], "get_min_value (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.get_min_value", false]], "get_min_value (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.get_min_value", false]], "get_min_value (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.get_min_value", false]], "get_min_value (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.get_min_value", false]], "get_min_value (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.get_min_value", false]], "get_min_value (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.get_min_value", false]], "get_min_value (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.get_min_value", false]], "get_min_value (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.get_min_value", false]], "get_min_value (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.get_min_value", false]], "get_normalized_rank_error() (kll_doubles_sketch method)": [[16, "datasketches.kll_doubles_sketch.get_normalized_rank_error", false]], "get_normalized_rank_error() (kll_floats_sketch method)": [[16, "datasketches.kll_floats_sketch.get_normalized_rank_error", false]], "get_normalized_rank_error() (kll_ints_sketch method)": [[16, "datasketches.kll_ints_sketch.get_normalized_rank_error", false]], "get_normalized_rank_error() (kll_items_sketch method)": [[16, "datasketches.kll_items_sketch.get_normalized_rank_error", false]], "get_normalized_rank_error() (quantiles_doubles_sketch method)": [[17, "datasketches.quantiles_doubles_sketch.get_normalized_rank_error", false]], "get_normalized_rank_error() (quantiles_floats_sketch method)": [[17, "datasketches.quantiles_floats_sketch.get_normalized_rank_error", false]], "get_normalized_rank_error() (quantiles_ints_sketch method)": [[17, "datasketches.quantiles_ints_sketch.get_normalized_rank_error", false]], "get_normalized_rank_error() (quantiles_items_sketch method)": [[17, "datasketches.quantiles_items_sketch.get_normalized_rank_error", false]], "get_pmf (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.get_pmf", false]], "get_pmf (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.get_pmf", false]], "get_pmf (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.get_pmf", false]], "get_pmf (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.get_pmf", false]], "get_pmf (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.get_pmf", false]], "get_pmf (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.get_pmf", false]], "get_pmf (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.get_pmf", false]], "get_pmf (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.get_pmf", false]], "get_pmf (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.get_pmf", false]], "get_pmf (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.get_pmf", false]], "get_pmf (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.get_pmf", false]], "get_quantile (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.get_quantile", false]], "get_quantile (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.get_quantile", false]], "get_quantile (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.get_quantile", false]], "get_quantile (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.get_quantile", false]], "get_quantile (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.get_quantile", false]], "get_quantile (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.get_quantile", false]], "get_quantile (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.get_quantile", false]], "get_quantile (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.get_quantile", false]], "get_quantile (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.get_quantile", false]], "get_quantile (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.get_quantile", false]], "get_quantile (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.get_quantile", false]], "get_quantiles (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.get_quantiles", false]], "get_quantiles (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.get_quantiles", false]], "get_quantiles (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.get_quantiles", false]], "get_quantiles (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.get_quantiles", false]], "get_quantiles (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.get_quantiles", false]], "get_quantiles (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.get_quantiles", false]], "get_quantiles (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.get_quantiles", false]], "get_quantiles (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.get_quantiles", false]], "get_quantiles (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.get_quantiles", false]], "get_quantiles (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.get_quantiles", false]], "get_quantiles (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.get_quantiles", false]], "get_rank (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.get_rank", false]], "get_rank (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.get_rank", false]], "get_rank (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.get_rank", false]], "get_rank (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.get_rank", false]], "get_rank (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.get_rank", false]], "get_rank (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.get_rank", false]], "get_rank (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.get_rank", false]], "get_rank (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.get_rank", false]], "get_rank (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.get_rank", false]], "get_rank (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.get_rank", false]], "get_rank (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.get_rank", false]], "get_rank_lower_bound (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.get_rank_lower_bound", false]], "get_rank_lower_bound (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.get_rank_lower_bound", false]], "get_rank_lower_bound (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.get_rank_lower_bound", false]], "get_rank_upper_bound (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.get_rank_upper_bound", false]], "get_rank_upper_bound (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.get_rank_upper_bound", false]], "get_rank_upper_bound (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.get_rank_upper_bound", false]], "get_rel_err() (hll_sketch method)": [[1, "datasketches.hll_sketch.get_rel_err", false]], "get_rel_err() (hll_union method)": [[1, "datasketches.hll_union.get_rel_err", false]], "get_relative_error (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.get_relative_error", false]], "get_result (cpc_union attribute)": [[0, "datasketches.cpc_union.get_result", false]], "get_result (hll_union attribute)": [[1, "datasketches.hll_union.get_result", false]], "get_result (theta_intersection attribute)": [[3, "datasketches.theta_intersection.get_result", false]], "get_result (theta_union attribute)": [[3, "datasketches.theta_union.get_result", false]], "get_result (tuple_intersection attribute)": [[4, "datasketches.tuple_intersection.get_result", false]], "get_result (tuple_union attribute)": [[4, "datasketches.tuple_union.get_result", false]], "get_result (var_opt_union attribute)": [[21, "datasketches.var_opt_union.get_result", false]], "get_rse() (req_floats_sketch method)": [[18, "datasketches.req_floats_sketch.get_RSE", false]], "get_rse() (req_ints_sketch method)": [[18, "datasketches.req_ints_sketch.get_RSE", false]], "get_rse() (req_items_sketch method)": [[18, "datasketches.req_items_sketch.get_RSE", false]], "get_seed_hash (theta_sketch attribute)": [[3, "datasketches.theta_sketch.get_seed_hash", false]], "get_seed_hash (tuple_sketch attribute)": [[4, "datasketches.tuple_sketch.get_seed_hash", false]], "get_serialized_size_bytes (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.get_serialized_size_bytes", false]], "get_serialized_size_bytes (ebpps_sketch attribute)": [[19, "datasketches.ebpps_sketch.get_serialized_size_bytes", false]], "get_serialized_size_bytes (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.get_serialized_size_bytes", false]], "get_serialized_size_bytes (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.get_serialized_size_bytes", false]], "get_serialized_size_bytes (var_opt_sketch attribute)": [[21, "datasketches.var_opt_sketch.get_serialized_size_bytes", false]], "get_serialized_size_bytes (var_opt_union attribute)": [[21, "datasketches.var_opt_union.get_serialized_size_bytes", false]], "get_size() (pyobjectserde method)": [[12, "datasketches.PyObjectSerDe.get_size", false]], "get_updatable_serialization_bytes (hll_sketch attribute)": [[1, "datasketches.hll_sketch.get_updatable_serialization_bytes", false]], "get_upper_bound (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.get_upper_bound", false]], "get_upper_bound (cpc_sketch attribute)": [[0, "datasketches.cpc_sketch.get_upper_bound", false]], "get_upper_bound (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.get_upper_bound", false]], "get_upper_bound (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.get_upper_bound", false]], "get_upper_bound (hll_sketch attribute)": [[1, "datasketches.hll_sketch.get_upper_bound", false]], "get_upper_bound (hll_union attribute)": [[1, "datasketches.hll_union.get_upper_bound", false]], "get_upper_bound (theta_sketch attribute)": [[3, "datasketches.theta_sketch.get_upper_bound", false]], "get_upper_bound (tuple_sketch attribute)": [[4, "datasketches.tuple_sketch.get_upper_bound", false]], "has_result (theta_intersection attribute)": [[3, "datasketches.theta_intersection.has_result", false]], "has_result (tuple_intersection attribute)": [[4, "datasketches.tuple_intersection.has_result", false]], "hll_4 (tgt_hll_type attribute)": [[1, "datasketches.tgt_hll_type.HLL_4", false]], "hll_6 (tgt_hll_type attribute)": [[1, "datasketches.tgt_hll_type.HLL_6", false]], "hll_8 (tgt_hll_type attribute)": [[1, "datasketches.tgt_hll_type.HLL_8", false]], "hll_sketch (class in _datasketches)": [[1, "datasketches.hll_sketch", false]], "hll_union (class in _datasketches)": [[1, "datasketches.hll_union", false]], "is_compact (hll_sketch attribute)": [[1, "datasketches.hll_sketch.is_compact", false]], "is_empty (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.is_empty", false]], "is_empty (cpc_sketch attribute)": [[0, "datasketches.cpc_sketch.is_empty", false]], "is_empty (density_sketch attribute)": [[22, "datasketches.density_sketch.is_empty", false]], "is_empty (ebpps_sketch attribute)": [[19, "datasketches.ebpps_sketch.is_empty", false]], "is_empty (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.is_empty", false]], "is_empty (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.is_empty", false]], "is_empty (hll_sketch attribute)": [[1, "datasketches.hll_sketch.is_empty", false]], "is_empty (hll_union attribute)": [[1, "datasketches.hll_union.is_empty", false]], "is_empty (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.is_empty", false]], "is_empty (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.is_empty", false]], "is_empty (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.is_empty", false]], "is_empty (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.is_empty", false]], "is_empty (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.is_empty", false]], "is_empty (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.is_empty", false]], "is_empty (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.is_empty", false]], "is_empty (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.is_empty", false]], "is_empty (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.is_empty", false]], "is_empty (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.is_empty", false]], "is_empty (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.is_empty", false]], "is_empty (theta_sketch attribute)": [[3, "datasketches.theta_sketch.is_empty", false]], "is_empty (tuple_sketch attribute)": [[4, "datasketches.tuple_sketch.is_empty", false]], "is_empty (var_opt_sketch attribute)": [[21, "datasketches.var_opt_sketch.is_empty", false]], "is_estimation_mode (density_sketch attribute)": [[22, "datasketches.density_sketch.is_estimation_mode", false]], "is_estimation_mode (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.is_estimation_mode", false]], "is_estimation_mode (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.is_estimation_mode", false]], "is_estimation_mode (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.is_estimation_mode", false]], "is_estimation_mode (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.is_estimation_mode", false]], "is_estimation_mode (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.is_estimation_mode", false]], "is_estimation_mode (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.is_estimation_mode", false]], "is_estimation_mode (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.is_estimation_mode", false]], "is_estimation_mode (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.is_estimation_mode", false]], "is_estimation_mode (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.is_estimation_mode", false]], "is_estimation_mode (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.is_estimation_mode", false]], "is_estimation_mode (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.is_estimation_mode", false]], "is_estimation_mode (theta_sketch attribute)": [[3, "datasketches.theta_sketch.is_estimation_mode", false]], "is_estimation_mode (tuple_sketch attribute)": [[4, "datasketches.tuple_sketch.is_estimation_mode", false]], "is_hra (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.is_hra", false]], "is_hra (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.is_hra", false]], "is_hra (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.is_hra", false]], "is_ordered (theta_sketch attribute)": [[3, "datasketches.theta_sketch.is_ordered", false]], "is_ordered (tuple_sketch attribute)": [[4, "datasketches.tuple_sketch.is_ordered", false]], "jaccard() (theta_jaccard_similarity method)": [[9, "datasketches.theta_jaccard_similarity.jaccard", false]], "jaccard() (tuple_jaccard_similarity method)": [[9, "datasketches.tuple_jaccard_similarity.jaccard", false]], "k (density_sketch property)": [[22, "datasketches.density_sketch.k", false]], "k (ebpps_sketch property)": [[19, "datasketches.ebpps_sketch.k", false]], "k (kll_doubles_sketch property)": [[16, "datasketches.kll_doubles_sketch.k", false]], "k (kll_floats_sketch property)": [[16, "datasketches.kll_floats_sketch.k", false]], "k (kll_ints_sketch property)": [[16, "datasketches.kll_ints_sketch.k", false]], "k (kll_items_sketch property)": [[16, "datasketches.kll_items_sketch.k", false]], "k (quantiles_doubles_sketch property)": [[17, "datasketches.quantiles_doubles_sketch.k", false]], "k (quantiles_floats_sketch property)": [[17, "datasketches.quantiles_floats_sketch.k", false]], "k (quantiles_ints_sketch property)": [[17, "datasketches.quantiles_ints_sketch.k", false]], "k (quantiles_items_sketch property)": [[17, "datasketches.quantiles_items_sketch.k", false]], "k (req_floats_sketch property)": [[18, "datasketches.req_floats_sketch.k", false]], "k (req_ints_sketch property)": [[18, "datasketches.req_ints_sketch.k", false]], "k (req_items_sketch property)": [[18, "datasketches.req_items_sketch.k", false]], "k (var_opt_sketch property)": [[21, "datasketches.var_opt_sketch.k", false]], "kernelfunction (class in datasketches)": [[10, "datasketches.KernelFunction", false]], "kll_doubles_sketch (class in datasketches)": [[16, "datasketches.kll_doubles_sketch", false]], "kll_floats_sketch (class in datasketches)": [[16, "datasketches.kll_floats_sketch", false]], "kll_ints_sketch (class in datasketches)": [[16, "datasketches.kll_ints_sketch", false]], "kll_items_sketch (class in datasketches)": [[16, "datasketches.kll_items_sketch", false]], "ks_test() (in module datasketches)": [[11, "datasketches.ks_test", false]], "lg_config_k (hll_sketch property)": [[1, "datasketches.hll_sketch.lg_config_k", false]], "lg_config_k (hll_union property)": [[1, "datasketches.hll_union.lg_config_k", false]], "lg_k (cpc_sketch property)": [[0, "datasketches.cpc_sketch.lg_k", false]], "maxintpolicy (class in datasketches)": [[13, "datasketches.MaxIntPolicy", false]], "merge (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.merge", false]], "merge (density_sketch attribute)": [[22, "datasketches.density_sketch.merge", false]], "merge (ebpps_sketch attribute)": [[19, "datasketches.ebpps_sketch.merge", false]], "merge (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.merge", false]], "merge (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.merge", false]], "merge (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.merge", false]], "merge (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.merge", false]], "merge (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.merge", false]], "merge (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.merge", false]], "merge (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.merge", false]], "merge (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.merge", false]], "merge (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.merge", false]], "merge (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.merge", false]], "merge (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.merge", false]], "merge (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.merge", false]], "merge (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.merge", false]], "minintpolicy (class in datasketches)": [[13, "datasketches.MinIntPolicy", false]], "n (density_sketch property)": [[22, "datasketches.density_sketch.n", false]], "n (ebpps_sketch property)": [[19, "datasketches.ebpps_sketch.n", false]], "n (kll_doubles_sketch property)": [[16, "datasketches.kll_doubles_sketch.n", false]], "n (kll_floats_sketch property)": [[16, "datasketches.kll_floats_sketch.n", false]], "n (kll_ints_sketch property)": [[16, "datasketches.kll_ints_sketch.n", false]], "n (kll_items_sketch property)": [[16, "datasketches.kll_items_sketch.n", false]], "n (quantiles_doubles_sketch property)": [[17, "datasketches.quantiles_doubles_sketch.n", false]], "n (quantiles_floats_sketch property)": [[17, "datasketches.quantiles_floats_sketch.n", false]], "n (quantiles_ints_sketch property)": [[17, "datasketches.quantiles_ints_sketch.n", false]], "n (quantiles_items_sketch property)": [[17, "datasketches.quantiles_items_sketch.n", false]], "n (req_floats_sketch property)": [[18, "datasketches.req_floats_sketch.n", false]], "n (req_ints_sketch property)": [[18, "datasketches.req_ints_sketch.n", false]], "n (req_items_sketch property)": [[18, "datasketches.req_items_sketch.n", false]], "n (var_opt_sketch property)": [[21, "datasketches.var_opt_sketch.n", false]], "no_false_negatives (frequent_items_error_type attribute)": [[6, "datasketches.frequent_items_error_type.NO_FALSE_NEGATIVES", false]], "no_false_positives (frequent_items_error_type attribute)": [[6, "datasketches.frequent_items_error_type.NO_FALSE_POSITIVES", false]], "normalized_rank_error (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.normalized_rank_error", false]], "normalized_rank_error (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.normalized_rank_error", false]], "normalized_rank_error (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.normalized_rank_error", false]], "normalized_rank_error (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.normalized_rank_error", false]], "normalized_rank_error (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.normalized_rank_error", false]], "normalized_rank_error (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.normalized_rank_error", false]], "normalized_rank_error (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.normalized_rank_error", false]], "normalized_rank_error (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.normalized_rank_error", false]], "num_active_items (frequent_items_sketch property)": [[6, "datasketches.frequent_items_sketch.num_active_items", false]], "num_active_items (frequent_strings_sketch property)": [[6, "datasketches.frequent_strings_sketch.num_active_items", false]], "num_buckets (count_min_sketch property)": [[5, "datasketches.count_min_sketch.num_buckets", false]], "num_hashes (count_min_sketch property)": [[5, "datasketches.count_min_sketch.num_hashes", false]], "num_retained (density_sketch property)": [[22, "datasketches.density_sketch.num_retained", false]], "num_retained (kll_doubles_sketch property)": [[16, "datasketches.kll_doubles_sketch.num_retained", false]], "num_retained (kll_floats_sketch property)": [[16, "datasketches.kll_floats_sketch.num_retained", false]], "num_retained (kll_ints_sketch property)": [[16, "datasketches.kll_ints_sketch.num_retained", false]], "num_retained (kll_items_sketch property)": [[16, "datasketches.kll_items_sketch.num_retained", false]], "num_retained (quantiles_doubles_sketch property)": [[17, "datasketches.quantiles_doubles_sketch.num_retained", false]], "num_retained (quantiles_floats_sketch property)": [[17, "datasketches.quantiles_floats_sketch.num_retained", false]], "num_retained (quantiles_ints_sketch property)": [[17, "datasketches.quantiles_ints_sketch.num_retained", false]], "num_retained (quantiles_items_sketch property)": [[17, "datasketches.quantiles_items_sketch.num_retained", false]], "num_retained (req_floats_sketch property)": [[18, "datasketches.req_floats_sketch.num_retained", false]], "num_retained (req_ints_sketch property)": [[18, "datasketches.req_ints_sketch.num_retained", false]], "num_retained (req_items_sketch property)": [[18, "datasketches.req_items_sketch.num_retained", false]], "num_retained (theta_sketch property)": [[3, "datasketches.theta_sketch.num_retained", false]], "num_retained (tuple_sketch property)": [[4, "datasketches.tuple_sketch.num_retained", false]], "num_samples (var_opt_sketch property)": [[21, "datasketches.var_opt_sketch.num_samples", false]], "pydoublesserde (class in datasketches)": [[12, "datasketches.PyDoublesSerDe", false]], "pyfloatsserde (class in datasketches)": [[12, "datasketches.PyFloatsSerDe", false]], "pyintsserde (class in datasketches)": [[12, "datasketches.PyIntsSerDe", false]], "pylongsserde (class in datasketches)": [[12, "datasketches.PyLongsSerDe", false]], "pyobjectserde (class in datasketches)": [[12, "datasketches.PyObjectSerDe", false]], "pystringsserde (class in datasketches)": [[12, "datasketches.PyStringsSerDe", false]], "quantiles_doubles_sketch (class in datasketches)": [[17, "datasketches.quantiles_doubles_sketch", false]], "quantiles_floats_sketch (class in datasketches)": [[17, "datasketches.quantiles_floats_sketch", false]], "quantiles_ints_sketch (class in datasketches)": [[17, "datasketches.quantiles_ints_sketch", false]], "quantiles_items_sketch (class in datasketches)": [[17, "datasketches.quantiles_items_sketch", false]], "req_floats_sketch (class in datasketches)": [[18, "datasketches.req_floats_sketch", false]], "req_ints_sketch (class in datasketches)": [[18, "datasketches.req_ints_sketch", false]], "req_items_sketch (class in datasketches)": [[18, "datasketches.req_items_sketch", false]], "reset (hll_sketch attribute)": [[1, "datasketches.hll_sketch.reset", false]], "reset (hll_union attribute)": [[1, "datasketches.hll_union.reset", false]], "reset (tuple_union attribute)": [[4, "datasketches.tuple_union.reset", false]], "reset (update_theta_sketch attribute)": [[3, "datasketches.update_theta_sketch.reset", false]], "reset (update_tuple_sketch attribute)": [[4, "datasketches.update_tuple_sketch.reset", false]], "reset (var_opt_union attribute)": [[21, "datasketches.var_opt_union.reset", false]], "seed (count_min_sketch property)": [[5, "datasketches.count_min_sketch.seed", false]], "serialize (compact_theta_sketch attribute)": [[3, "datasketches.compact_theta_sketch.serialize", false]], "serialize (compact_tuple_sketch attribute)": [[4, "datasketches.compact_tuple_sketch.serialize", false]], "serialize (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.serialize", false]], "serialize (cpc_sketch attribute)": [[0, "datasketches.cpc_sketch.serialize", false]], "serialize (density_sketch attribute)": [[22, "datasketches.density_sketch.serialize", false]], "serialize (ebpps_sketch attribute)": [[19, "datasketches.ebpps_sketch.serialize", false]], "serialize (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.serialize", false]], "serialize (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.serialize", false]], "serialize (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.serialize", false]], "serialize (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.serialize", false]], "serialize (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.serialize", false]], "serialize (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.serialize", false]], "serialize (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.serialize", false]], "serialize (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.serialize", false]], "serialize (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.serialize", false]], "serialize (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.serialize", false]], "serialize (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.serialize", false]], "serialize (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.serialize", false]], "serialize (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.serialize", false]], "serialize (var_opt_sketch attribute)": [[21, "datasketches.var_opt_sketch.serialize", false]], "serialize (var_opt_union attribute)": [[21, "datasketches.var_opt_union.serialize", false]], "serialize_compact (hll_sketch attribute)": [[1, "datasketches.hll_sketch.serialize_compact", false]], "serialize_updatable (hll_sketch attribute)": [[1, "datasketches.hll_sketch.serialize_updatable", false]], "similarity_test() (theta_jaccard_similarity method)": [[9, "datasketches.theta_jaccard_similarity.similarity_test", false]], "similarity_test() (tuple_jaccard_similarity method)": [[9, "datasketches.tuple_jaccard_similarity.similarity_test", false]], "suggest_num_buckets() (count_min_sketch method)": [[5, "datasketches.count_min_sketch.suggest_num_buckets", false]], "suggest_num_hashes() (count_min_sketch method)": [[5, "datasketches.count_min_sketch.suggest_num_hashes", false]], "tgt_hll_type (class in _datasketches)": [[1, "datasketches.tgt_hll_type", false]], "tgt_type (hll_sketch property)": [[1, "datasketches.hll_sketch.tgt_type", false]], "theta (theta_sketch property)": [[3, "datasketches.theta_sketch.theta", false]], "theta (tuple_sketch property)": [[4, "datasketches.tuple_sketch.theta", false]], "theta64 (theta_sketch property)": [[3, "datasketches.theta_sketch.theta64", false]], "theta64 (tuple_sketch property)": [[4, "datasketches.tuple_sketch.theta64", false]], "theta_a_not_b (class in datasketches)": [[3, "datasketches.theta_a_not_b", false]], "theta_intersection (class in datasketches)": [[3, "datasketches.theta_intersection", false]], "theta_jaccard_similarity (class in datasketches)": [[9, "datasketches.theta_jaccard_similarity", false]], "theta_sketch (class in datasketches)": [[3, "datasketches.theta_sketch", false]], "theta_union (class in datasketches)": [[3, "datasketches.theta_union", false]], "to_bytes() (pyobjectserde method)": [[12, "datasketches.PyObjectSerDe.to_bytes", false]], "to_string (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.to_string", false]], "to_string (cpc_sketch attribute)": [[0, "datasketches.cpc_sketch.to_string", false]], "to_string (density_sketch attribute)": [[22, "datasketches.density_sketch.to_string", false]], "to_string (ebpps_sketch attribute)": [[19, "datasketches.ebpps_sketch.to_string", false]], "to_string (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.to_string", false]], "to_string (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.to_string", false]], "to_string (hll_sketch attribute)": [[1, "datasketches.hll_sketch.to_string", false]], "to_string (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.to_string", false]], "to_string (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.to_string", false]], "to_string (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.to_string", false]], "to_string (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.to_string", false]], "to_string (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.to_string", false]], "to_string (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.to_string", false]], "to_string (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.to_string", false]], "to_string (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.to_string", false]], "to_string (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.to_string", false]], "to_string (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.to_string", false]], "to_string (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.to_string", false]], "to_string (theta_sketch attribute)": [[3, "datasketches.theta_sketch.to_string", false]], "to_string (tuple_sketch attribute)": [[4, "datasketches.tuple_sketch.to_string", false]], "to_string (var_opt_sketch attribute)": [[21, "datasketches.var_opt_sketch.to_string", false]], "to_string (var_opt_union attribute)": [[21, "datasketches.var_opt_union.to_string", false]], "total_weight (count_min_sketch property)": [[5, "datasketches.count_min_sketch.total_weight", false]], "total_weight (frequent_items_sketch property)": [[6, "datasketches.frequent_items_sketch.total_weight", false]], "total_weight (frequent_strings_sketch property)": [[6, "datasketches.frequent_strings_sketch.total_weight", false]], "trim (update_theta_sketch attribute)": [[3, "datasketches.update_theta_sketch.trim", false]], "trim (update_tuple_sketch attribute)": [[4, "datasketches.update_tuple_sketch.trim", false]], "tuple_a_not_b (class in datasketches)": [[4, "datasketches.tuple_a_not_b", false]], "tuple_intersection (class in datasketches)": [[4, "datasketches.tuple_intersection", false]], "tuple_jaccard_similarity (class in datasketches)": [[9, "datasketches.tuple_jaccard_similarity", false]], "tuple_sketch (class in datasketches)": [[4, "datasketches.tuple_sketch", false]], "tuple_union (class in datasketches)": [[4, "datasketches.tuple_union", false]], "tuplepolicy (class in datasketches)": [[13, "datasketches.TuplePolicy", false]], "update (count_min_sketch attribute)": [[5, "datasketches.count_min_sketch.update", false]], "update (cpc_sketch attribute)": [[0, "datasketches.cpc_sketch.update", false]], "update (cpc_union attribute)": [[0, "datasketches.cpc_union.update", false]], "update (density_sketch attribute)": [[22, "datasketches.density_sketch.update", false]], "update (ebpps_sketch attribute)": [[19, "datasketches.ebpps_sketch.update", false]], "update (frequent_items_sketch attribute)": [[6, "datasketches.frequent_items_sketch.update", false]], "update (frequent_strings_sketch attribute)": [[6, "datasketches.frequent_strings_sketch.update", false]], "update (hll_sketch attribute)": [[1, "datasketches.hll_sketch.update", false]], "update (hll_union attribute)": [[1, "datasketches.hll_union.update", false]], "update (kll_doubles_sketch attribute)": [[16, "datasketches.kll_doubles_sketch.update", false]], "update (kll_floats_sketch attribute)": [[16, "datasketches.kll_floats_sketch.update", false]], "update (kll_ints_sketch attribute)": [[16, "datasketches.kll_ints_sketch.update", false]], "update (kll_items_sketch attribute)": [[16, "datasketches.kll_items_sketch.update", false]], "update (quantiles_doubles_sketch attribute)": [[17, "datasketches.quantiles_doubles_sketch.update", false]], "update (quantiles_floats_sketch attribute)": [[17, "datasketches.quantiles_floats_sketch.update", false]], "update (quantiles_ints_sketch attribute)": [[17, "datasketches.quantiles_ints_sketch.update", false]], "update (quantiles_items_sketch attribute)": [[17, "datasketches.quantiles_items_sketch.update", false]], "update (req_floats_sketch attribute)": [[18, "datasketches.req_floats_sketch.update", false]], "update (req_ints_sketch attribute)": [[18, "datasketches.req_ints_sketch.update", false]], "update (req_items_sketch attribute)": [[18, "datasketches.req_items_sketch.update", false]], "update (theta_intersection attribute)": [[3, "datasketches.theta_intersection.update", false]], "update (theta_union attribute)": [[3, "datasketches.theta_union.update", false]], "update (tuple_intersection attribute)": [[4, "datasketches.tuple_intersection.update", false]], "update (tuple_union attribute)": [[4, "datasketches.tuple_union.update", false]], "update (update_theta_sketch attribute)": [[3, "datasketches.update_theta_sketch.update", false]], "update (update_tuple_sketch attribute)": [[4, "datasketches.update_tuple_sketch.update", false]], "update (var_opt_sketch attribute)": [[21, "datasketches.var_opt_sketch.update", false]], "update (var_opt_union attribute)": [[21, "datasketches.var_opt_union.update", false]], "update_summary() (tuplepolicy method)": [[13, "datasketches.TuplePolicy.update_summary", false]], "update_theta_sketch (class in datasketches)": [[3, "datasketches.update_theta_sketch", false]], "update_tuple_sketch (class in datasketches)": [[4, "datasketches.update_tuple_sketch", false]], "var_opt_sketch (class in datasketches)": [[21, "datasketches.var_opt_sketch", false]], "var_opt_union (class in datasketches)": [[21, "datasketches.var_opt_union", false]]}, "objects": {"_datasketches": [[5, 0, 1, "datasketches.count_min_sketch", "count_min_sketch"], [0, 0, 1, "datasketches.cpc_sketch", "cpc_sketch"], [0, 0, 1, "datasketches.cpc_union", "cpc_union"], [1, 0, 1, "datasketches.hll_sketch", "hll_sketch"], [1, 0, 1, "datasketches.hll_union", "hll_union"], [1, 0, 1, "datasketches.tgt_hll_type", "tgt_hll_type"]], "_datasketches.count_min_sketch": [[5, 1, 1, "datasketches.count_min_sketch.deserialize", "deserialize"], [5, 2, 1, "datasketches.count_min_sketch.get_estimate", "get_estimate"], [5, 2, 1, "datasketches.count_min_sketch.get_lower_bound", "get_lower_bound"], [5, 2, 1, "datasketches.count_min_sketch.get_relative_error", "get_relative_error"], [5, 2, 1, "datasketches.count_min_sketch.get_serialized_size_bytes", "get_serialized_size_bytes"], [5, 2, 1, "datasketches.count_min_sketch.get_upper_bound", "get_upper_bound"], [5, 2, 1, "datasketches.count_min_sketch.is_empty", "is_empty"], [5, 2, 1, "datasketches.count_min_sketch.merge", "merge"], [5, 3, 1, "datasketches.count_min_sketch.num_buckets", "num_buckets"], [5, 3, 1, "datasketches.count_min_sketch.num_hashes", "num_hashes"], [5, 3, 1, "datasketches.count_min_sketch.seed", "seed"], [5, 2, 1, "datasketches.count_min_sketch.serialize", "serialize"], [5, 1, 1, "datasketches.count_min_sketch.suggest_num_buckets", "suggest_num_buckets"], [5, 1, 1, "datasketches.count_min_sketch.suggest_num_hashes", "suggest_num_hashes"], [5, 2, 1, "datasketches.count_min_sketch.to_string", "to_string"], [5, 3, 1, "datasketches.count_min_sketch.total_weight", "total_weight"], [5, 2, 1, "datasketches.count_min_sketch.update", "update"]], "_datasketches.cpc_sketch": [[0, 1, 1, "datasketches.cpc_sketch.__init__", "__init__"], [0, 1, 1, "datasketches.cpc_sketch.deserialize", "deserialize"], [0, 2, 1, "datasketches.cpc_sketch.get_estimate", "get_estimate"], [0, 2, 1, "datasketches.cpc_sketch.get_lower_bound", "get_lower_bound"], [0, 2, 1, "datasketches.cpc_sketch.get_upper_bound", "get_upper_bound"], [0, 2, 1, "datasketches.cpc_sketch.is_empty", "is_empty"], [0, 3, 1, "datasketches.cpc_sketch.lg_k", "lg_k"], [0, 2, 1, "datasketches.cpc_sketch.serialize", "serialize"], [0, 2, 1, "datasketches.cpc_sketch.to_string", "to_string"], [0, 2, 1, "datasketches.cpc_sketch.update", "update"]], "_datasketches.cpc_union": [[0, 1, 1, "datasketches.cpc_union.__init__", "__init__"], [0, 2, 1, "datasketches.cpc_union.get_result", "get_result"], [0, 2, 1, "datasketches.cpc_union.update", "update"]], "_datasketches.hll_sketch": [[1, 1, 1, "datasketches.hll_sketch.__init__", "__init__"], [1, 1, 1, "datasketches.hll_sketch.deserialize", "deserialize"], [1, 2, 1, "datasketches.hll_sketch.get_compact_serialization_bytes", "get_compact_serialization_bytes"], [1, 2, 1, "datasketches.hll_sketch.get_estimate", "get_estimate"], [1, 2, 1, "datasketches.hll_sketch.get_lower_bound", "get_lower_bound"], [1, 1, 1, "datasketches.hll_sketch.get_max_updatable_serialization_bytes", "get_max_updatable_serialization_bytes"], [1, 1, 1, "datasketches.hll_sketch.get_rel_err", "get_rel_err"], [1, 2, 1, "datasketches.hll_sketch.get_updatable_serialization_bytes", "get_updatable_serialization_bytes"], [1, 2, 1, "datasketches.hll_sketch.get_upper_bound", "get_upper_bound"], [1, 2, 1, "datasketches.hll_sketch.is_compact", "is_compact"], [1, 2, 1, "datasketches.hll_sketch.is_empty", "is_empty"], [1, 3, 1, "datasketches.hll_sketch.lg_config_k", "lg_config_k"], [1, 2, 1, "datasketches.hll_sketch.reset", "reset"], [1, 2, 1, "datasketches.hll_sketch.serialize_compact", "serialize_compact"], [1, 2, 1, "datasketches.hll_sketch.serialize_updatable", "serialize_updatable"], [1, 3, 1, "datasketches.hll_sketch.tgt_type", "tgt_type"], [1, 2, 1, "datasketches.hll_sketch.to_string", "to_string"], [1, 2, 1, "datasketches.hll_sketch.update", "update"]], "_datasketches.hll_union": [[1, 1, 1, "datasketches.hll_union.__init__", "__init__"], [1, 2, 1, "datasketches.hll_union.get_estimate", "get_estimate"], [1, 2, 1, "datasketches.hll_union.get_lower_bound", "get_lower_bound"], [1, 1, 1, "datasketches.hll_union.get_rel_err", "get_rel_err"], [1, 2, 1, "datasketches.hll_union.get_result", "get_result"], [1, 2, 1, "datasketches.hll_union.get_upper_bound", "get_upper_bound"], [1, 2, 1, "datasketches.hll_union.is_empty", "is_empty"], [1, 3, 1, "datasketches.hll_union.lg_config_k", "lg_config_k"], [1, 2, 1, "datasketches.hll_union.reset", "reset"], [1, 2, 1, "datasketches.hll_union.update", "update"]], "_datasketches.tgt_hll_type": [[1, 2, 1, "datasketches.tgt_hll_type.HLL_4", "HLL_4"], [1, 2, 1, "datasketches.tgt_hll_type.HLL_6", "HLL_6"], [1, 2, 1, "datasketches.tgt_hll_type.HLL_8", "HLL_8"]], "datasketches": [[13, 0, 1, "", "AccumulatorPolicy"], [10, 0, 1, "", "GaussianKernel"], [10, 0, 1, "", "KernelFunction"], [13, 0, 1, "", "MaxIntPolicy"], [13, 0, 1, "", "MinIntPolicy"], [12, 0, 1, "", "PyDoublesSerDe"], [12, 0, 1, "", "PyFloatsSerDe"], [12, 0, 1, "", "PyIntsSerDe"], [12, 0, 1, "", "PyLongsSerDe"], [12, 0, 1, "", "PyObjectSerDe"], [12, 0, 1, "", "PyStringsSerDe"], [13, 0, 1, "", "TuplePolicy"], [3, 0, 1, "", "compact_theta_sketch"], [4, 0, 1, "", "compact_tuple_sketch"], [22, 0, 1, "", "density_sketch"], [19, 0, 1, "", "ebpps_sketch"], [6, 0, 1, "", "frequent_items_error_type"], [6, 0, 1, "", "frequent_items_sketch"], [6, 0, 1, "", "frequent_strings_sketch"], [16, 0, 1, "", "kll_doubles_sketch"], [16, 0, 1, "", "kll_floats_sketch"], [16, 0, 1, "", "kll_ints_sketch"], [16, 0, 1, "", "kll_items_sketch"], [11, 4, 1, "", "ks_test"], [17, 0, 1, "", "quantiles_doubles_sketch"], [17, 0, 1, "", "quantiles_floats_sketch"], [17, 0, 1, "", "quantiles_ints_sketch"], [17, 0, 1, "", "quantiles_items_sketch"], [18, 0, 1, "", "req_floats_sketch"], [18, 0, 1, "", "req_ints_sketch"], [18, 0, 1, "", "req_items_sketch"], [3, 0, 1, "", "theta_a_not_b"], [3, 0, 1, "", "theta_intersection"], [9, 0, 1, "", "theta_jaccard_similarity"], [3, 0, 1, "", "theta_sketch"], [3, 0, 1, "", "theta_union"], [4, 0, 1, "", "tuple_a_not_b"], [4, 0, 1, "", "tuple_intersection"], [9, 0, 1, "", "tuple_jaccard_similarity"], [4, 0, 1, "", "tuple_sketch"], [4, 0, 1, "", "tuple_union"], [3, 0, 1, "", "update_theta_sketch"], [4, 0, 1, "", "update_tuple_sketch"], [21, 0, 1, "", "var_opt_sketch"], [21, 0, 1, "", "var_opt_union"]], "datasketches.KernelFunction": [[10, 1, 1, "", "__call__"]], "datasketches.PyObjectSerDe": [[12, 1, 1, "", "from_bytes"], [12, 1, 1, "", "get_size"], [12, 1, 1, "", "to_bytes"]], "datasketches.TuplePolicy": [[13, 1, 1, "", "__call__"], [13, 1, 1, "", "create_summary"], [13, 1, 1, "", "update_summary"]], "datasketches.compact_theta_sketch": [[3, 1, 1, "", "__init__"], [3, 1, 1, "", "deserialize"], [3, 2, 1, "", "serialize"]], "datasketches.compact_tuple_sketch": [[4, 1, 1, "", "__init__"], [4, 1, 1, "", "deserialize"], [4, 2, 1, "", "filter"], [4, 2, 1, "", "serialize"]], "datasketches.density_sketch": [[22, 1, 1, "", "__init__"], [22, 1, 1, "", "deserialize"], [22, 3, 1, "", "dim"], [22, 2, 1, "", "get_estimate"], [22, 2, 1, "", "is_empty"], [22, 2, 1, "", "is_estimation_mode"], [22, 3, 1, "", "k"], [22, 2, 1, "", "merge"], [22, 3, 1, "", "n"], [22, 3, 1, "", "num_retained"], [22, 2, 1, "", "serialize"], [22, 2, 1, "", "to_string"], [22, 2, 1, "", "update"]], "datasketches.ebpps_sketch": [[19, 1, 1, "", "__init__"], [19, 3, 1, "", "c"], [19, 1, 1, "", "deserialize"], [19, 2, 1, "", "get_serialized_size_bytes"], [19, 2, 1, "", "is_empty"], [19, 3, 1, "", "k"], [19, 2, 1, "", "merge"], [19, 3, 1, "", "n"], [19, 2, 1, "", "serialize"], [19, 2, 1, "", "to_string"], [19, 2, 1, "", "update"]], "datasketches.frequent_items_error_type": [[6, 2, 1, "", "NO_FALSE_NEGATIVES"], [6, 2, 1, "", "NO_FALSE_POSITIVES"]], "datasketches.frequent_items_sketch": [[6, 1, 1, "", "__init__"], [6, 1, 1, "", "deserialize"], [6, 3, 1, "", "epsilon"], [6, 1, 1, "", "get_apriori_error"], [6, 1, 1, "", "get_epsilon_for_lg_size"], [6, 2, 1, "", "get_estimate"], [6, 2, 1, "", "get_frequent_items"], [6, 2, 1, "", "get_lower_bound"], [6, 2, 1, "", "get_serialized_size_bytes"], [6, 2, 1, "", "get_upper_bound"], [6, 2, 1, "", "is_empty"], [6, 2, 1, "", "merge"], [6, 3, 1, "", "num_active_items"], [6, 2, 1, "", "serialize"], [6, 2, 1, "", "to_string"], [6, 3, 1, "", "total_weight"], [6, 2, 1, "", "update"]], "datasketches.frequent_strings_sketch": [[6, 1, 1, "", "__init__"], [6, 1, 1, "", "deserialize"], [6, 3, 1, "", "epsilon"], [6, 1, 1, "", "get_apriori_error"], [6, 1, 1, "", "get_epsilon_for_lg_size"], [6, 2, 1, "", "get_estimate"], [6, 2, 1, "", "get_frequent_items"], [6, 2, 1, "", "get_lower_bound"], [6, 2, 1, "", "get_serialized_size_bytes"], [6, 2, 1, "", "get_upper_bound"], [6, 2, 1, "", "is_empty"], [6, 2, 1, "", "merge"], [6, 3, 1, "", "num_active_items"], [6, 2, 1, "", "serialize"], [6, 2, 1, "", "to_string"], [6, 3, 1, "", "total_weight"], [6, 2, 1, "", "update"]], "datasketches.kll_doubles_sketch": [[16, 1, 1, "", "__init__"], [16, 1, 1, "", "deserialize"], [16, 2, 1, "", "get_cdf"], [16, 2, 1, "", "get_max_value"], [16, 2, 1, "", "get_min_value"], [16, 1, 1, "", "get_normalized_rank_error"], [16, 2, 1, "", "get_pmf"], [16, 2, 1, "", "get_quantile"], [16, 2, 1, "", "get_quantiles"], [16, 2, 1, "", "get_rank"], [16, 2, 1, "", "is_empty"], [16, 2, 1, "", "is_estimation_mode"], [16, 3, 1, "", "k"], [16, 2, 1, "", "merge"], [16, 3, 1, "", "n"], [16, 2, 1, "", "normalized_rank_error"], [16, 3, 1, "", "num_retained"], [16, 2, 1, "", "serialize"], [16, 2, 1, "", "to_string"], [16, 2, 1, "", "update"]], "datasketches.kll_floats_sketch": [[16, 1, 1, "", "__init__"], [16, 1, 1, "", "deserialize"], [16, 2, 1, "", "get_cdf"], [16, 2, 1, "", "get_max_value"], [16, 2, 1, "", "get_min_value"], [16, 1, 1, "", "get_normalized_rank_error"], [16, 2, 1, "", "get_pmf"], [16, 2, 1, "", "get_quantile"], [16, 2, 1, "", "get_quantiles"], [16, 2, 1, "", "get_rank"], [16, 2, 1, "", "is_empty"], [16, 2, 1, "", "is_estimation_mode"], [16, 3, 1, "", "k"], [16, 2, 1, "", "merge"], [16, 3, 1, "", "n"], [16, 2, 1, "", "normalized_rank_error"], [16, 3, 1, "", "num_retained"], [16, 2, 1, "", "serialize"], [16, 2, 1, "", "to_string"], [16, 2, 1, "", "update"]], "datasketches.kll_ints_sketch": [[16, 1, 1, "", "__init__"], [16, 1, 1, "", "deserialize"], [16, 2, 1, "", "get_cdf"], [16, 2, 1, "", "get_max_value"], [16, 2, 1, "", "get_min_value"], [16, 1, 1, "", "get_normalized_rank_error"], [16, 2, 1, "", "get_pmf"], [16, 2, 1, "", "get_quantile"], [16, 2, 1, "", "get_quantiles"], [16, 2, 1, "", "get_rank"], [16, 2, 1, "", "is_empty"], [16, 2, 1, "", "is_estimation_mode"], [16, 3, 1, "", "k"], [16, 2, 1, "", "merge"], [16, 3, 1, "", "n"], [16, 2, 1, "", "normalized_rank_error"], [16, 3, 1, "", "num_retained"], [16, 2, 1, "", "serialize"], [16, 2, 1, "", "to_string"], [16, 2, 1, "", "update"]], "datasketches.kll_items_sketch": [[16, 1, 1, "", "__init__"], [16, 1, 1, "", "deserialize"], [16, 2, 1, "", "get_cdf"], [16, 2, 1, "", "get_max_value"], [16, 2, 1, "", "get_min_value"], [16, 1, 1, "", "get_normalized_rank_error"], [16, 2, 1, "", "get_pmf"], [16, 2, 1, "", "get_quantile"], [16, 2, 1, "", "get_quantiles"], [16, 2, 1, "", "get_rank"], [16, 2, 1, "", "is_empty"], [16, 2, 1, "", "is_estimation_mode"], [16, 3, 1, "", "k"], [16, 2, 1, "", "merge"], [16, 3, 1, "", "n"], [16, 2, 1, "", "normalized_rank_error"], [16, 3, 1, "", "num_retained"], [16, 2, 1, "", "serialize"], [16, 2, 1, "", "to_string"], [16, 2, 1, "", "update"]], "datasketches.quantiles_doubles_sketch": [[17, 1, 1, "", "__init__"], [17, 1, 1, "", "deserialize"], [17, 2, 1, "", "get_cdf"], [17, 2, 1, "", "get_max_value"], [17, 2, 1, "", "get_min_value"], [17, 1, 1, "", "get_normalized_rank_error"], [17, 2, 1, "", "get_pmf"], [17, 2, 1, "", "get_quantile"], [17, 2, 1, "", "get_quantiles"], [17, 2, 1, "", "get_rank"], [17, 2, 1, "", "is_empty"], [17, 2, 1, "", "is_estimation_mode"], [17, 3, 1, "", "k"], [17, 2, 1, "", "merge"], [17, 3, 1, "", "n"], [17, 2, 1, "", "normalized_rank_error"], [17, 3, 1, "", "num_retained"], [17, 2, 1, "", "serialize"], [17, 2, 1, "", "to_string"], [17, 2, 1, "", "update"]], "datasketches.quantiles_floats_sketch": [[17, 1, 1, "", "__init__"], [17, 1, 1, "", "deserialize"], [17, 2, 1, "", "get_cdf"], [17, 2, 1, "", "get_max_value"], [17, 2, 1, "", "get_min_value"], [17, 1, 1, "", "get_normalized_rank_error"], [17, 2, 1, "", "get_pmf"], [17, 2, 1, "", "get_quantile"], [17, 2, 1, "", "get_quantiles"], [17, 2, 1, "", "get_rank"], [17, 2, 1, "", "is_empty"], [17, 2, 1, "", "is_estimation_mode"], [17, 3, 1, "", "k"], [17, 2, 1, "", "merge"], [17, 3, 1, "", "n"], [17, 2, 1, "", "normalized_rank_error"], [17, 3, 1, "", "num_retained"], [17, 2, 1, "", "serialize"], [17, 2, 1, "", "to_string"], [17, 2, 1, "", "update"]], "datasketches.quantiles_ints_sketch": [[17, 1, 1, "", "__init__"], [17, 1, 1, "", "deserialize"], [17, 2, 1, "", "get_cdf"], [17, 2, 1, "", "get_max_value"], [17, 2, 1, "", "get_min_value"], [17, 1, 1, "", "get_normalized_rank_error"], [17, 2, 1, "", "get_pmf"], [17, 2, 1, "", "get_quantile"], [17, 2, 1, "", "get_quantiles"], [17, 2, 1, "", "get_rank"], [17, 2, 1, "", "is_empty"], [17, 2, 1, "", "is_estimation_mode"], [17, 3, 1, "", "k"], [17, 2, 1, "", "merge"], [17, 3, 1, "", "n"], [17, 2, 1, "", "normalized_rank_error"], [17, 3, 1, "", "num_retained"], [17, 2, 1, "", "serialize"], [17, 2, 1, "", "to_string"], [17, 2, 1, "", "update"]], "datasketches.quantiles_items_sketch": [[17, 1, 1, "", "__init__"], [17, 1, 1, "", "deserialize"], [17, 2, 1, "", "get_cdf"], [17, 2, 1, "", "get_max_value"], [17, 2, 1, "", "get_min_value"], [17, 1, 1, "", "get_normalized_rank_error"], [17, 2, 1, "", "get_pmf"], [17, 2, 1, "", "get_quantile"], [17, 2, 1, "", "get_quantiles"], [17, 2, 1, "", "get_rank"], [17, 2, 1, "", "is_empty"], [17, 2, 1, "", "is_estimation_mode"], [17, 3, 1, "", "k"], [17, 2, 1, "", "merge"], [17, 3, 1, "", "n"], [17, 2, 1, "", "normalized_rank_error"], [17, 3, 1, "", "num_retained"], [17, 2, 1, "", "serialize"], [17, 2, 1, "", "to_string"], [17, 2, 1, "", "update"]], "datasketches.req_floats_sketch": [[18, 1, 1, "", "__init__"], [18, 1, 1, "", "deserialize"], [18, 1, 1, "", "get_RSE"], [18, 2, 1, "", "get_cdf"], [18, 2, 1, "", "get_max_value"], [18, 2, 1, "", "get_min_value"], [18, 2, 1, "", "get_pmf"], [18, 2, 1, "", "get_quantile"], [18, 2, 1, "", "get_quantiles"], [18, 2, 1, "", "get_rank"], [18, 2, 1, "", "get_rank_lower_bound"], [18, 2, 1, "", "get_rank_upper_bound"], [18, 2, 1, "", "is_empty"], [18, 2, 1, "", "is_estimation_mode"], [18, 2, 1, "", "is_hra"], [18, 3, 1, "", "k"], [18, 2, 1, "", "merge"], [18, 3, 1, "", "n"], [18, 3, 1, "", "num_retained"], [18, 2, 1, "", "serialize"], [18, 2, 1, "", "to_string"], [18, 2, 1, "", "update"]], "datasketches.req_ints_sketch": [[18, 1, 1, "", "__init__"], [18, 1, 1, "", "deserialize"], [18, 1, 1, "", "get_RSE"], [18, 2, 1, "", "get_cdf"], [18, 2, 1, "", "get_max_value"], [18, 2, 1, "", "get_min_value"], [18, 2, 1, "", "get_pmf"], [18, 2, 1, "", "get_quantile"], [18, 2, 1, "", "get_quantiles"], [18, 2, 1, "", "get_rank"], [18, 2, 1, "", "get_rank_lower_bound"], [18, 2, 1, "", "get_rank_upper_bound"], [18, 2, 1, "", "is_empty"], [18, 2, 1, "", "is_estimation_mode"], [18, 2, 1, "", "is_hra"], [18, 3, 1, "", "k"], [18, 2, 1, "", "merge"], [18, 3, 1, "", "n"], [18, 3, 1, "", "num_retained"], [18, 2, 1, "", "serialize"], [18, 2, 1, "", "to_string"], [18, 2, 1, "", "update"]], "datasketches.req_items_sketch": [[18, 1, 1, "", "__init__"], [18, 1, 1, "", "deserialize"], [18, 1, 1, "", "get_RSE"], [18, 2, 1, "", "get_cdf"], [18, 2, 1, "", "get_max_value"], [18, 2, 1, "", "get_min_value"], [18, 2, 1, "", "get_pmf"], [18, 2, 1, "", "get_quantile"], [18, 2, 1, "", "get_quantiles"], [18, 2, 1, "", "get_rank"], [18, 2, 1, "", "get_rank_lower_bound"], [18, 2, 1, "", "get_rank_upper_bound"], [18, 2, 1, "", "is_empty"], [18, 2, 1, "", "is_estimation_mode"], [18, 2, 1, "", "is_hra"], [18, 3, 1, "", "k"], [18, 2, 1, "", "merge"], [18, 3, 1, "", "n"], [18, 3, 1, "", "num_retained"], [18, 2, 1, "", "serialize"], [18, 2, 1, "", "to_string"], [18, 2, 1, "", "update"]], "datasketches.theta_a_not_b": [[3, 1, 1, "", "__init__"], [3, 2, 1, "", "compute"]], "datasketches.theta_intersection": [[3, 1, 1, "", "__init__"], [3, 2, 1, "", "get_result"], [3, 2, 1, "", "has_result"], [3, 2, 1, "", "update"]], "datasketches.theta_jaccard_similarity": [[9, 1, 1, "", "dissimilarity_test"], [9, 1, 1, "", "exactly_equal"], [9, 1, 1, "", "jaccard"], [9, 1, 1, "", "similarity_test"]], "datasketches.theta_sketch": [[3, 2, 1, "", "get_estimate"], [3, 2, 1, "", "get_lower_bound"], [3, 2, 1, "", "get_seed_hash"], [3, 2, 1, "", "get_upper_bound"], [3, 2, 1, "", "is_empty"], [3, 2, 1, "", "is_estimation_mode"], [3, 2, 1, "", "is_ordered"], [3, 3, 1, "", "num_retained"], [3, 3, 1, "", "theta"], [3, 3, 1, "", "theta64"], [3, 2, 1, "", "to_string"]], "datasketches.theta_union": [[3, 1, 1, "", "__init__"], [3, 2, 1, "", "get_result"], [3, 2, 1, "", "update"]], "datasketches.tuple_a_not_b": [[4, 1, 1, "", "__init__"], [4, 2, 1, "", "compute"]], "datasketches.tuple_intersection": [[4, 1, 1, "", "__init__"], [4, 2, 1, "", "get_result"], [4, 2, 1, "", "has_result"], [4, 2, 1, "", "update"]], "datasketches.tuple_jaccard_similarity": [[9, 1, 1, "", "dissimilarity_test"], [9, 1, 1, "", "exactly_equal"], [9, 1, 1, "", "jaccard"], [9, 1, 1, "", "similarity_test"]], "datasketches.tuple_sketch": [[4, 2, 1, "", "DEFAULT_SEED"], [4, 2, 1, "", "get_estimate"], [4, 2, 1, "", "get_lower_bound"], [4, 2, 1, "", "get_seed_hash"], [4, 2, 1, "", "get_upper_bound"], [4, 2, 1, "", "is_empty"], [4, 2, 1, "", "is_estimation_mode"], [4, 2, 1, "", "is_ordered"], [4, 3, 1, "", "num_retained"], [4, 3, 1, "", "theta"], [4, 3, 1, "", "theta64"], [4, 2, 1, "", "to_string"]], "datasketches.tuple_union": [[4, 1, 1, "", "__init__"], [4, 2, 1, "", "get_result"], [4, 2, 1, "", "reset"], [4, 2, 1, "", "update"]], "datasketches.update_theta_sketch": [[3, 1, 1, "", "__init__"], [3, 2, 1, "", "compact"], [3, 2, 1, "", "reset"], [3, 2, 1, "", "trim"], [3, 2, 1, "", "update"]], "datasketches.update_tuple_sketch": [[4, 1, 1, "", "__init__"], [4, 2, 1, "", "compact"], [4, 2, 1, "", "filter"], [4, 2, 1, "", "reset"], [4, 2, 1, "", "trim"], [4, 2, 1, "", "update"]], "datasketches.var_opt_sketch": [[21, 1, 1, "", "__init__"], [21, 1, 1, "", "deserialize"], [21, 2, 1, "", "estimate_subset_sum"], [21, 2, 1, "", "get_serialized_size_bytes"], [21, 2, 1, "", "is_empty"], [21, 3, 1, "", "k"], [21, 3, 1, "", "n"], [21, 3, 1, "", "num_samples"], [21, 2, 1, "", "serialize"], [21, 2, 1, "", "to_string"], [21, 2, 1, "", "update"]], "datasketches.var_opt_union": [[21, 1, 1, "", "__init__"], [21, 1, 1, "", "deserialize"], [21, 2, 1, "", "get_result"], [21, 2, 1, "", "get_serialized_size_bytes"], [21, 2, 1, "", "reset"], [21, 2, 1, "", "serialize"], [21, 2, 1, "", "to_string"], [21, 2, 1, "", "update"]]}, "objnames": {"0": ["py", "class", "Python class"], "1": ["py", "method", "Python method"], "2": ["py", "attribute", "Python attribute"], "3": ["py", "property", "Python property"], "4": ["py", "function", "Python function"]}, "objtypes": {"0": "py:class", "1": "py:method", "2": "py:attribute", "3": "py:property", "4": "py:function"}, "terms": {"": [1, 6, 19, 20, 21], "0": [3, 4, 5, 6, 10, 16, 17, 18], "01668v2": 18, "05": 5, "1": [0, 1, 3, 4, 5, 6, 10, 16, 17, 18], "10": [1, 17], "100": 17, "1000": 17, "11": 0, "12": [3, 4, 18], "128": 17, "13": 16, "14": 6, "16": 1, "18": 6, "1982": 6, "1985": 2, "1e": 6, "1e9": 6, "2": [0, 1, 3, 4, 6, 17, 18], "20": 17, "200": 16, "2002": 6, "2003": 6, "2004": 18, "2006": 6, "2020": 16, "2021": 17, "2023": 19, "21": 1, "3": [0, 1, 3, 4, 6, 17, 18], "30": 17, "32": [12, 16], "33": 16, "4": [1, 12, 17], "40": 17, "47": 16, "483": 17, "5": [5, 6, 17], "500": 17, "50th": 17, "517": 17, "6": 1, "64": [0, 3, 4, 5, 12, 17], "65": 16, "7": [1, 9, 17], "75": 6, "8": [1, 6, 12], "80": 11, "900": 17, "9001": [0, 3, 4, 9], "93smirnov_test": 11, "95": [5, 17], "95th": 17, "97": 9, "99": [16, 17], "A": [1, 3, 4, 6, 10, 11, 12, 13, 16, 17, 21], "As": [0, 16, 17], "For": [0, 1, 5, 6, 16, 17, 18, 23], "If": [1, 6, 9, 16, 17, 18], "In": [0, 1, 16, 19], "It": [3, 16, 17, 18], "One": 2, "That": 15, "The": [0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 22], "Then": 16, "There": [3, 6], "These": [1, 8, 9, 15, 20, 23], "With": [16, 17, 18], "_": 11, "__call__": [10, 13], "__eq__": 6, "__hash__": 6, "__init__": [0, 1, 3, 4, 6, 16, 17, 18, 19, 21, 22], "__lt__": [16, 17, 18], "_datasketch": [0, 1, 3, 4, 5, 6, 9, 11, 16, 17, 18, 19, 21, 22], "ab": 18, "abbadi": 6, "abil": 18, "about": [1, 15, 16, 17], "abov": [7, 16], "absolut": 8, "abstract": [3, 4, 8, 10, 12, 13], "accept": 23, "account": 11, "accumulatori": 13, "accumulatorpolici": 13, "accuraci": [0, 1, 2, 3, 5, 6, 16, 17, 18], "achiev": 5, "activ": [6, 14], "actual": [9, 17], "ad": 13, "add": 16, "addit": [0, 2, 6, 12], "addition": 16, "advanc": 20, "affect": [16, 17], "after": [18, 20], "against": [0, 9], "agraw": 6, "algorithm": [0, 1, 2, 3, 6, 14, 18], "all": [1, 3, 6, 12, 13, 15, 16, 17, 19, 21], "alloc": 12, "allow": [0, 4, 12, 13, 18], "along": 6, "also": [0, 3, 10, 14, 15, 17], "altern": 15, "although": [1, 19], "alwai": [6, 13, 16, 17, 19, 20], "an": [0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 12, 13, 15, 16, 17, 18, 19, 20, 21, 22], "analog": [16, 17, 18], "analysi": [4, 11, 16, 17, 18], "analyz": 14, "ani": [3, 4, 5, 6, 7, 13, 16, 17], "anoth": [0, 6, 18], "answer": 15, "appl": 0, "appli": [2, 3, 4, 6, 13, 15, 16, 18, 20, 21], "applic": 2, "approach": 15, "approx": [5, 18], "approxim": [0, 1, 3, 4, 5, 6, 10, 15, 16, 17, 18, 22], "ar": [0, 1, 3, 4, 5, 6, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 20, 23], "arbitrari": [4, 6], "arg": [0, 1, 3, 4, 5, 6, 10, 12, 13, 16, 17, 18, 19, 21, 22], "arg0": 3, "arg1": 3, "around": 16, "arrai": [6, 10, 16, 17, 18], "art": 2, "arxiv": 18, "as_pmf": [16, 17], "associ": [4, 6, 16, 17, 18], "assum": [6, 11], "avail": 16, "avoid": 3, "axi": 16, "b": [3, 4, 10, 19], "back": 0, "background": 6, "backward": [6, 15], "bag": 6, "bandwidth": 10, "base": [0, 1, 2, 3, 4, 5, 6, 8, 10, 12, 13, 18, 19, 20, 22], "basi": 10, "basic": [3, 4, 10], "becaus": 16, "been": [7, 16, 17, 18, 21], "befor": [6, 7], "behavior": 1, "being": 20, "below": 16, "best": [16, 17], "better": [1, 2, 3], "between": [1, 3, 4, 6, 8, 9, 16, 17, 18, 22], "beyond": 3, "big": 14, "bin": [0, 16], "binari": [12, 16, 17], "bit": [0, 1, 3, 4, 5, 12, 16, 17], "blob": 22, "bool": [1, 3, 4, 9, 11, 16, 17, 18], "both": [11, 18, 20], "bound": [0, 1, 3, 4, 5, 6, 9, 14, 15, 16, 18, 20, 21], "boundari": [1, 6], "bracket": 16, "bucket": [1, 5], "build": 22, "byte": [0, 1, 3, 4, 5, 6, 12, 16, 17, 18, 19, 21, 22], "c": [0, 19], "call": [16, 19], "came": 2, "can": [0, 1, 3, 4, 6, 11, 13, 15, 16, 17, 18], "cannot": 16, "capabl": [0, 6, 18], "capac": 6, "cardin": [0, 3], "case": [1, 6, 8, 17, 19], "caus": 6, "cdf": [15, 16, 17, 18], "certain": [7, 8, 10, 16, 19], "choic": 1, "choos": 18, "class": [0, 1, 3, 4, 5, 6, 9, 10, 12, 13, 16, 17, 18, 19, 21, 22], "classic": [15, 17], "close": 7, "cm": 5, "code": [6, 18], "collect": 1, "com": 22, "combin": [8, 13], "come": [11, 17], "commonli": [6, 16], "compact": [1, 3, 4, 16, 18], "compact_theta_sketch": 3, "compact_tuple_sketch": 4, "compactor": 18, "compar": [0, 16, 17, 18], "comparison": [0, 18], "compat": [6, 12, 15, 16, 17], "complic": 4, "compress": [1, 2, 3, 14], "comput": [3, 4, 6, 8, 9, 15, 19, 21, 22], "concept": 2, "concret": 8, "confid": [5, 9, 16, 17], "configur": [0, 1, 5, 16, 17, 18, 19, 21, 22], "consecut": [16, 17, 18], "consid": [9, 17], "consist": 13, "constant": [1, 6, 16, 17, 18], "construct": [1, 18, 21], "consum": [1, 12], "contain": [3, 6, 7], "context": 10, "contrast": [5, 19], "control": [16, 17, 18, 22], "coreset": 22, "cormod": [5, 18], "correspond": [0, 1, 3, 4, 5, 6, 16, 17, 18, 19, 21, 22], "cost": [1, 12], "could": [16, 17, 18], "count": [1, 3, 4, 6, 17, 18], "count_min_sketch": [5, 7], "counter": 6, "countmin": [7, 14], "coupon": 1, "cpc": [1, 2, 14], "cpc_sketch": [0, 2], "cpc_union": 0, "creat": [0, 3, 4, 6, 13, 16, 17, 18, 19, 21, 22], "create_summari": 13, "creation": 19, "criterion": 18, "critic": 12, "cross": [12, 17], "cumul": [15, 16, 17, 18], "current": [1, 3, 4, 5, 6, 7, 11, 15, 19, 21], "custom": [4, 10, 12, 13], "data": [2, 3, 6, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 22], "datasketch": [2, 11], "datum": [0, 1, 3, 4], "debug": 18, "decreas": [15, 18], "decrement": 6, "dedic": [3, 4], "default": [1, 3, 4, 10, 16, 17, 18], "default_se": 4, "defin": [3, 4, 6, 10, 16, 19], "definit": [16, 17, 18], "delta": 5, "demain": 6, "denot": [5, 6], "densiti": [8, 10, 14, 23], "density_sketch": [10, 22, 23], "depend": [5, 16], "deprec": [14, 15], "deriv": [3, 16, 17, 18], "describ": [0, 5, 18], "deseri": [0, 1, 3, 4, 5, 6, 8, 14, 16, 17, 18, 19, 21, 22], "design": [15, 23], "desing": 21, "detail": [18, 20], "determin": [7, 11], "determinist": 6, "develop": [0, 14], "deviat": [0, 1, 3, 4, 18], "differ": [0, 1, 2, 3, 6, 12, 13, 18, 20], "dim": 22, "dimac": 5, "dimens": [0, 22], "dimension": 16, "discov": 6, "discrep": 22, "discuss": 18, "disjoint": [16, 17, 18], "dissimilar": 9, "dissimilarity_test": 9, "distanc": 22, "distinct": [0, 1, 3, 4, 6], "distribut": [1, 11, 15, 16, 17, 18], "divid": [16, 17, 18], "do": 6, "document": 16, "doe": [0, 5, 6, 7, 16, 18, 20], "domain": 16, "doubl": [16, 17, 18, 19], "dtype": [16, 17, 18], "dure": 1, "e": 15, "e2": 11, "each": [1, 2, 4, 6, 11, 12, 13, 15, 16, 17, 18, 20], "earliest": 2, "easili": [3, 4], "ebpp": [14, 20], "ebpps_sketch": [19, 20], "edg": [16, 17], "edo": [18, 22], "edoliberti": 22, "edu": 5, "effect": [3, 4], "effici": [0, 3, 6, 14], "either": [6, 15, 16, 17, 18], "element": [2, 6], "els": 18, "empir": [0, 16, 17, 18], "emploi": 6, "empti": [0, 1, 3, 4, 6, 16, 17, 18, 19, 21, 22], "en": 11, "enabl": [16, 17], "encod": 12, "end": 15, "endian": 12, "enough": 1, "ensur": [6, 19, 20], "entir": [7, 15, 20], "entri": [1, 3, 4, 6], "entropi": 0, "ep": 16, "epsilon": [6, 16], "equal": [11, 15, 16, 17, 18, 19], "equival": [9, 16, 17, 19, 21], "error": [1, 3, 5, 6, 8, 11, 14, 15, 16, 17, 19, 21, 22], "estim": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 16, 17, 18, 21, 22, 23], "estimate_subset_sum": 21, "estimated_total_stream_weight": 6, "estimated_total_weight": 6, "evalu": [4, 10], "even": [0, 20], "everi": [3, 4, 5, 6], "exact": [6, 14, 20], "exactli": [19, 20], "exactly_equ": 9, "exampl": [4, 5, 6, 8, 10, 12, 17], "exce": [6, 18, 19], "except": [1, 16, 17, 18], "excess": [3, 4], "exclud": 6, "exclus": [16, 17, 18], "exist": [3, 4, 13], "expect": [9, 19], "expens": 6, "express": 18, "extend": [12, 13], "extens": [4, 18], "extern": 6, "extrem": [0, 6], "f688c8161a25582457b0a09deb4630a81406293b": 22, "f_x": 5, "factor": 18, "failur": 5, "fals": [0, 1, 3, 4, 5, 6, 9, 11, 16, 17, 18, 19, 21, 22], "famili": [1, 8, 11], "far": [6, 15, 16, 17, 18, 19], "fast": 0, "favor": [15, 17], "fed": 1, "feed": [19, 21], "few": 4, "fewer": [6, 19, 21], "field": 6, "filter": 4, "find": 6, "fit": [16, 17], "fix": 4, "flag": [16, 17], "flajolet": [1, 2], "flavor": [1, 6], "float": [0, 1, 3, 4, 5, 6, 9, 10, 11, 12, 15, 16, 17, 18, 19], "float32": [16, 17, 18], "float64": [16, 17], "fm85": 0, "follow": [6, 16, 18, 22], "footprint": 2, "form": [3, 4, 6, 11], "format": 12, "found": 6, "fraction": [3, 4, 16, 17, 19], "framework": 3, "frequenc": [5, 6, 17], "frequent": [5, 7, 14], "frequent_items_error_typ": 6, "frequent_items_sketch": [6, 7], "frequent_strings_sketch": [6, 7], "from": [2, 3, 4, 6, 7, 10, 11, 12, 16, 17, 18, 19, 20, 21, 22], "from_byt": 12, "full": [1, 5], "funciton": 10, "function": [0, 1, 3, 4, 5, 6, 8, 11, 14, 15, 16, 17, 18], "futur": 0, "g": 15, "gaussian": 10, "gaussiankernel": 10, "gde": 22, "gener": [6, 7, 10, 15, 16, 17, 18], "get": [16, 17], "get_apriori_error": 6, "get_cdf": [16, 17, 18], "get_compact_serialization_byt": 1, "get_epsilon_for_lg_s": 6, "get_estim": [0, 1, 3, 4, 5, 6, 22], "get_frequent_item": 6, "get_lower_bound": [0, 1, 3, 4, 5, 6], "get_max_updatable_serialization_byt": 1, "get_max_valu": [16, 17, 18], "get_min_valu": [16, 17, 18], "get_n": 17, "get_normalized_rank_error": [16, 17, 18], "get_pmf": [16, 17, 18], "get_quantil": [16, 17, 18], "get_rank": [16, 17, 18], "get_rank_lower_bound": 18, "get_rank_upper_bound": 18, "get_rel_err": 1, "get_relative_error": 5, "get_result": [0, 1, 3, 4, 19, 21], "get_rs": 18, "get_seed_hash": [3, 4], "get_serialized_size_byt": [5, 6, 19, 21], "get_siz": 12, "get_updatable_serialization_byt": 1, "get_upper_bound": [0, 1, 3, 4, 5, 6], "github": 22, "given": [0, 1, 3, 4, 5, 6, 10, 11, 12, 15, 16, 17, 18, 19, 21, 22], "global": [6, 15], "good": [2, 3], "graham": [5, 18], "gri": 6, "grow": 6, "guarante": [5, 6, 16, 17, 18], "ha": [1, 3, 4, 5, 7, 15, 16, 17, 18], "haa": 19, "handl": [3, 7, 19], "has_result": [3, 4], "hash": [0, 3, 4, 5, 6], "hat": 5, "have": [1, 6, 11, 16, 17, 18, 21], "heavi": [5, 6, 7, 14], "heaviest": 7, "help": [9, 18], "hentschel": 19, "here": 18, "hi": 0, "high": [0, 1, 15, 18], "higher": [1, 17], "highest": 1, "highli": 14, "hip": 0, "histogram": [15, 17], "histor": [0, 15], "hitter": [5, 6, 7, 14], "hll": [0, 2, 14], "hll_4": 1, "hll_6": 1, "hll_8": 1, "hll_sketch": [1, 2], "hll_union": 1, "hold": [1, 6], "how": [4, 7, 8, 13, 18], "howev": [6, 16, 18], "http": [5, 11, 18, 22], "hyper": 2, "hyperloglog": [0, 2, 3, 14], "hypothesi": 11, "hypothet": [16, 17, 18], "i": [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22], "icon": 0, "identifi": 7, "imag": 5, "implement": [0, 1, 4, 6, 7, 10, 12, 13, 16, 17, 18, 22], "improv": [1, 21], "includ": [15, 16, 17, 18, 19, 20, 21], "inclus": [1, 16, 17, 18, 20], "incom": [3, 4, 6], "increas": [16, 17, 18], "increment": 6, "independ": 16, "index": [9, 14, 16, 17], "indic": [1, 10], "inform": 19, "inherit": 10, "init_number_of_sect": 18, "initi": [1, 3, 4, 6, 18], "input": [0, 1, 3, 4, 6, 10, 11, 16, 17, 18, 20, 22, 23], "insert": [3, 5, 6], "inspir": 22, "instanc": [6, 16, 17, 18, 19, 21, 22], "instead": [17, 18], "insuffici": 11, "int": [0, 1, 3, 4, 5, 6, 9, 12, 16, 17, 18, 19, 21, 22], "int32": [16, 17, 18], "integ": [0, 5, 6, 12, 13, 15], "integr": [1, 3, 4], "intern": 6, "internet": 6, "interpret": 16, "intersect": [2, 3, 4, 13], "interv": [16, 17, 18], "introduc": 6, "invers": [0, 16], "involv": 7, "is_compact": 1, "is_empti": [0, 1, 3, 4, 5, 6, 16, 17, 18, 19, 21, 22], "is_estimation_mod": [3, 4, 16, 17, 18, 22], "is_hra": 18, "is_ord": [3, 4], "item": [1, 3, 4, 5, 7, 12, 14, 15, 16, 17, 18, 19, 20, 21, 22], "iter": 19, "its": [0, 12, 16, 17, 19], "itself": 6, "j": 19, "j_": 9, "jaccard": [3, 4, 8, 14], "java": [16, 17], "just": 16, "justin": 18, "k": [0, 1, 2, 3, 4, 6, 7, 16, 17, 18, 19, 21, 22], "kappa": 0, "karnin": [18, 22], "karnin19a": 22, "karp": 6, "keep": [1, 4, 19], "kei": [2, 4], "kept": 13, "kernel": [8, 14, 22, 23], "kernel_funct": 8, "kernel_sketch": 8, "kernelfunct": [10, 22], "kevin": 0, "kll": [14, 15, 17], "kll_doubles_sketch": [11, 16], "kll_floats_sketch": [11, 16], "kll_ints_sketch": [11, 16], "kll_items_sketch": [11, 16], "known": [0, 2, 6, 10, 14, 20], "kolmogorov": [8, 14], "ks_test": [8, 11], "kwarg": [0, 1, 3, 4, 5, 6, 10, 12, 13, 16, 17, 18, 19, 21, 22], "lang": 0, "languag": [12, 17], "larg": [1, 15, 16, 17], "larger": [2, 16, 19], "largest": 13, "last": [16, 17, 18], "lazi": 16, "lb": [6, 9], "le": 5, "learn": [10, 22], "least": [6, 8], "left": [16, 17, 18], "legaci": 6, "lemma": 18, "len": 12, "length": [6, 16, 17, 18, 19, 20, 21, 22], "less": [15, 16, 17, 18], "let": 16, "letter": 19, "level": [5, 18], "leverag": 1, "lg_config_k": 1, "lg_k": [0, 1, 3, 4], "lg_max_k": [1, 6], "lg_max_map_s": 6, "liberti": [18, 22], "librari": [2, 4, 6, 7, 10, 11, 15, 23], "like": [1, 7, 11, 16], "limit": [6, 19], "line": [16, 17, 18], "list": [5, 7, 9], "littl": 12, "load_factor": 6, "log": [1, 2], "log2": [1, 6], "logarithm": [0, 3, 4, 6], "logic": [6, 15], "longer": 2, "look": 6, "loos": 18, "lopez": 6, "low": [15, 18], "lower": [0, 1, 3, 4, 5, 6, 9, 16, 18, 21], "lower_bound": 9, "m": [6, 16, 17, 18], "machin": [10, 22], "mai": [5, 6, 14, 15, 16, 18, 19], "maintain": [3, 7], "make": 16, "mani": 3, "map": 6, "mapcap": 6, "mapsiz": 6, "margin": 19, "martin": 2, "mass": [15, 16, 17, 18], "mass_i": 16, "match": [0, 3, 4, 21], "mathemat": [10, 18], "max": [13, 16, 17, 18], "max_k": 21, "max_map_s": 6, "maximum": [1, 3, 4, 5, 6, 16, 17, 18, 19, 21], "maxintpolici": 13, "maxmapcap": 6, "maxmaps": 6, "mean": [4, 6, 16, 17, 19], "measur": [3, 4, 9, 16, 17, 18], "median": [6, 17], "member": [3, 6], "memori": [1, 2, 6], "merg": [0, 1, 4, 5, 6, 16, 17, 18, 19, 22], "method": [0, 1, 3, 4, 5, 6, 10, 12, 16, 17, 18, 19, 21, 22], "metwal": 6, "might": [6, 16], "million": 17, "min": [13, 16, 17, 18], "minim": 20, "minimum": [2, 3, 16, 17, 18, 21], "minintpolici": 13, "misra": 6, "miss": 6, "mlr": 22, "mode": [1, 3, 4, 16, 17, 18, 22], "modifi": [11, 18], "modul": [1, 6, 14], "monoton": [16, 17, 18], "more": [0, 6], "most": [7, 17], "much": [1, 6], "multipli": 17, "multiset": 6, "munro": 6, "must": [1, 3, 4, 10, 12, 13, 16, 17, 18], "muthukrishnan": 5, "n": [1, 16, 17, 18, 19, 21, 22], "name": [1, 6], "nan": [16, 17, 18], "natur": [16, 17], "ndarrai": [16, 17, 18], "nearli": [0, 16], "necessari": [16, 17, 18], "necessarili": 7, "need": [3, 5, 6, 13, 19, 20, 21], "network": 17, "never": [5, 6, 16, 18], "new": [0, 1, 6, 13, 17, 19, 21, 22], "newli": 0, "no_false_neg": 6, "no_false_posit": 6, "node": 17, "nomin": [3, 4, 18], "non": [0, 1, 3, 4, 5, 6, 16, 17, 18, 19, 21, 22], "none": [0, 1, 3, 4, 5, 6, 16, 17, 18, 19, 21, 22], "normal": [16, 17, 18], "normalized_rank_error": [16, 17], "note": [6, 9, 11, 16, 18], "novemb": 17, "now": 23, "null": [11, 12], "num_active_item": 6, "num_bucket": 5, "num_byt": 12, "num_hash": 5, "num_retain": [3, 4, 16, 17, 18, 22], "num_sampl": 21, "num_std_dev": 1, "number": [0, 1, 2, 3, 4, 5, 6, 12, 16, 17, 18, 19, 21, 22], "numer": [15, 19], "numpi": 10, "numsect": 18, "object": [0, 1, 3, 4, 5, 6, 7, 9, 10, 12, 13, 16, 17, 18, 19, 21, 22], "obtain": [5, 16, 17, 18], "occurr": 5, "off": [1, 2, 16, 17, 18], "offer": [1, 2, 7], "offest": 12, "offset": 12, "often": 7, "one": [2, 5, 6, 7, 8, 16, 17, 18, 22], "onli": [1, 6, 16, 17, 18, 23], "oper": [0, 2, 3, 4, 13, 16, 18], "opposit": 16, "opt": 21, "optim": [0, 14, 16, 20], "option": [0, 3, 4, 6, 16, 17, 18, 19, 21], "order": [3, 4, 5, 13, 15, 19], "org": [11, 18], "ortiz": 6, "other": [3, 4, 5, 16, 17], "otherwis": [0, 1, 3, 4, 5, 6, 9, 11, 16, 17, 18, 19, 21, 22], "our": 6, "output": 18, "outsid": 7, "over": [6, 15, 17], "overal": 17, "overestim": 5, "overload": [0, 1, 3, 4, 5, 11, 16, 17, 18], "overrid": [10, 12], "p": [3, 4, 11, 19], "packag": 3, "packet": [6, 17], "page": 14, "pair": [6, 8, 11], "papadimitri": 6, "paper": [0, 3, 5, 18, 22], "paramet": [0, 1, 3, 4, 5, 6, 10, 12, 13, 16, 17, 18, 19, 21, 22], "partial": 19, "particular": 18, "particularli": 10, "pass": [16, 17], "pattern": 10, "pavel": 18, "pdf": [5, 22], "per": [1, 16], "percentag": 7, "percentil": [16, 17], "perform": [0, 1, 2, 3, 4, 8, 10, 11, 16, 18], "permiss": 5, "phillip": 1, "physic": 6, "plot": 16, "plu": 6, "pmf": [15, 16, 17, 18], "point": [0, 1, 3, 4, 10, 12, 15, 16, 17, 18, 19, 22], "polici": [4, 8, 14], "portion": [15, 19], "posit": 6, "possibl": 0, "power": [6, 18], "pp": 19, "practic": [3, 6], "pre": 12, "precis": [16, 17, 19], "predic": [4, 20, 21], "present": 21, "press": 22, "print": [19, 21], "priori": [1, 6, 18], "probabilist": [1, 2, 5, 14, 15, 16, 17, 18], "probabilitii": [14, 20], "probabl": [0, 5, 6, 15, 16, 17, 18, 19, 20, 21], "problem": 14, "proceed": 22, "process": [19, 21], "produc": [0, 1, 3, 4, 5, 6, 16, 17, 18, 19, 21, 22], "project": [14, 17], "proof": 6, "properti": [0, 1, 2, 3, 4, 5, 6, 16, 17, 18, 19, 21, 22], "proport": [14, 20], "prototyp": 18, "proven": 15, "provid": [0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 15, 16, 17, 18, 21, 22, 23], "pub": 5, "purg": 6, "py": 22, "pydoublesserd": 12, "pyfloatsserd": 12, "pyintsserd": 12, "pylongsserd": 12, "pyobjectserd": [4, 6, 12, 16, 17, 18, 19, 21], "pystringsserd": 12, "python": [13, 18], "q": 16, "q_hi": 16, "q_lo": 16, "qualifi": 6, "qualnam": [1, 6], "quantil": [8, 16, 22], "quantiles_doubles_sketch": [11, 17], "quantiles_floats_sketch": [11, 17], "quantiles_ints_sketch": [11, 17], "quantiles_items_sketch": [11, 17], "queri": [5, 15, 16, 17, 21], "quickli": 14, "quit": [0, 4, 16], "r": 16, "r1": 16, "r2": 16, "r_": 16, "r_i": 16, "radial": 10, "random": [6, 19], "randomli": 20, "rang": 15, "rank": [15, 16, 17, 18], "rate": [3, 4], "reach": [1, 6], "read": [0, 1, 3, 4, 5, 6, 12, 19, 21, 22], "real": [16, 17, 18], "reason": 1, "rebuild": 6, "receiv": [1, 17], "recognit": 10, "recommend": 1, "reconstruct": 12, "redesign": 6, "rediscov": 6, "refer": [6, 8, 12, 16], "reflect": 11, "regardless": 7, "reject": 11, "rel": [1, 5, 7, 14, 15, 19, 20, 21], "relat": [7, 9, 19, 21], "relationship": 16, "relative_error": 5, "relev": 13, "reli": 10, "remain": 18, "remov": [3, 4, 6], "repeat": 6, "repres": [1, 17, 19], "req": [14, 15, 17], "req_floats_sketch": 18, "req_ints_sketch": 18, "req_items_sketch": 18, "requir": [4, 5, 6, 8, 16, 17, 18, 19, 21, 22], "reservoir": [19, 21], "reset": [1, 3, 4, 21], "respect": [16, 17], "result": [0, 3, 4, 6, 16, 17, 18, 20, 21], "retain": [3, 4, 6, 16, 17, 18, 22], "retun": 12, "return": [0, 1, 3, 4, 5, 6, 9, 10, 11, 12, 13, 16, 17, 18, 19, 21, 22], "right": [4, 16, 17, 18], "roughli": [0, 21], "round": 18, "row": 1, "rse": 18, "rule": 13, "run": 6, "runtimeerror": [16, 17, 18], "rutger": 5, "s1": 16, "s2": 16, "s_i": 16, "s_m": 16, "same": [1, 3, 11], "sampl": [3, 4, 16, 17, 18, 22], "satisfi": 5, "scheme": [12, 16], "score": 10, "search": 14, "section": 18, "section_s": 18, "secur": 0, "see": 16, "seed": [0, 3, 4, 5, 9], "seem": 16, "seen": [5, 6, 7, 15, 19], "select": 4, "self": [0, 1, 3, 4, 5, 6, 10, 12, 13, 16, 17, 18, 19, 21, 22], "semin": 2, "separ": [3, 9, 16, 17, 18], "serd": [4, 6, 8, 14, 16, 17, 18, 19, 21], "serial": [0, 1, 3, 4, 5, 6, 8, 14, 16, 17, 18, 19, 21, 22], "serialize_compact": 1, "serialize_updat": 1, "set": [2, 3, 4, 6, 13, 16, 17, 18, 22], "sever": [2, 3, 4, 6, 12], "shenker": 6, "should": [13, 16, 19], "shown": 16, "side": [16, 17], "significantli": 1, "similar": [2, 3, 4, 8, 10, 13, 14], "similarity_test": 9, "similarli": 17, "simpl": [2, 3, 6, 12], "simultan": 0, "sinc": [6, 18], "singl": [16, 17], "size": [1, 3, 4, 5, 6, 11, 12, 14, 16, 17, 18, 20, 21, 22], "sk_1": 11, "sk_2": 11, "skech": 18, "sketch": [0, 1, 2, 6, 8, 9, 11, 12, 19, 21], "sketch_a": 9, "sketch_b": 9, "slot": 1, "sm": 16, "small": [1, 6, 11], "smaller": [0, 1, 6, 16, 21], "smallest": 13, "smirnov": [8, 14], "snly": 7, "so": [0, 6, 15, 16, 17, 18, 19], "solut": 2, "some": [6, 8, 16], "sometim": 16, "somewhat": [2, 20], "sort": [3, 4, 16, 17, 18], "sourc": [3, 4], "sourch": 4, "space": [0, 1, 2, 3, 6], "special": 18, "specif": [6, 8, 10, 15, 16, 17], "specifi": [0, 1, 5, 6, 8, 12, 13, 16, 18], "speed": [0, 6], "split": [16, 17, 18], "split_point": [16, 17, 18], "sqrt": 18, "standard": [0, 1, 3, 4, 18], "start": [1, 6, 12, 18], "start_full_s": 1, "start_max_s": 1, "state": [1, 2, 3, 4, 6, 18, 21], "static": [0, 1, 3, 4, 5, 6, 16, 17, 18, 19, 21, 22], "stochast": [16, 17], "storag": [1, 12], "store": [2, 3, 6], "str": [0, 1, 3, 4, 5], "straightforward": 15, "stream": [0, 1, 3, 4, 5, 6, 7, 15, 16, 17, 18, 19, 20, 21, 22], "strictli": 19, "string": [0, 1, 3, 4, 5, 6, 7, 12, 16, 17, 18, 19, 21, 22], "string_cont": 12, "subset": [20, 21], "subtract": 16, "suggest": 5, "suggest_num_bucket": 5, "suggest_num_hash": 5, "sum": [6, 16, 17, 18, 20, 21], "summari": [0, 1, 3, 4, 5, 6, 8, 13, 16, 17, 18, 19, 21, 22], "support": [2, 6], "surviv": 0, "t": [16, 17], "tabl": [1, 6], "take": 11, "target": 1, "target_hll_typ": 1, "task": 2, "templat": [16, 17], "term": 1, "termin": 12, "test": [8, 9, 14], "tgt_hll_type": 1, "tgt_type": 1, "thaler": 18, "than": [0, 1, 2, 3, 6, 15, 16, 17, 18, 19], "thei": [4, 11, 15, 20], "them": 8, "theta": [1, 2, 4, 8, 9, 14], "theta64": [3, 4], "theta_a_not_b": 3, "theta_intersect": 3, "theta_jaccard_similar": [3, 9], "theta_sketch": [2, 3, 4, 9], "theta_union": 3, "thi": [0, 1, 4, 5, 6, 11, 12, 13, 14, 16, 17, 18, 19, 21, 22], "those": [7, 8], "thousand": [16, 17], "three": [1, 12, 15], "threshold": 9, "through": [3, 4, 6], "throw": [16, 17, 18], "thu": [16, 18], "tian": 19, "tight": 18, "time": [1, 6, 16, 17, 18], "to_byt": 12, "to_str": [0, 1, 3, 4, 5, 6, 16, 17, 18, 19, 21, 22], "too": [6, 11], "tool": 18, "top": [6, 7], "topk": 14, "total": [5, 17, 18, 19, 21], "total_weight": [5, 6], "track": 6, "trade": [1, 2, 16, 17, 18], "tradeoff": 0, "translat": 16, "trial": [16, 17], "trim": [3, 4], "true": [0, 1, 3, 4, 5, 6, 9, 11, 16, 17, 18, 19, 21, 22], "true_mass": 16, "true_rank": 16, "tupl": [2, 3, 8, 9, 12, 14], "tuple_a_not_b": [3, 4], "tuple_intersect": 4, "tuple_jaccard_similar": [4, 9], "tuple_polici": 8, "tuple_sketch": [2, 4, 8, 9, 13], "tuple_union": 4, "tuplepolici": [4, 13], "two": [0, 6, 7, 10, 11, 16, 18, 22], "type": [1, 2, 4, 6, 7, 10, 11, 12, 13, 15], "typic": 6, "u": 16, "ub": [6, 9], "under": 14, "underestim": 5, "underli": 11, "understand": [15, 18], "unequ": 19, "uniform": [15, 19, 21], "union": [0, 1, 3, 4, 13, 21], "uniqu": [0, 1, 2, 16, 17, 18], "unsurprisingli": 10, "up": [1, 6], "updat": [0, 1, 3, 4, 5, 6, 13, 16, 17, 18, 19, 21, 22], "update_summari": 13, "update_theta_sketch": 3, "update_tuple_sketch": 4, "upon": 19, "upper": [0, 1, 3, 4, 5, 6, 9, 16, 18, 21], "upper_bound": [1, 9], "us": [1, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 22], "usag": 6, "user": [0, 10, 18], "usual": 6, "v99": 22, "valid": [3, 4, 18], "valu": [0, 1, 2, 3, 4, 5, 6, 10, 11, 12, 13, 15, 16, 17, 18, 19, 21], "var": 21, "var_opt_sketch": [20, 21], "var_opt_union": 21, "variabl": [6, 18], "varianc": [14, 20], "variant": [3, 6, 7], "varopt": [14, 19, 20], "vector": [10, 16, 17, 18, 22], "veri": [4, 6, 16, 17], "version": [1, 6, 7, 12, 15, 16, 17, 18], "vesel\u00fd": 18, "via": 18, "view": 16, "visibl": 18, "w": 6, "warmup": 1, "we": [6, 11, 16, 18], "weight": [5, 6, 7, 16, 17, 18, 19, 20, 21], "well": [0, 2, 15, 21], "were": [2, 6, 16, 17], "what": [6, 15], "when": [0, 1, 3, 4, 5, 8, 13, 15, 16, 17, 18, 21], "where": [1, 6, 12, 13, 16, 19], "whether": [1, 3, 4, 18], "which": [2, 3, 4, 5, 6, 7, 10, 12, 15, 16, 17, 18], "while": [2, 3], "whose": 7, "wiki": 11, "wikipedia": 11, "win": 0, "within": [5, 8], "work": [2, 17, 18], "wors": 16, "worst": 6, "would": 6, "written": [12, 18], "x": [5, 16], "y": [16, 19], "year": 6, "yield": 16, "you": 17, "zero": 16, "zohar": [18, 22]}, "titles": ["Compressed Probabilistic Counting (CPC)", "HyperLogLog (HLL)", "Distinct Counting", "Theta Sketch", "Tuple Sketch", "CountMin Sketch", "Frequent Items", "Frequency Sketches", "Helper Classes", "Jaccard Similarity", "Kernel Function", "Kolmogorov-Smirnov Test", "Serialize/Deserialize (SerDe)", "Tuple Policy", "Apache DataSketches", "Quantiles Sketches", "KLL Sketch", "Quantiles Sketch (Deprecated)", "Relative Error Quantiles (REQ) Sketch", "Exact and Bounded, Probabilitiy Proportional to Size (EBPPS) Sampling", "Random Sampling Sketches", "Variance Optimal Sampling (VarOpt)", "Density Sketch", "Vector Sketches"], "titleterms": {"apach": 14, "bound": 19, "class": [8, 14], "compress": 0, "count": [0, 2, 14], "countmin": 5, "cpc": 0, "datasketch": 14, "densiti": 22, "deprec": 17, "deseri": 12, "distinct": [2, 14], "ebpp": 19, "error": 18, "estim": 14, "exact": 19, "frequenc": [7, 14], "frequent": 6, "function": 10, "helper": [8, 14], "hll": 1, "hyperloglog": 1, "indic": 14, "item": 6, "jaccard": 9, "kernel": 10, "kll": 16, "kolmogorov": 11, "optim": 21, "polici": 13, "probabilist": 0, "probabilitii": 19, "proport": 19, "quantil": [14, 15, 17, 18], "random": [14, 20], "rel": 18, "req": 18, "sampl": [14, 19, 20, 21], "serd": 12, "serial": 12, "similar": 9, "size": 19, "sketch": [3, 4, 5, 7, 14, 15, 16, 17, 18, 20, 22, 23], "smirnov": 11, "tabl": 14, "test": 11, "theta": 3, "tupl": [4, 13], "varianc": 21, "varopt": 21, "vector": [14, 23]}}) \ No newline at end of file diff --git a/docs/5.1.1/vector/density_sketch.html b/docs/5.1.1/vector/density_sketch.html new file mode 100644 index 00000000..aa3d6f2f --- /dev/null +++ b/docs/5.1.1/vector/density_sketch.html @@ -0,0 +1,246 @@ + + + + + + + + + Density Sketch — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Density Sketch

+

Builds a coreset from the given set of input points. +Provides density estimate at a given point.

+

Based on the following paper: Zohar Karnin, Edo Liberty +“Discrepancy, Coresets, and Sketches in Machine Learning” +https://proceedings.mlr.press/v99/karnin19a/karnin19a.pdf

+

Inspired by the following implementation: https://github.com/edoliberty/streaming-quantiles/blob/f688c8161a25582457b0a09deb4630a81406293b/gde.py

+

Requires the use of a KernelFunction to compute the distance between two vectors.

+
+
+class density_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, kernel: _datasketches.KernelFunction) _datasketches.density_sketch
+

Reads a bytes object and returns the corresponding density_sketch

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int, dim: int, kernel: _datasketches.KernelFunction) None
+

Creates a new density sketch

+
+
Parameters:
+
    +
  • k (int) – controls the size and error of the sketch

  • +
  • dim (int) – dimension of the input data

  • +
  • kernel (KernelFunction) – instance of a kernel

  • +
+
+
+
+ +
+
+property dim
+

The configured parameter dim

+
+ +
+
+get_estimate
+

Returns an approximate density at the given point

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Updates the sketch with the given vector

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.1.1/vector/index.html b/docs/5.1.1/vector/index.html new file mode 100644 index 00000000..e3e7fc38 --- /dev/null +++ b/docs/5.1.1/vector/index.html @@ -0,0 +1,133 @@ + + + + + + + + + Vector Sketches — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Vector Sketches

+

These sketches are designed to accept vector inputs. For now, the library provides only the +density_sketch for Kernel Density Estimation.

+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.2.0/.buildinfo b/docs/5.2.0/.buildinfo new file mode 100644 index 00000000..d6ebb969 --- /dev/null +++ b/docs/5.2.0/.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: 86d4b171ba47c51d1a3d7f924e02560f +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/docs/5.2.0/_sources/distinct_counting/cpc.rst.txt b/docs/5.2.0/_sources/distinct_counting/cpc.rst.txt new file mode 100644 index 00000000..6a28d387 --- /dev/null +++ b/docs/5.2.0/_sources/distinct_counting/cpc.rst.txt @@ -0,0 +1,32 @@ +Compressed Probabilistic Counting (CPC) +--------------------------------------- +High performance C++ implementation of Compressed Probabilistic Counting (CPC) Sketch. +This is a unique-counting sketch that implements the Compressed Probabilistic Counting (CPC, a.k.a FM85) algorithms developed by Kevin Lang in his paper +`Back to the Future: an Even More Nearly Optimal Cardinality Estimation Algorithm `_. +This sketch is extremely space-efficient when serialized. +In an apples-to-apples empirical comparison against compressed HyperLogLog sketches, this new algorithm simultaneously wins on the two dimensions of the space/accuracy tradeoff and produces sketches that are smaller than the entropy of HLL, so no possible implementation of compressed HLL can match its space efficiency for a given accuracy. As described in the paper this sketch implements a newly developed ICON estimator algorithm that survives unioning operations, another well-known estimator, the Historical Inverse Probability (HIP) estimator does not. +The update speed performance of this sketch is quite fast and is comparable to the speed of HLL. +The unioning (merging) capability of this sketch also allows for merging of sketches with different configurations of K. +For additional security this sketch can be configured with a user-specified hash seed. + + +.. autoclass:: _datasketches.cpc_sketch + :members: + :undoc-members: + :exclude-members: deserialize + + .. rubric:: Static Methods: + + .. automethod:: deserialize + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + + +.. autoclass:: _datasketches.cpc_union + :members: + :undoc-members: + :exclude-members: deserialize + + .. automethod:: __init__ diff --git a/docs/5.2.0/_sources/distinct_counting/hyper_log_log.rst.txt b/docs/5.2.0/_sources/distinct_counting/hyper_log_log.rst.txt new file mode 100644 index 00000000..287209b0 --- /dev/null +++ b/docs/5.2.0/_sources/distinct_counting/hyper_log_log.rst.txt @@ -0,0 +1,55 @@ +HyperLogLog (HLL) +----------------- +This is a high performance implementation of Phillipe Flajolet's HLL sketch but with significantly improved error behavior. + +If the ONLY use case for sketching is counting uniques and merging, the HLL sketch is a reasonable choice, although the highest performing in terms of accuracy for storage space consumed is CPC (Compressed Probabilistic Counting). For large enough counts, this HLL version (with HLL_4) can be 2 to 16 times smaller than the Theta sketch family for the same accuracy. + +This implementation offers three different types of HLL sketch, each with different trade-offs with accuracy, space and performance. +These types are specified with the target_hll_type parameter. + +In terms of accuracy, all three types, for the same lg_config_k, have the same error distribution as a function of ``n``, the number of unique values fed to the sketch. +The configuration parameter ``lg_config_k`` is the log-base-2 of ``k``, where ``k`` is the number of buckets or slots for the sketch. + +During warmup, when the sketch has only received a small number of unique items (up to about 10% of ``k``), this implementation leverages a new class of estimator algorithms with significantly better accuracy. + + +.. autoclass:: _datasketches.tgt_hll_type + + .. autoattribute:: HLL_4 + :annotation: : 4 bits per entry + + .. autoattribute:: HLL_6 + :annotation: : 6 bits per entry + + .. autoattribute:: HLL_8 + :annotation: : 8 bits per entry + + +.. autoclass:: _datasketches.hll_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_max_updatable_serialization_bytes, get_rel_err + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_max_updatable_serialization_bytes + .. automethod:: get_rel_err + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: _datasketches.hll_union + :members: + :undoc-members: + :exclude-members: get_rel_err + + .. rubric:: Static Methods: + + .. automethod:: get_rel_err + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + \ No newline at end of file diff --git a/docs/5.2.0/_sources/distinct_counting/index.rst.txt b/docs/5.2.0/_sources/distinct_counting/index.rst.txt new file mode 100644 index 00000000..f4038815 --- /dev/null +++ b/docs/5.2.0/_sources/distinct_counting/index.rst.txt @@ -0,0 +1,24 @@ +Distinct Counting +================= + +.. currentmodule:: datasketches + +Distinct counting is one of the earliest tasks to which sketches were applied. The concept is simple: +Provide an estimate of the number of unique elements in a set of data. One of the earliest solutions came +from Flajolet and Martin in 1985 with their seminal work +`Probabilistic counting Algorithms for Data Base Applications `_. + +The DataSketches library offers several types of distinct counting sketches, each with different properties. + + * :class:`hll_sketch`: Hyper Log Log, a well-known sketch for distinct counting but no longer state-of-the-art. + * :class:`cpc_sketch`: Provides a better accuracy-space trade-off than HLL, but with a somewhat larger footprint while in-memory. + * :class:`theta_sketch`: Theta sketch, a type of k-minimum value sketch, which provide good performance with intersection and set difference operations. + * :class:`tuple_sketch`: Tuple sketch, which is similar to a theta sketch but supports additional data stored with each key. + +.. toctree:: + :maxdepth: 1 + + hyper_log_log + cpc + theta + tuple \ No newline at end of file diff --git a/docs/5.2.0/_sources/distinct_counting/theta.rst.txt b/docs/5.2.0/_sources/distinct_counting/theta.rst.txt new file mode 100644 index 00000000..94951f96 --- /dev/null +++ b/docs/5.2.0/_sources/distinct_counting/theta.rst.txt @@ -0,0 +1,65 @@ +Theta Sketch +------------ + +.. currentmodule:: datasketches + +Theta sketches are used for distinct counting. + +The theta package contains the basic sketch classes that are members of the `Theta Sketch Framework `_. +There is a separate Tuple package for many of the sketches that are derived from the same algorithms defined in the Theta Sketch Framework paper. + +The *Theta Sketch* sketch is a space-efficient method for estimating cardinalities of sets. +It can also easily handle set operations (such as union, intersection, difference) while maintaining good accuracy. +Theta sketch is a practical variant of the K-Minimum Values sketch which avoids the need to sort the stored +hash values on every insertion to the sketch. +It has better error properties than the HyperLogLog sketch for set operations beyond the simple union. + +Set operations (union, intersection, A-not-B) are performed through the use of dedicated objects. + +Several `Jaccard similarity `_ +measures can be computed between theta sketches with the :class:`theta_jaccard_similarity` class. + +.. autoclass:: theta_sketch + :members: + :undoc-members: + +.. autoclass:: update_theta_sketch + :members: + :undoc-members: + + .. automethod:: __init__ + + +.. autoclass:: compact_theta_sketch + :members: + :undoc-members: + :exclude-members: deserialize + + .. rubric:: Static Methods: + + .. automethod:: deserialize + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + + +.. autoclass:: theta_union + :members: + :undoc-members: + + .. automethod:: __init__ + + +.. autoclass:: theta_intersection + :members: + :undoc-members: + + .. automethod:: __init__ + + +.. autoclass:: theta_a_not_b + :members: + :undoc-members: + + .. automethod:: __init__ diff --git a/docs/5.2.0/_sources/distinct_counting/tuple.rst.txt b/docs/5.2.0/_sources/distinct_counting/tuple.rst.txt new file mode 100644 index 00000000..e4a369f2 --- /dev/null +++ b/docs/5.2.0/_sources/distinct_counting/tuple.rst.txt @@ -0,0 +1,64 @@ +Tuple Sketch +------------ + +.. currentmodule:: datasketches + +Tuple sketches are an extension of Theta sketches, meaning they provide estimate of distinct counts, that +allow the keeping of arbitrary summaries associated with each retained key +(for example, a count for every key). The use of a :class:`tuple_sketch` requires a :class:`TuplePolicy` which +defines how summaries are created, updated, merged, or intersected. The library provides a few basic +examples of :class:`TuplePolicy` implementations, but the right custom summary and policy can allow very +complicated analysis to be performed quite easily. + +Set operations (union, intersection, A-not-B) are performed through the use of dedicated objects. + +Several `Jaccard similarity `_ +measures can be computed between theta sketches with the :class:`tuple_jaccard_similarity` class. + +.. note:: + Serializing and deserializing this sketch requires the use of a :class:`PyObjectSerDe`. + +.. autoclass:: tuple_sketch + :members: + :undoc-members: + +.. autoclass:: update_tuple_sketch + :members: + :undoc-members: + + .. automethod:: __init__ + + +.. autoclass:: compact_tuple_sketch + :members: + :undoc-members: + :exclude-members: deserialize + + .. rubric:: Static Methods: + + .. automethod:: deserialize + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + + +.. autoclass:: tuple_union + :members: + :undoc-members: + + .. automethod:: __init__ + + +.. autoclass:: tuple_intersection + :members: + :undoc-members: + + .. automethod:: __init__ + + +.. autoclass:: tuple_a_not_b + :members: + :undoc-members: + + .. automethod:: __init__ diff --git a/docs/5.2.0/_sources/frequency/count_min_sketch.rst.txt b/docs/5.2.0/_sources/frequency/count_min_sketch.rst.txt new file mode 100644 index 00000000..b53b02e4 --- /dev/null +++ b/docs/5.2.0/_sources/frequency/count_min_sketch.rst.txt @@ -0,0 +1,27 @@ +CountMin Sketch +--------------- + +The CountMin sketch, as described in Cormode and Muthukrishnan in +http://dimacs.rutgers.edu/~graham/pubs/papers/cm-full.pdf, +is used for approximate Frequency Estimation. +For an item :math:`x` with frequency :math:`f_x`, the sketch provides an estimate, :math:`\hat{f_x}`, +such that :math:`f_x \approx \hat{f_x}.` +The sketch guarantees that :math:`f_x \le \hat{f_x}` and provides a probabilistic upper bound which is dependent on the size parameters. +The sketch provides an estimate of the occurrence frequency for any queried item but, in contrast +to the Frequent Items Sketch, this sketch does not provide a list of +heavy hitters. + +.. currentmodule:: _datasketches + +.. autoclass:: count_min_sketch + :members: + :undoc-members: + :exclude-members: deserialize, suggest_num_buckets, suggest_num_hashes + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: suggest_num_buckets + .. automethod:: suggest_num_hashes + + .. rubric:: Non-static Methods: diff --git a/docs/5.2.0/_sources/frequency/frequent_items.rst.txt b/docs/5.2.0/_sources/frequency/frequent_items.rst.txt new file mode 100644 index 00000000..76d81f58 --- /dev/null +++ b/docs/5.2.0/_sources/frequency/frequent_items.rst.txt @@ -0,0 +1,120 @@ +Frequent Items +-------------- + +.. currentmodule:: datasketches + +This sketch is useful for tracking approximate frequencies of items (``object`` or ``string``) with optional associated +integer counts that are members of a multiset of such items. +The true frequency of an item is defined to be the sum of associated counts. + +This implementation provides the following capabilities: + +* Estimate the *frequency* of an item. +* Return *upper* and *lower bounds* of any item, such that the true frequency is always between the upper and lower bounds. +* Return a global *maximum error* that holds for all items in the stream. +* Return an array of frequent items that qualify either a *NO_FALSE_POSITIVES* or a *NO_FALSE_NEGATIVES* error type. +* *Merge* itself with another sketch object created from this class. +* *Serialize/Deserialize* to/from a byte array. + +**Space Usage** + +The sketch is initialized with a maximum map size, ``maxMapSize``, that specifies the maximum physical length of the internal hash map of the form ``(object item, int count)``. +The maximum map size is always a power of 2, defined through the variables ``lg_max_map_size``. + +The hash map starts at a very small size (8 entries) and grows as needed up to the specified maximum map size. + +Excluding external space required for the item objects, the internal memory space usage of this sketch is ``18 * mapSize`` bytes (assuming 8 bytes for each reference), +plus a small constant number of additional bytes. +The internal memory space usage of this sketch will never exceed ``18 * maxMapSize`` bytes, plus a small constant number of additional bytes. + +**Maximum Capacity of the Sketch** + +The ``LOAD_FACTOR`` for the hash map is internally set at :math:`75\%`, which means at any time the map capacity of ``(item, count)`` pairs is ``mapCap = 0.75 * mapSize``. +The maximum capacity of ``(item, count)`` pairs of the sketch is ``maxMapCap = 0.75 * maxMapSize``. + +**Updating the sketch with ``(item, count)`` pairs** + +If the item is found in the hash map, the mapped count field (the "counter") is incremented by the incoming count; otherwise, a new counter ``(item, count)`` pair is created. +If the number of tracked counters reaches the maximum capacity of the hash map, the sketch decrements all of the counters (by an approximately computed median) +and removes any non-positive counters. + +**Accuracy** + +If fewer than ``0.75 * maxMapSize`` different items are inserted into the sketch, the estimated frequencies returned by the sketch will be exact. + +The logic of the frequent items sketch is such that the stored counts and true counts are never too different. +More specifically, for any item, the sketch can return an estimate of the true frequency of item, along with upper and lower bounds on the frequency (that hold deterministically). + +For this implementation and for a specific active item, it is guaranteed that the true frequency will be between the Upper Bound (UB) and the Lower Bound (LB) computed for that item. +Specifically, ``(UB- LB) ≤ W * epsilon``, where :math:`W` denotes the sum of all item counts, and :math:`epsilon = 3.5/M`, where :math:`epsilon = M` is the maxMapSize. + +This is a worst-case guarantee that applies to arbitrary inputs. +For inputs typically seen in practice, ``(UB-LB)`` is usually much smaller. + +**Background** + +This code implements a variant of what is commonly known as the "Misra-Gries algorithm". +Variants of it were discovered and rediscovered and redesigned several times over the years: + +* *Finding repeated elements*, Misra, Gries, 1982 +* *Frequency estimation of Internet packet streams with limited space* Demaine, Lopez-Ortiz, Munro, 2002 +* *A simple algorithm for finding frequent elements in streams and bags* Karp, Shenker, Papadimitriou, 2003 +* *Efficient Computation of Frequent and Top-k Elements in Data Streams* Metwally, Agrawal, Abbadi, 2006 + + +For speed, we do employ some randomization that introduces a small probability that our proof of the worst-case bound might not apply to a given run. +However, we have ensured that this probability is extremely small. +For example, if the stream causes one table purge (rebuild), our proof of the worst-case bound applies with a probability of at least `1 - 1E-14`. +If the stream causes ``1E9`` purges, our proof applies with a probability of at least ``1 - 1E-5``. + +There are two flavors of Frequent Items Sketches, one with generic items (objects) and another specific to strings. +The string version is a legacy name from before the library supported generic objects and is retained +only for backwards compatibility. + +.. note:: + The :class:`frequent_items_sketch` uses an input object's ``__hash__`` and ``__eq__`` methods. + +.. note:: + Serializing and deserializing the :class:`frequent_items_sketch` requires the use of a :class:`PyObjectSerDe`. + +.. autoclass:: frequent_items_error_type + + .. autoattribute:: NO_FALSE_POSITIVES + :annotation: : Returns only true positives but may miss some heavy hitters. + + .. autoattribute:: NO_FALSE_NEGATIVES + :annotation: : Does not miss any heavy hitters but may return false positives. + + +.. autoclass:: frequent_items_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_epsilon_for_lg_size, get_apriori_error + :member-order: groupwise + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_epsilon_for_lg_size + .. automethod:: get_apriori_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + + +.. autoclass:: frequent_strings_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_epsilon_for_lg_size, get_apriori_error + :member-order: groupwise + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_epsilon_for_lg_size + .. automethod:: get_apriori_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ diff --git a/docs/5.2.0/_sources/frequency/index.rst.txt b/docs/5.2.0/_sources/frequency/index.rst.txt new file mode 100644 index 00000000..3cd3dfa5 --- /dev/null +++ b/docs/5.2.0/_sources/frequency/index.rst.txt @@ -0,0 +1,15 @@ +Frequency Sketches +================== + +Frequency estimation involves determining how often an item has been seen in a stream. The library currently +offers two types of sketches for frequency estimation, one of which has two closely-related variants. + + * :class:`frequent_items_sketch`: Identifies the *Top K* or *heavy hitters* in a stream, those items whose weight is above a certain percentage of the entire stream. Does not necessarily provide an estimate for most items outside the heavy hitters. + * :class:`frequent_strings_sketch`: Like the items version but containing snly strings (an implementation from before the library handled generic objects). + * :class:`count_min_sketch`: Provides an estimate for any item, regardless of relative weight, but does not maintain a list of the heaviest items. + +.. toctree:: + :maxdepth: 1 + + frequent_items + count_min_sketch \ No newline at end of file diff --git a/docs/5.2.0/_sources/helper/index.rst.txt b/docs/5.2.0/_sources/helper/index.rst.txt new file mode 100644 index 00000000..182b8e85 --- /dev/null +++ b/docs/5.2.0/_sources/helper/index.rst.txt @@ -0,0 +1,24 @@ +Helper Classes +============== + +.. currentmodule:: dataksetches + +These classes are required for certain sketches or specific +functionality within sketches. +Some of them are abstract base classes, but in those cases there is at +least one reference example of a concrete class. + + * :class:`serde` is used when serializing and deserializing sketches. + * :class:`jaccard` is used to compute the Jaccard similarity between pairs of theta or tuple sketches. + * :class:`tuple_policy` is required to use a :class:`tuple_sketch` by specifying how summaries are combined. + * :func:`ks_test` performs a Kolmogorov-Smirnov test on absolute-error quantiles family sketches. + * :class:`kernel_function` is required when using a :class:`kernel_sketch` for Kernel Density Estimation. + +.. toctree:: + :maxdepth: 1 + + serde + jaccard + tuple_policy + ks_test + kernel diff --git a/docs/5.2.0/_sources/helper/jaccard.rst.txt b/docs/5.2.0/_sources/helper/jaccard.rst.txt new file mode 100644 index 00000000..d3b9bfa3 --- /dev/null +++ b/docs/5.2.0/_sources/helper/jaccard.rst.txt @@ -0,0 +1,23 @@ +Jaccard Similarity +################## + +.. currentmodule:: datasketches + +These objects provide measures related to the `Jaccard similarity `_ +of :class:`theta_sketch` and :class:`tuple_sketch` objects. + +Note that there are separate classes to be used for theta and tuple sketches. + +.. autoclass:: theta_jaccard_similarity + + .. automethod:: jaccard + .. automethod:: exactly_equal + .. automethod:: similarity_test + .. automethod:: dissimilarity_test + +.. autoclass:: tuple_jaccard_similarity + + .. automethod:: jaccard + .. automethod:: exactly_equal + .. automethod:: similarity_test + .. automethod:: dissimilarity_test diff --git a/docs/5.2.0/_sources/helper/kernel.rst.txt b/docs/5.2.0/_sources/helper/kernel.rst.txt new file mode 100644 index 00000000..bdc2c729 --- /dev/null +++ b/docs/5.2.0/_sources/helper/kernel.rst.txt @@ -0,0 +1,21 @@ +Kernel Function +############### + +.. currentmodule:: datasketches + +A `kernel function `_ is a specific type of +mathematical funciton that is particularly useful in certain machine learning and pattern recognition +contexts. The :class:`density_sketch` performs approximate +`kernel density estimation `_ which, unsurprisingly, +relies on the use of such a kernel function. + +The library provides an abstract base class :class:`KernelFunction` and an example implementation of a +Gaussian (also known as a Radial Basis Function) kernel. Custom classes must override the base class +and provide a floating point value as a score indicating the similarity of two input vectors. + +.. autoclass:: KernelFunction + + .. automethod:: __call__ + +.. autoclass:: GaussianKernel + :show-inheritance: \ No newline at end of file diff --git a/docs/5.2.0/_sources/helper/ks_test.rst.txt b/docs/5.2.0/_sources/helper/ks_test.rst.txt new file mode 100644 index 00000000..c9bc19b0 --- /dev/null +++ b/docs/5.2.0/_sources/helper/ks_test.rst.txt @@ -0,0 +1,14 @@ +Kolmogorov-Smirnov Test +####################### + +.. currentmodule:: datasketches + +A `Kolmogorov-Smirnov Test `_` is +a test of equality of two distributions to determine if they are likely to have come from the same +underlying distribution. +The DataSketches library provides a modified form of the test that takes into account the error +in each underlying sketch in the analysis. + +Currently, the test assumes both input sketches are of the same family and data type. + +.. autofunction:: ks_test diff --git a/docs/5.2.0/_sources/helper/serde.rst.txt b/docs/5.2.0/_sources/helper/serde.rst.txt new file mode 100644 index 00000000..ccac1d84 --- /dev/null +++ b/docs/5.2.0/_sources/helper/serde.rst.txt @@ -0,0 +1,34 @@ +Serialize/Deserialize (SerDe) +############################# + +.. currentmodule:: datasketches + +A SerDe is a class used to serialize items sketches to a :class:`bytes` object in binary. +Several example SerDes are provided as references. + +The use of binary-compatible SerDes in different languages is critical for cross-language compatibility. + +Each implementation must extend the :class:`PyObjectSerDe` class and override all three of its methods. + +.. autoclass:: PyObjectSerDe + + .. automethod:: get_size + .. automethod:: to_bytes + .. automethod:: from_bytes + + +The provided SerDes are: + +.. autoclass:: PyStringsSerDe + :show-inheritance: + +.. autoclass:: PyIntsSerDe + :show-inheritance: + +.. autoclass:: PyLongsSerDe + :show-inheritance: + +.. autoclass:: PyFloatsSerDe + :show-inheritance: + +.. autoclass:: PyDoublesSerDe diff --git a/docs/5.2.0/_sources/helper/tuple_policy.rst.txt b/docs/5.2.0/_sources/helper/tuple_policy.rst.txt new file mode 100644 index 00000000..3f5781f2 --- /dev/null +++ b/docs/5.2.0/_sources/helper/tuple_policy.rst.txt @@ -0,0 +1,25 @@ +Tuple Policy +############ + +.. currentmodule:: datasketches + +A Tuple Policy is needed when using a :class:`tuple_sketch` in order to specify how the +summary values should be created, updated, combined, or intersected. A summary can consist of +any python object. + +Each implementation must extend the abstract base class :class:`TuplePolicy`. + +.. autoclass:: TuplePolicy + + .. automethod:: create_summary + .. automethod:: update_summary + .. automethod:: __call__ + +.. autoclass:: AccumulatorPolicy + :show-inheritance: + +.. autoclass:: MinIntPolicy + :show-inheritance: + +.. autoclass:: MaxIntPolicy + :show-inheritance: diff --git a/docs/5.2.0/_sources/index.rst.txt b/docs/5.2.0/_sources/index.rst.txt new file mode 100644 index 00000000..b683e1fd --- /dev/null +++ b/docs/5.2.0/_sources/index.rst.txt @@ -0,0 +1,73 @@ +.. datasketches documentation master file, created by + sphinx-quickstart on Tue Jul 25 11:04:59 2023. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Apache DataSketches +================================================= + +**DataSketches** are highly-efficient algorithms to analyze big data quickly. + + +Counting Distincts +################## +.. + maxdepth: 1 means only the heading is printed in the contents +.. toctree:: + :maxdepth: 2 + + distinct_counting/index + +Quantile Estimation +################### + +.. toctree:: + :maxdepth: 2 + + quantiles/index + +Frequency Sketches +################## +This problem may also be known as **heavy hitters** or **TopK** + +.. toctree:: + :maxdepth: 2 + + frequency/index + +Vector Sketches +############### + +.. toctree:: + :maxdepth: 2 + + vector/index + + +Random Sampling +############### + +.. toctree:: + :maxdepth: 2 + + sampling/index + +Helper Classes +############## + +.. toctree:: + :maxdepth: 2 + + helper/index + + +.. note:: + + This project is under active development. + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/docs/source/quantiles/index.rst b/docs/5.2.0/_sources/quantiles/index.rst.txt similarity index 100% rename from docs/source/quantiles/index.rst rename to docs/5.2.0/_sources/quantiles/index.rst.txt diff --git a/docs/source/quantiles/kll.rst b/docs/5.2.0/_sources/quantiles/kll.rst.txt similarity index 100% rename from docs/source/quantiles/kll.rst rename to docs/5.2.0/_sources/quantiles/kll.rst.txt diff --git a/docs/5.2.0/_sources/quantiles/quantiles_depr.rst.txt b/docs/5.2.0/_sources/quantiles/quantiles_depr.rst.txt new file mode 100644 index 00000000..18dd5df6 --- /dev/null +++ b/docs/5.2.0/_sources/quantiles/quantiles_depr.rst.txt @@ -0,0 +1,106 @@ +Quantiles Sketch (Deprecated) +----------------------------- + +.. currentmodule:: datasketches + +This is a deprecated quantiles sketch that is included for cross-language compatibility. +Most new projects will favor the KLL sketch over this one, or the REQ sketch for higher accuracy +at the very edge of a distribution. + +This is a stochastic streaming sketch that enables near-real time analysis of the +approximate distribution from a very large stream in a single pass. +The analysis is obtained using `get_rank()` and `get_quantile()` functions, +the Probability Mass Function from `get_pmf()`` and the Cumulative Distribution Function from `get_cdf`. + +Consider a large stream of one million values such as packet sizes coming into a network node. +The natural rank of any specific size value is its index in the hypothetical sorted +array of values. +The normalized rank is the natural rank divided by the stream size, +in this case one million. +The value corresponding to the normalized rank of `0.5` represents the 50th percentile or median +value of the distribution, or `get_quantile(0.5)`. +Similarly, the 95th percentile is obtained from `get_quantile(0.95)`. + +From the min and max values, for example, 1 and 1000 bytes, +you can obtain the PMF from `get_pmf(100, 500, 900)` that will result in an array of +4 fractional values such as {.4, .3, .2, .1}, which means that +40% of the values were < 100, +30% of the values were ≥ 100 and < 500, +20% of the values were ≥ 500 and < 900, and +10% of the values were ≥ 900. +A frequency histogram can be obtained by multiplying these fractions by `get_n()`, +which is the total count of values received. +The `get_cdf()`` works similarly, but produces the cumulative distribution instead. + +As of November 2021, this implementation produces serialized sketches which are binary-compatible +with the equivalent Java implementation only when template parameter T = double +(64-bit double precision values). + +The accuracy of this sketch is a function of the configured value `k`, which also affects +the overall size of the sketch. Accuracy of this quantile sketch is always with respect to +the normalized rank. A `k` of 128 produces a normalized, rank error of about 1.7%. +For example, the median item returned from `get_quantile(0.5)` will be between the actual items +from the hypothetically sorted array of input items at normalized ranks of 0.483 and 0.517, with +a confidence of about 99%. + +.. note:: + For the :class:`quantiles_items_sketch`, objects must be comparable with ``__lt__``. + +.. note:: + Serializing and deserializing a :class:`quantiles_items_sketch` requires the use of a :class:`PyObjectSerDe`. + +.. autoclass:: quantiles_ints_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_normalized_rank_error + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_normalized_rank_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: quantiles_floats_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_normalized_rank_error + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_normalized_rank_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: quantiles_doubles_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_normalized_rank_error + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_normalized_rank_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: quantiles_items_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_normalized_rank_error + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_normalized_rank_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ diff --git a/docs/5.2.0/_sources/quantiles/req.rst.txt b/docs/5.2.0/_sources/quantiles/req.rst.txt new file mode 100644 index 00000000..3f63e01e --- /dev/null +++ b/docs/5.2.0/_sources/quantiles/req.rst.txt @@ -0,0 +1,79 @@ +Relative Error Quantiles (REQ) Sketch +------------------------------------- + +.. currentmodule:: datasketches + +This is an implementation based on the `paper `_ "Relative Error Streaming Quantiles" by Graham Cormode, Zohar Karnin, Edo Liberty, Justin Thaler, Pavel Veselý, and loosely derived from a Python prototype written by Pavel Veselý. + +This implementation differs from the algorithm described in the paper in the following: + +The algorithm requires no upper bound on the stream length. +Instead, each relative-compactor counts the number of compaction operations performed so far (via variable state). +Initially, the relative-compactor starts with `INIT_NUMBER_OF_SECTIONS`. +Each time the number of compactions `(variable state) exceeds 2^{numSections - 1}`, we double `numSections`. +Note that after merging the sketch with another one variable state may not correspond to the number of compactions performed at a particular level, however, +since the state variable never exceeds the number of compactions, the guarantees of the sketch remain valid. + +The size of each section (variable `k` and `section_size` in the code and parameter `k` in the paper) is +initialized with a number set by the user via variable `k`. +When the number of sections doubles, we decrease section_size by a factor of `sqrt(2)`. +This is applied at each level separately. +Thus, when we double the number of sections, the nominal compactor size increases by a factor of approx. `sqrt(2) (+/- rounding)`. + +The merge operation here does not perform "special compactions", which are used in the paper to allow for a tight mathematical analysis of the sketch. +This implementation provides a number of capabilities not discussed in the paper or provided in the Python prototype. + +The Python prototype only implemented high accuracy for low ranks. This implementation provides the user with the ability to +choose either high rank accuracy or low rank accuracy at the time of sketch construction. +The Python prototype only implemented a comparison criterion of `INCLUSIVE`. +This implementation allows the user to use both the `INCLUSIVE` criterion and the `EXCLUSIVE` criterion. +This implementation provides extensive debug visibility into the operation of the sketch with two levels of detail output. +This is not only useful for debugging, but is a powerful tool to help users understand how the sketch works. + +.. note:: + For the :class:`req_items_sketch`, objects must be comparable with ``__lt__``. + +.. note:: + Serializing and deserializing a :class:`req_items_sketch` requires the use of a :class:`PyObjectSerDe`. + +.. autoclass:: req_ints_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_RSE + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_RSE + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: req_floats_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_RSE + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_RSE + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: req_items_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_RSE + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_RSE + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ diff --git a/docs/source/quantiles/tdigest.rst b/docs/5.2.0/_sources/quantiles/tdigest.rst.txt similarity index 100% rename from docs/source/quantiles/tdigest.rst rename to docs/5.2.0/_sources/quantiles/tdigest.rst.txt diff --git a/docs/5.2.0/_sources/sampling/ebpps.rst.txt b/docs/5.2.0/_sources/sampling/ebpps.rst.txt new file mode 100644 index 00000000..b2253209 --- /dev/null +++ b/docs/5.2.0/_sources/sampling/ebpps.rst.txt @@ -0,0 +1,33 @@ +Exact and Bounded, Probabilitiy Proportional to Size (EBPPS) Sampling +--------------------------------------------------------------------- + +.. currentmodule:: datasketches + +An EBPPS sketch produces a randome sample of data from a stream of items, ensuring that the probability +of including an item is always exactly equal to the item's size. The size of an item is defined as its +weight relative to the total weight of all items seen so far by the sketch. In contrast to VarOpt sampling, +this sketch may return fewer than `k` items in order to keep the probability of including an item strictly +proportional to its size. + +This sketch is based on: B. Hentschel, P. J. Haas, Y. Tian +"Exact PPS Sampling with Bounded Sample Size", +Information Processing Letters, 2023. + +EBPPS sampling is related to reservoir sampling, but handles unequal item weights. +Feeding the sketch items with a uniform weight value will produce a sample equivalent to reservoir sampling. + +.. note:: + Serializing and deserializing this sketch requires the use of a :class:`PyObjectSerDe`. + +.. autoclass:: ebpps_sketch + :members: + :undoc-members: + :exclude-members: deserialize + + .. rubric:: Static Methods: + + .. automethod:: deserialize + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ diff --git a/docs/5.2.0/_sources/sampling/index.rst.txt b/docs/5.2.0/_sources/sampling/index.rst.txt new file mode 100644 index 00000000..fca6c3ce --- /dev/null +++ b/docs/5.2.0/_sources/sampling/index.rst.txt @@ -0,0 +1,21 @@ +Random Sampling Sketches +======================== + +.. currentmodule:: datasketches + +These sketches are used to randomly sample items. The length of the input +stream does not need to be known in advance. + +Both VarOpt (Variance Optimal) and EBPPS (Exact and Bounded, +Probability Proportional to Size) sketches will include sample items based on +each item's weight relative to the weight of the entire stream but +they differ in details: + + * :class:`ebpps_sketch` ensures that the probability of including an item is always exactly proportional to the item's weight. + * :class:`var_opt_sketch` optimizes for applying a predicate to the resulting sample such that the variance of the subset sum after applying the predicate is minimized, even if the inclusion probability differs somewhat from being proportional to the item's weight. + +.. toctree:: + :maxdepth: 1 + + varopt + ebpps diff --git a/docs/5.2.0/_sources/sampling/varopt.rst.txt b/docs/5.2.0/_sources/sampling/varopt.rst.txt new file mode 100644 index 00000000..d837835e --- /dev/null +++ b/docs/5.2.0/_sources/sampling/varopt.rst.txt @@ -0,0 +1,42 @@ +Variance Optimal Sampling (VarOpt) +---------------------------------- + +.. currentmodule:: datasketches + +A VarOpt sketch samples data from a stream of items. The sketch is desinged for optimal (minimum) +variance when querying the sketch to estimate subset sums of items matching a provided predicate. +The sketch will produce a sample of size `k` (or smaller if fewer items have been presented), with +the probability of including an item roughly corresponding it the item's weight relative to the total +weight of all items presented to the sketch. + +VarOpt sampling is related to reservoir sampling, with improved error bounds for subset sum estimation. +Feeding the sketch items with a uniform weight value will produce a sample equivalent to reservoir sampling. + +.. note:: + Serializing and deserializing this sketch requires the use of a :class:`PyObjectSerDe`. + +.. autoclass:: var_opt_sketch + :members: + :undoc-members: + :exclude-members: deserialize + + .. rubric:: Static Methods: + + .. automethod:: deserialize + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: var_opt_union + :members: + :undoc-members: + :exclude-members: deserialize + + .. rubric:: Static Methods: + + .. automethod:: deserialize + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ diff --git a/docs/5.2.0/_sources/vector/density_sketch.rst.txt b/docs/5.2.0/_sources/vector/density_sketch.rst.txt new file mode 100644 index 00000000..07d83181 --- /dev/null +++ b/docs/5.2.0/_sources/vector/density_sketch.rst.txt @@ -0,0 +1,28 @@ +Density Sketch +-------------- + +.. currentmodule:: datasketches + +Builds a coreset from the given set of input points. +Provides density estimate at a given point. + +Based on the following paper: Zohar Karnin, Edo Liberty +"Discrepancy, Coresets, and Sketches in Machine Learning" +https://proceedings.mlr.press/v99/karnin19a/karnin19a.pdf + +Inspired by the following implementation: https://github.com/edoliberty/streaming-quantiles/blob/f688c8161a25582457b0a09deb4630a81406293b/gde.py + +Requires the use of a :class:`KernelFunction` to compute the distance between two vectors. + +.. autoclass:: density_sketch + :members: + :undoc-members: + :exclude-members: deserialize + + .. rubric:: Static Methods: + + .. automethod:: deserialize + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ diff --git a/docs/5.2.0/_sources/vector/index.rst.txt b/docs/5.2.0/_sources/vector/index.rst.txt new file mode 100644 index 00000000..1b83a43c --- /dev/null +++ b/docs/5.2.0/_sources/vector/index.rst.txt @@ -0,0 +1,12 @@ +Vector Sketches +================== + +.. currentmodule:: dataksetches + +These sketches are designed to accept vector inputs. For now, the library provides only the +:class:`density_sketch` for Kernel Density Estimation. + +.. toctree:: + :maxdepth: 1 + + density_sketch \ No newline at end of file diff --git a/docs/5.2.0/_static/_sphinx_javascript_frameworks_compat.js b/docs/5.2.0/_static/_sphinx_javascript_frameworks_compat.js new file mode 100644 index 00000000..81415803 --- /dev/null +++ b/docs/5.2.0/_static/_sphinx_javascript_frameworks_compat.js @@ -0,0 +1,123 @@ +/* Compatability shim for jQuery and underscores.js. + * + * Copyright Sphinx contributors + * Released under the two clause BSD licence + */ + +/** + * small helper function to urldecode strings + * + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL + */ +jQuery.urldecode = function(x) { + if (!x) { + return x + } + return decodeURIComponent(x.replace(/\+/g, ' ')); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s === 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node, addItems) { + if (node.nodeType === 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && + !jQuery(node.parentNode).hasClass(className) && + !jQuery(node.parentNode).hasClass("nohighlight")) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.className = className; + } + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + if (isInSVG) { + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + var bbox = node.parentElement.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": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} diff --git a/docs/5.2.0/_static/basic.css b/docs/5.2.0/_static/basic.css new file mode 100644 index 00000000..4738b2ed --- /dev/null +++ b/docs/5.2.0/_static/basic.css @@ -0,0 +1,906 @@ +/* + * 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; +} + +/* -- 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/docs/5.2.0/_static/css/badge_only.css b/docs/5.2.0/_static/css/badge_only.css new file mode 100644 index 00000000..88ba55b9 --- /dev/null +++ b/docs/5.2.0/_static/css/badge_only.css @@ -0,0 +1 @@ +.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions .rst-other-versions .rtd-current-item{font-weight:700}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}#flyout-search-form{padding:6px} \ No newline at end of file diff --git a/docs/5.2.0/_static/css/fonts/Roboto-Slab-Bold.woff b/docs/5.2.0/_static/css/fonts/Roboto-Slab-Bold.woff new file mode 100644 index 00000000..6cb60000 Binary files /dev/null and b/docs/5.2.0/_static/css/fonts/Roboto-Slab-Bold.woff differ diff --git a/docs/5.2.0/_static/css/fonts/Roboto-Slab-Bold.woff2 b/docs/5.2.0/_static/css/fonts/Roboto-Slab-Bold.woff2 new file mode 100644 index 00000000..7059e231 Binary files /dev/null and b/docs/5.2.0/_static/css/fonts/Roboto-Slab-Bold.woff2 differ diff --git a/docs/5.2.0/_static/css/fonts/Roboto-Slab-Regular.woff b/docs/5.2.0/_static/css/fonts/Roboto-Slab-Regular.woff new file mode 100644 index 00000000..f815f63f Binary files /dev/null and b/docs/5.2.0/_static/css/fonts/Roboto-Slab-Regular.woff differ diff --git a/docs/5.2.0/_static/css/fonts/Roboto-Slab-Regular.woff2 b/docs/5.2.0/_static/css/fonts/Roboto-Slab-Regular.woff2 new file mode 100644 index 00000000..f2c76e5b Binary files /dev/null and b/docs/5.2.0/_static/css/fonts/Roboto-Slab-Regular.woff2 differ diff --git a/docs/5.2.0/_static/css/fonts/fontawesome-webfont.eot b/docs/5.2.0/_static/css/fonts/fontawesome-webfont.eot new file mode 100644 index 00000000..e9f60ca9 Binary files /dev/null and b/docs/5.2.0/_static/css/fonts/fontawesome-webfont.eot differ diff --git a/docs/5.2.0/_static/css/fonts/fontawesome-webfont.svg b/docs/5.2.0/_static/css/fonts/fontawesome-webfont.svg new file mode 100644 index 00000000..855c845e --- /dev/null +++ b/docs/5.2.0/_static/css/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/5.2.0/_static/css/fonts/fontawesome-webfont.ttf b/docs/5.2.0/_static/css/fonts/fontawesome-webfont.ttf new file mode 100644 index 00000000..35acda2f Binary files /dev/null and b/docs/5.2.0/_static/css/fonts/fontawesome-webfont.ttf differ diff --git a/docs/5.2.0/_static/css/fonts/fontawesome-webfont.woff b/docs/5.2.0/_static/css/fonts/fontawesome-webfont.woff new file mode 100644 index 00000000..400014a4 Binary files /dev/null and b/docs/5.2.0/_static/css/fonts/fontawesome-webfont.woff differ diff --git a/docs/5.2.0/_static/css/fonts/fontawesome-webfont.woff2 b/docs/5.2.0/_static/css/fonts/fontawesome-webfont.woff2 new file mode 100644 index 00000000..4d13fc60 Binary files /dev/null and b/docs/5.2.0/_static/css/fonts/fontawesome-webfont.woff2 differ diff --git a/docs/5.2.0/_static/css/fonts/lato-bold-italic.woff b/docs/5.2.0/_static/css/fonts/lato-bold-italic.woff new file mode 100644 index 00000000..88ad05b9 Binary files /dev/null and b/docs/5.2.0/_static/css/fonts/lato-bold-italic.woff differ diff --git a/docs/5.2.0/_static/css/fonts/lato-bold-italic.woff2 b/docs/5.2.0/_static/css/fonts/lato-bold-italic.woff2 new file mode 100644 index 00000000..c4e3d804 Binary files /dev/null and b/docs/5.2.0/_static/css/fonts/lato-bold-italic.woff2 differ diff --git a/docs/5.2.0/_static/css/fonts/lato-bold.woff b/docs/5.2.0/_static/css/fonts/lato-bold.woff new file mode 100644 index 00000000..c6dff51f Binary files /dev/null and b/docs/5.2.0/_static/css/fonts/lato-bold.woff differ diff --git a/docs/5.2.0/_static/css/fonts/lato-bold.woff2 b/docs/5.2.0/_static/css/fonts/lato-bold.woff2 new file mode 100644 index 00000000..bb195043 Binary files /dev/null and b/docs/5.2.0/_static/css/fonts/lato-bold.woff2 differ diff --git a/docs/5.2.0/_static/css/fonts/lato-normal-italic.woff b/docs/5.2.0/_static/css/fonts/lato-normal-italic.woff new file mode 100644 index 00000000..76114bc0 Binary files /dev/null and b/docs/5.2.0/_static/css/fonts/lato-normal-italic.woff differ diff --git a/docs/5.2.0/_static/css/fonts/lato-normal-italic.woff2 b/docs/5.2.0/_static/css/fonts/lato-normal-italic.woff2 new file mode 100644 index 00000000..3404f37e Binary files /dev/null and b/docs/5.2.0/_static/css/fonts/lato-normal-italic.woff2 differ diff --git a/docs/5.2.0/_static/css/fonts/lato-normal.woff b/docs/5.2.0/_static/css/fonts/lato-normal.woff new file mode 100644 index 00000000..ae1307ff Binary files /dev/null and b/docs/5.2.0/_static/css/fonts/lato-normal.woff differ diff --git a/docs/5.2.0/_static/css/fonts/lato-normal.woff2 b/docs/5.2.0/_static/css/fonts/lato-normal.woff2 new file mode 100644 index 00000000..3bf98433 Binary files /dev/null and b/docs/5.2.0/_static/css/fonts/lato-normal.woff2 differ diff --git a/docs/5.2.0/_static/css/theme.css b/docs/5.2.0/_static/css/theme.css new file mode 100644 index 00000000..0f14f106 --- /dev/null +++ b/docs/5.2.0/_static/css/theme.css @@ -0,0 +1,4 @@ +html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden],audio:not([controls]){display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;text-decoration:none}ins,mark{color:#000}mark{background:#ff0;font-style:italic;font-weight:700}.rst-content code,.rst-content tt,code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:after,q:before{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,ol,ul{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure,form{margin:0}label{cursor:pointer}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{body,html,section{background:none!important}*{box-shadow:none!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}.rst-content .toctree-wrapper>p.caption,h2,h3,p{orphans:3;widows:3}.rst-content .toctree-wrapper>p.caption,h2,h3{page-break-after:avoid}}.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .eqno .headerlink:before,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .eqno .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a button.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-left.toctree-expand,.wy-menu-vertical li button.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .eqno .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a button.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-right.toctree-expand,.wy-menu-vertical li button.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .eqno .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a button.pull-left.toctree-expand,.wy-menu-vertical li.on a button.pull-left.toctree-expand,.wy-menu-vertical li button.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .eqno .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a button.pull-right.toctree-expand,.wy-menu-vertical li.on a button.pull-right.toctree-expand,.wy-menu-vertical li button.pull-right.toctree-expand{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li button.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content .eqno a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content p a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li a button.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content .eqno .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content p .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li button.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content .eqno .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a button.toctree-expand,.btn .wy-menu-vertical li.on a button.toctree-expand,.btn .wy-menu-vertical li button.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content .eqno .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a button.toctree-expand,.nav .wy-menu-vertical li.on a button.toctree-expand,.nav .wy-menu-vertical li button.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .eqno .btn .headerlink,.rst-content .eqno .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p .btn .headerlink,.rst-content p .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn button.toctree-expand,.wy-menu-vertical li.current>a .btn button.toctree-expand,.wy-menu-vertical li.current>a .nav button.toctree-expand,.wy-menu-vertical li .nav button.toctree-expand,.wy-menu-vertical li.on a .btn button.toctree-expand,.wy-menu-vertical li.on a .nav button.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .eqno .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li button.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .eqno .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li button.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .eqno .btn .fa-large.headerlink,.rst-content .eqno .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p .btn .fa-large.headerlink,.rst-content p .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn button.fa-large.toctree-expand,.wy-menu-vertical li .nav button.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .eqno .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li button.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .eqno .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li button.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .eqno .btn .fa-spin.headerlink,.rst-content .eqno .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p .btn .fa-spin.headerlink,.rst-content p .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn button.fa-spin.toctree-expand,.wy-menu-vertical li .nav button.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content .eqno .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li button.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content .eqno .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li button.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content .eqno .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li button.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content .eqno .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini button.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.rst-content section ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.rst-content section ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.rst-content section ul li p:last-child,.rst-content section ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.rst-content section ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.rst-content section ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.rst-content section ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content .section ol.arabic,.rst-content .toctree-wrapper ol,.rst-content .toctree-wrapper ol.arabic,.rst-content section ol,.rst-content section ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol.arabic li,.rst-content .section ol li,.rst-content .toctree-wrapper ol.arabic li,.rst-content .toctree-wrapper ol li,.rst-content section ol.arabic li,.rst-content section ol li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol.arabic li ul,.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content .toctree-wrapper ol.arabic li ul,.rst-content .toctree-wrapper ol li p:last-child,.rst-content .toctree-wrapper ol li ul,.rst-content section ol.arabic li ul,.rst-content section ol li p:last-child,.rst-content section ol li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol.arabic li ul li,.rst-content .section ol li ul li,.rst-content .toctree-wrapper ol.arabic li ul li,.rst-content .toctree-wrapper ol li ul li,.rst-content section ol.arabic li ul li,.rst-content section ol li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs>li{display:inline-block;padding-top:5px}.wy-breadcrumbs>li.wy-breadcrumbs-aside{float:right}.rst-content .wy-breadcrumbs>li code,.rst-content .wy-breadcrumbs>li tt,.wy-breadcrumbs>li .rst-content tt,.wy-breadcrumbs>li code{all:inherit;color:inherit}.breadcrumb-item:before{content:"/";color:#bbb;font-size:13px;padding:0 6px 0 3px}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li button.toctree-expand{display:block;float:left;margin-left:-1.2em;line-height:18px;color:#4d4d4d;border:none;background:none;padding:0}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover button.toctree-expand,.wy-menu-vertical li.on a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand{display:block;line-height:18px;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{padding:.4045em 1.618em .4045em 4.045em}.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{padding:.4045em 1.618em .4045em 5.663em}.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a{padding:.4045em 1.618em .4045em 7.281em}.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a{padding:.4045em 1.618em .4045em 8.899em}.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a{padding:.4045em 1.618em .4045em 10.517em}.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a{padding:.4045em 1.618em .4045em 12.135em}.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a{padding:.4045em 1.618em .4045em 13.753em}.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a{padding:.4045em 1.618em .4045em 15.371em}.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 1.618em .4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 button.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 button.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover button.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active button.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em;max-width:100%}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search .wy-dropdown>aactive,.wy-side-nav-search .wy-dropdown>afocus,.wy-side-nav-search>a:hover,.wy-side-nav-search>aactive,.wy-side-nav-search>afocus{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon,.wy-side-nav-search>a.icon{display:block}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.switch-menus{position:relative;display:block;margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-side-nav-search>div.switch-menus>div.language-switch,.wy-side-nav-search>div.switch-menus>div.version-switch{display:inline-block;padding:.2em}.wy-side-nav-search>div.switch-menus>div.language-switch select,.wy-side-nav-search>div.switch-menus>div.version-switch select{display:inline-block;margin-right:-2rem;padding-right:2rem;max-width:240px;text-align-last:center;background:none;border:none;border-radius:0;box-shadow:none;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-size:1em;font-weight:400;color:hsla(0,0%,100%,.3);cursor:pointer;appearance:none;-webkit-appearance:none;-moz-appearance:none}.wy-side-nav-search>div.switch-menus>div.language-switch select:active,.wy-side-nav-search>div.switch-menus>div.language-switch select:focus,.wy-side-nav-search>div.switch-menus>div.language-switch select:hover,.wy-side-nav-search>div.switch-menus>div.version-switch select:active,.wy-side-nav-search>div.switch-menus>div.version-switch select:focus,.wy-side-nav-search>div.switch-menus>div.version-switch select:hover{background:hsla(0,0%,100%,.1);color:hsla(0,0%,100%,.5)}.wy-side-nav-search>div.switch-menus>div.language-switch select option,.wy-side-nav-search>div.switch-menus>div.version-switch select option{color:#000}.wy-side-nav-search>div.switch-menus>div.language-switch:has(>select):after,.wy-side-nav-search>div.switch-menus>div.version-switch:has(>select):after{display:inline-block;width:1.5em;height:100%;padding:.1em;content:"\f0d7";font-size:1em;line-height:1.2em;font-family:FontAwesome;text-align:center;pointer-events:none;box-sizing:border-box}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .eqno .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content .eqno .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions .rst-other-versions .rtd-current-item{font-weight:700}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}#flyout-search-form{padding:6px}.rst-content .toctree-wrapper>p.caption,.rst-content h1,.rst-content h2,.rst-content h3,.rst-content h4,.rst-content h5,.rst-content h6{margin-bottom:24px}.rst-content img{max-width:100%;height:auto}.rst-content div.figure,.rst-content figure{margin-bottom:24px}.rst-content div.figure .caption-text,.rst-content figure .caption-text{font-style:italic}.rst-content div.figure p:last-child.caption,.rst-content figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center,.rst-content figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img,.rst-content section>a>img,.rst-content section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp,.rst-content div.highlight span.linenos{user-select:none;pointer-events:none}.rst-content div.highlight span.linenos{display:inline-block;padding-left:0;padding-right:12px;margin-right:12px;border-right:1px solid #e6e9ea}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li,.rst-content .toctree-wrapper ol.loweralpha,.rst-content .toctree-wrapper ol.loweralpha>li,.rst-content section ol.loweralpha,.rst-content section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li,.rst-content .toctree-wrapper ol.upperalpha,.rst-content .toctree-wrapper ol.upperalpha>li,.rst-content section ol.upperalpha,.rst-content section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*,.rst-content .toctree-wrapper ol li>*,.rst-content .toctree-wrapper ul li>*,.rst-content section ol li>*,.rst-content section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child,.rst-content .toctree-wrapper ol li>:first-child,.rst-content .toctree-wrapper ul li>:first-child,.rst-content section ol li>:first-child,.rst-content section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child,.rst-content .toctree-wrapper ol li>p,.rst-content .toctree-wrapper ol li>p:last-child,.rst-content .toctree-wrapper ul li>p,.rst-content .toctree-wrapper ul li>p:last-child,.rst-content section ol li>p,.rst-content section ol li>p:last-child,.rst-content section ul li>p,.rst-content section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child,.rst-content .toctree-wrapper ol li>p:only-child,.rst-content .toctree-wrapper ol li>p:only-child:last-child,.rst-content .toctree-wrapper ul li>p:only-child,.rst-content .toctree-wrapper ul li>p:only-child:last-child,.rst-content section ol li>p:only-child,.rst-content section ol li>p:only-child:last-child,.rst-content section ul li>p:only-child,.rst-content section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul,.rst-content .toctree-wrapper ol li>ol,.rst-content .toctree-wrapper ol li>ul,.rst-content .toctree-wrapper ul li>ol,.rst-content .toctree-wrapper ul li>ul,.rst-content section ol li>ol,.rst-content section ol li>ul,.rst-content section ul li>ol,.rst-content section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul,.rst-content .toctree-wrapper ol.simple li>*,.rst-content .toctree-wrapper ol.simple li ol,.rst-content .toctree-wrapper ol.simple li ul,.rst-content .toctree-wrapper ul.simple li>*,.rst-content .toctree-wrapper ul.simple li ol,.rst-content .toctree-wrapper ul.simple li ul,.rst-content section ol.simple li>*,.rst-content section ol.simple li ol,.rst-content section ol.simple li ul,.rst-content section ul.simple li>*,.rst-content section ul.simple li ol,.rst-content section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink{opacity:0;font-size:14px;font-family:FontAwesome;margin-left:.5em}.rst-content .code-block-caption .headerlink:focus,.rst-content .code-block-caption:hover .headerlink,.rst-content .eqno .headerlink:focus,.rst-content .eqno:hover .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink:focus,.rst-content .toctree-wrapper>p.caption:hover .headerlink,.rst-content dl dt .headerlink:focus,.rst-content dl dt:hover .headerlink,.rst-content h1 .headerlink:focus,.rst-content h1:hover .headerlink,.rst-content h2 .headerlink:focus,.rst-content h2:hover .headerlink,.rst-content h3 .headerlink:focus,.rst-content h3:hover .headerlink,.rst-content h4 .headerlink:focus,.rst-content h4:hover .headerlink,.rst-content h5 .headerlink:focus,.rst-content h5:hover .headerlink,.rst-content h6 .headerlink:focus,.rst-content h6:hover .headerlink,.rst-content p.caption .headerlink:focus,.rst-content p.caption:hover .headerlink,.rst-content p .headerlink:focus,.rst-content p:hover .headerlink,.rst-content table>caption .headerlink:focus,.rst-content table>caption:hover .headerlink{opacity:1}.rst-content p a{overflow-wrap:anywhere}.rst-content .wy-table td p,.rst-content .wy-table td ul,.rst-content .wy-table th p,.rst-content .wy-table th ul,.rst-content table.docutils td p,.rst-content table.docutils td ul,.rst-content table.docutils th p,.rst-content table.docutils th ul,.rst-content table.field-list td p,.rst-content table.field-list td ul,.rst-content table.field-list th p,.rst-content table.field-list th ul{font-size:inherit}.rst-content .btn:focus{outline:2px solid}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .citation-reference>span.fn-bracket,.rst-content .footnote-reference>span.fn-bracket{display:none}.rst-content .hlist{width:100%}.rst-content dl dt span.classifier:before{content:" : "}.rst-content dl dt span.classifier-delimiter{display:none!important}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:auto minmax(80%,95%)}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{display:inline-grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{display:grid;grid-template-columns:auto auto minmax(.65rem,auto) minmax(40%,95%)}html.writer-html5 .rst-content aside.citation>span.label,html.writer-html5 .rst-content aside.footnote>span.label,html.writer-html5 .rst-content div.citation>span.label{grid-column-start:1;grid-column-end:2}html.writer-html5 .rst-content aside.citation>span.backrefs,html.writer-html5 .rst-content aside.footnote>span.backrefs,html.writer-html5 .rst-content div.citation>span.backrefs{grid-column-start:2;grid-column-end:3;grid-row-start:1;grid-row-end:3}html.writer-html5 .rst-content aside.citation>p,html.writer-html5 .rst-content aside.footnote>p,html.writer-html5 .rst-content div.citation>p{grid-column-start:4;grid-column-end:5}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{margin-bottom:24px}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.citation>dt>span.brackets:before,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.citation>dt>span.brackets:after,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a{word-break:keep-all}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a:not(:first-child):before,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.citation>dd p,html.writer-html5 .rst-content dl.footnote>dd p{font-size:.9rem}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{padding-left:1rem;padding-right:1rem;font-size:.9rem;line-height:1.2rem}html.writer-html5 .rst-content aside.citation p,html.writer-html5 .rst-content aside.footnote p,html.writer-html5 .rst-content div.citation p{font-size:.9rem;line-height:1.2rem;margin-bottom:12px}html.writer-html5 .rst-content aside.citation span.backrefs,html.writer-html5 .rst-content aside.footnote span.backrefs,html.writer-html5 .rst-content div.citation span.backrefs{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content aside.citation span.backrefs>a,html.writer-html5 .rst-content aside.footnote span.backrefs>a,html.writer-html5 .rst-content div.citation span.backrefs>a{word-break:keep-all}html.writer-html5 .rst-content aside.citation span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content aside.footnote span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content div.citation span.backrefs>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content aside.citation span.label,html.writer-html5 .rst-content aside.footnote span.label,html.writer-html5 .rst-content div.citation span.label{line-height:1.2rem}html.writer-html5 .rst-content aside.citation-list,html.writer-html5 .rst-content aside.footnote-list,html.writer-html5 .rst-content div.citation-list{margin-bottom:24px}html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content aside.footnote-list aside.footnote,html.writer-html5 .rst-content div.citation-list>div.citation,html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content aside.footnote-list aside.footnote code,html.writer-html5 .rst-content aside.footnote-list aside.footnote tt,html.writer-html5 .rst-content aside.footnote code,html.writer-html5 .rst-content aside.footnote tt,html.writer-html5 .rst-content div.citation-list>div.citation code,html.writer-html5 .rst-content div.citation-list>div.citation tt,html.writer-html5 .rst-content dl.citation code,html.writer-html5 .rst-content dl.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c;white-space:normal}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040;overflow-wrap:normal}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}.rst-content dl dd>ol:last-child,.rst-content dl dd>p:last-child,.rst-content dl dd>table:last-child,.rst-content dl dd>ul:last-child{margin-bottom:0}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px;max-width:100%}html.writer-html4 .rst-content dl:not(.docutils) .k,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .k{font-style:italic}html.writer-html4 .rst-content dl:not(.docutils) .descclassname,html.writer-html4 .rst-content dl:not(.docutils) .descname,html.writer-html4 .rst-content dl:not(.docutils) .sig-name,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .sig-name{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#000}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel,.rst-content .menuselection{font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .guilabel,.rst-content .menuselection{border:1px solid #7fbbe3;background:#e7f2fa}.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>.kbd,.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>kbd{color:inherit;font-size:80%;background-color:#fff;border:1px solid #a6a6a6;border-radius:4px;box-shadow:0 2px grey;padding:2.4px 6px;margin:auto 0}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block} \ No newline at end of file diff --git a/docs/5.2.0/_static/doctools.js b/docs/5.2.0/_static/doctools.js new file mode 100644 index 00000000..0398ebb9 --- /dev/null +++ b/docs/5.2.0/_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/docs/5.2.0/_static/documentation_options.js b/docs/5.2.0/_static/documentation_options.js new file mode 100644 index 00000000..e21c068c --- /dev/null +++ b/docs/5.2.0/_static/documentation_options.js @@ -0,0 +1,13 @@ +const DOCUMENTATION_OPTIONS = { + VERSION: '0.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/docs/5.2.0/_static/file.png b/docs/5.2.0/_static/file.png new file mode 100644 index 00000000..a858a410 Binary files /dev/null and b/docs/5.2.0/_static/file.png differ diff --git a/docs/5.2.0/_static/fonts/Lato/lato-bold.eot b/docs/5.2.0/_static/fonts/Lato/lato-bold.eot new file mode 100644 index 00000000..3361183a Binary files /dev/null and b/docs/5.2.0/_static/fonts/Lato/lato-bold.eot differ diff --git a/docs/5.2.0/_static/fonts/Lato/lato-bold.ttf b/docs/5.2.0/_static/fonts/Lato/lato-bold.ttf new file mode 100644 index 00000000..29f691d5 Binary files /dev/null and b/docs/5.2.0/_static/fonts/Lato/lato-bold.ttf differ diff --git a/docs/5.2.0/_static/fonts/Lato/lato-bold.woff b/docs/5.2.0/_static/fonts/Lato/lato-bold.woff new file mode 100644 index 00000000..c6dff51f Binary files /dev/null and b/docs/5.2.0/_static/fonts/Lato/lato-bold.woff differ diff --git a/docs/5.2.0/_static/fonts/Lato/lato-bold.woff2 b/docs/5.2.0/_static/fonts/Lato/lato-bold.woff2 new file mode 100644 index 00000000..bb195043 Binary files /dev/null and b/docs/5.2.0/_static/fonts/Lato/lato-bold.woff2 differ diff --git a/docs/5.2.0/_static/fonts/Lato/lato-bolditalic.eot b/docs/5.2.0/_static/fonts/Lato/lato-bolditalic.eot new file mode 100644 index 00000000..3d415493 Binary files /dev/null and b/docs/5.2.0/_static/fonts/Lato/lato-bolditalic.eot differ diff --git a/docs/5.2.0/_static/fonts/Lato/lato-bolditalic.ttf b/docs/5.2.0/_static/fonts/Lato/lato-bolditalic.ttf new file mode 100644 index 00000000..f402040b Binary files /dev/null and b/docs/5.2.0/_static/fonts/Lato/lato-bolditalic.ttf differ diff --git a/docs/5.2.0/_static/fonts/Lato/lato-bolditalic.woff b/docs/5.2.0/_static/fonts/Lato/lato-bolditalic.woff new file mode 100644 index 00000000..88ad05b9 Binary files /dev/null and b/docs/5.2.0/_static/fonts/Lato/lato-bolditalic.woff differ diff --git a/docs/5.2.0/_static/fonts/Lato/lato-bolditalic.woff2 b/docs/5.2.0/_static/fonts/Lato/lato-bolditalic.woff2 new file mode 100644 index 00000000..c4e3d804 Binary files /dev/null and b/docs/5.2.0/_static/fonts/Lato/lato-bolditalic.woff2 differ diff --git a/docs/5.2.0/_static/fonts/Lato/lato-italic.eot b/docs/5.2.0/_static/fonts/Lato/lato-italic.eot new file mode 100644 index 00000000..3f826421 Binary files /dev/null and b/docs/5.2.0/_static/fonts/Lato/lato-italic.eot differ diff --git a/docs/5.2.0/_static/fonts/Lato/lato-italic.ttf b/docs/5.2.0/_static/fonts/Lato/lato-italic.ttf new file mode 100644 index 00000000..b4bfc9b2 Binary files /dev/null and b/docs/5.2.0/_static/fonts/Lato/lato-italic.ttf differ diff --git a/docs/5.2.0/_static/fonts/Lato/lato-italic.woff b/docs/5.2.0/_static/fonts/Lato/lato-italic.woff new file mode 100644 index 00000000..76114bc0 Binary files /dev/null and b/docs/5.2.0/_static/fonts/Lato/lato-italic.woff differ diff --git a/docs/5.2.0/_static/fonts/Lato/lato-italic.woff2 b/docs/5.2.0/_static/fonts/Lato/lato-italic.woff2 new file mode 100644 index 00000000..3404f37e Binary files /dev/null and b/docs/5.2.0/_static/fonts/Lato/lato-italic.woff2 differ diff --git a/docs/5.2.0/_static/fonts/Lato/lato-regular.eot b/docs/5.2.0/_static/fonts/Lato/lato-regular.eot new file mode 100644 index 00000000..11e3f2a5 Binary files /dev/null and b/docs/5.2.0/_static/fonts/Lato/lato-regular.eot differ diff --git a/docs/5.2.0/_static/fonts/Lato/lato-regular.ttf b/docs/5.2.0/_static/fonts/Lato/lato-regular.ttf new file mode 100644 index 00000000..74decd9e Binary files /dev/null and b/docs/5.2.0/_static/fonts/Lato/lato-regular.ttf differ diff --git a/docs/5.2.0/_static/fonts/Lato/lato-regular.woff b/docs/5.2.0/_static/fonts/Lato/lato-regular.woff new file mode 100644 index 00000000..ae1307ff Binary files /dev/null and b/docs/5.2.0/_static/fonts/Lato/lato-regular.woff differ diff --git a/docs/5.2.0/_static/fonts/Lato/lato-regular.woff2 b/docs/5.2.0/_static/fonts/Lato/lato-regular.woff2 new file mode 100644 index 00000000..3bf98433 Binary files /dev/null and b/docs/5.2.0/_static/fonts/Lato/lato-regular.woff2 differ diff --git a/docs/5.2.0/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot b/docs/5.2.0/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot new file mode 100644 index 00000000..79dc8efe Binary files /dev/null and b/docs/5.2.0/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot differ diff --git a/docs/5.2.0/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf b/docs/5.2.0/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf new file mode 100644 index 00000000..df5d1df2 Binary files /dev/null and b/docs/5.2.0/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf differ diff --git a/docs/5.2.0/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff b/docs/5.2.0/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff new file mode 100644 index 00000000..6cb60000 Binary files /dev/null and b/docs/5.2.0/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff differ diff --git a/docs/5.2.0/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2 b/docs/5.2.0/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2 new file mode 100644 index 00000000..7059e231 Binary files /dev/null and b/docs/5.2.0/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2 differ diff --git a/docs/5.2.0/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot b/docs/5.2.0/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot new file mode 100644 index 00000000..2f7ca78a Binary files /dev/null and b/docs/5.2.0/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot differ diff --git a/docs/5.2.0/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf b/docs/5.2.0/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf new file mode 100644 index 00000000..eb52a790 Binary files /dev/null and b/docs/5.2.0/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf differ diff --git a/docs/5.2.0/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff b/docs/5.2.0/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff new file mode 100644 index 00000000..f815f63f Binary files /dev/null and b/docs/5.2.0/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff differ diff --git a/docs/5.2.0/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2 b/docs/5.2.0/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2 new file mode 100644 index 00000000..f2c76e5b Binary files /dev/null and b/docs/5.2.0/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2 differ diff --git a/docs/5.2.0/_static/jquery.js b/docs/5.2.0/_static/jquery.js new file mode 100644 index 00000000..c4c6022f --- /dev/null +++ b/docs/5.2.0/_static/jquery.js @@ -0,0 +1,2 @@ +/*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0
"),n("table.docutils.footnote").wrap("
"),n("table.docutils.citation").wrap("
"),n(".wy-menu-vertical ul").not(".simple").siblings("a").each((function(){var t=n(this);expand=n(''),expand.on("click",(function(n){return e.toggleCurrent(t),n.stopPropagation(),!1})),t.prepend(expand)}))},reset:function(){var n=encodeURI(window.location.hash)||"#";try{var e=$(".wy-menu-vertical"),t=e.find('[href="'+n+'"]');if(0===t.length){var i=$('.document [id="'+n.substring(1)+'"]').closest("div.section");0===(t=e.find('[href="#'+i.attr("id")+'"]')).length&&(t=e.find('[href="#"]'))}if(t.length>0){$(".wy-menu-vertical .current").removeClass("current").attr("aria-expanded","false"),t.addClass("current").attr("aria-expanded","true"),t.closest("li.toctree-l1").parent().addClass("current").attr("aria-expanded","true");for(let n=1;n<=10;n++)t.closest("li.toctree-l"+n).addClass("current").attr("aria-expanded","true");t[0].scrollIntoView()}}catch(n){console.log("Error expanding nav for anchor",n)}},onScroll:function(){this.winScroll=!1;var n=this.win.scrollTop(),e=n+this.winHeight,t=this.navBar.scrollTop()+(n-this.winPosition);n<0||e>this.docHeight||(this.navBar.scrollTop(t),this.winPosition=n)},onResize:function(){this.winResize=!1,this.winHeight=this.win.height(),this.docHeight=$(document).height()},hashChange:function(){this.linkScroll=!0,this.win.one("hashchange",(function(){this.linkScroll=!1}))},toggleCurrent:function(n){var e=n.closest("li");e.siblings("li.current").removeClass("current").attr("aria-expanded","false"),e.siblings().find("li.current").removeClass("current").attr("aria-expanded","false");var t=e.find("> ul li");t.length&&(t.removeClass("current").attr("aria-expanded","false"),e.toggleClass("current").attr("aria-expanded",(function(n,e){return"true"==e?"false":"true"})))}},"undefined"!=typeof window&&(window.SphinxRtdTheme={Navigation:n.exports.ThemeNav,StickyNav:n.exports.ThemeNav}),function(){for(var n=0,e=["ms","moz","webkit","o"],t=0;t a.language.name.localeCompare(b.language.name)); + + const languagesHTML = ` +
+
Languages
+ ${languages + .map( + (translation) => ` +
+ ${translation.language.code} +
+ `, + ) + .join("\n")} +
+ `; + return languagesHTML; + } + + function renderVersions(config) { + if (!config.versions.active.length) { + return ""; + } + const versionsHTML = ` +
+
Versions
+ ${config.versions.active + .map( + (version) => ` +
+ ${version.slug} +
+ `, + ) + .join("\n")} +
+ `; + return versionsHTML; + } + + function renderDownloads(config) { + if (!Object.keys(config.versions.current.downloads).length) { + return ""; + } + const downloadsNameDisplay = { + pdf: "PDF", + epub: "Epub", + htmlzip: "HTML", + }; + + const downloadsHTML = ` +
+
Downloads
+ ${Object.entries(config.versions.current.downloads) + .map( + ([name, url]) => ` +
+ ${downloadsNameDisplay[name]} +
+ `, + ) + .join("\n")} +
+ `; + return downloadsHTML; + } + + document.addEventListener("readthedocs-addons-data-ready", function (event) { + const config = event.detail.data(); + + const flyout = ` +
+ + Read the Docs + v: ${config.versions.current.slug} + + +
+
+ ${renderLanguages(config)} + ${renderVersions(config)} + ${renderDownloads(config)} +
+
On Read the Docs
+
+ Project Home +
+
+ Builds +
+
+ Downloads +
+
+
+
Search
+
+
+ +
+
+
+
+ + Hosted by Read the Docs + +
+
+ `; + + // Inject the generated flyout into the body HTML element. + document.body.insertAdjacentHTML("beforeend", flyout); + + // Trigger the Read the Docs Addons Search modal when clicking on the "Search docs" input from inside the flyout. + document + .querySelector("#flyout-search-form") + .addEventListener("focusin", () => { + const event = new CustomEvent("readthedocs-search-show"); + document.dispatchEvent(event); + }); + }) +} + +if (themeLanguageSelector || themeVersionSelector) { + function onSelectorSwitch(event) { + const option = event.target.selectedIndex; + const item = event.target.options[option]; + window.location.href = item.dataset.url; + } + + document.addEventListener("readthedocs-addons-data-ready", function (event) { + const config = event.detail.data(); + + const versionSwitch = document.querySelector( + "div.switch-menus > div.version-switch", + ); + if (themeVersionSelector) { + let versions = config.versions.active; + if (config.versions.current.hidden || config.versions.current.type === "external") { + versions.unshift(config.versions.current); + } + const versionSelect = ` + + `; + + versionSwitch.innerHTML = versionSelect; + versionSwitch.firstElementChild.addEventListener("change", onSelectorSwitch); + } + + const languageSwitch = document.querySelector( + "div.switch-menus > div.language-switch", + ); + + if (themeLanguageSelector) { + if (config.projects.translations.length) { + // Add the current language to the options on the selector + let languages = config.projects.translations.concat( + config.projects.current, + ); + languages = languages.sort((a, b) => + a.language.name.localeCompare(b.language.name), + ); + + const languageSelect = ` + + `; + + languageSwitch.innerHTML = languageSelect; + languageSwitch.firstElementChild.addEventListener("change", onSelectorSwitch); + } + else { + languageSwitch.remove(); + } + } + }); +} + +document.addEventListener("readthedocs-addons-data-ready", function (event) { + // Trigger the Read the Docs Addons Search modal when clicking on "Search docs" input from the topnav. + document + .querySelector("[role='search'] input") + .addEventListener("focusin", () => { + const event = new CustomEvent("readthedocs-search-show"); + document.dispatchEvent(event); + }); +}); \ No newline at end of file diff --git a/docs/5.2.0/_static/language_data.js b/docs/5.2.0/_static/language_data.js new file mode 100644 index 00000000..c7fe6c6f --- /dev/null +++ b/docs/5.2.0/_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/docs/5.2.0/_static/minus.png b/docs/5.2.0/_static/minus.png new file mode 100644 index 00000000..d96755fd Binary files /dev/null and b/docs/5.2.0/_static/minus.png differ diff --git a/docs/5.2.0/_static/plus.png b/docs/5.2.0/_static/plus.png new file mode 100644 index 00000000..7107cec9 Binary files /dev/null and b/docs/5.2.0/_static/plus.png differ diff --git a/docs/5.2.0/_static/pygments.css b/docs/5.2.0/_static/pygments.css new file mode 100644 index 00000000..6f8b210a --- /dev/null +++ b/docs/5.2.0/_static/pygments.css @@ -0,0 +1,75 @@ +pre { line-height: 125%; } +td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +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: #3D7B7B; font-style: italic } /* Comment */ +.highlight .err { border: 1px solid #F00 } /* Error */ +.highlight .k { color: #008000; font-weight: bold } /* Keyword */ +.highlight .o { color: #666 } /* Operator */ +.highlight .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */ +.highlight .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #9C6500 } /* Comment.Preproc */ +.highlight .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */ +.highlight .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */ +.highlight .gr { color: #E40000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #008400 } /* Generic.Inserted */ +.highlight .go { color: #717171 } /* Generic.Output */ +.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #04D } /* Generic.Traceback */ +.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #008000 } /* Keyword.Pseudo */ +.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #B00040 } /* Keyword.Type */ +.highlight .m { color: #666 } /* Literal.Number */ +.highlight .s { color: #BA2121 } /* Literal.String */ +.highlight .na { color: #687822 } /* Name.Attribute */ +.highlight .nb { color: #008000 } /* Name.Builtin */ +.highlight .nc { color: #00F; font-weight: bold } /* Name.Class */ +.highlight .no { color: #800 } /* Name.Constant */ +.highlight .nd { color: #A2F } /* Name.Decorator */ +.highlight .ni { color: #717171; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #00F } /* Name.Function */ +.highlight .nl { color: #767600 } /* Name.Label */ +.highlight .nn { color: #00F; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #19177C } /* Name.Variable */ +.highlight .ow { color: #A2F; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #BBB } /* Text.Whitespace */ +.highlight .mb { color: #666 } /* Literal.Number.Bin */ +.highlight .mf { color: #666 } /* Literal.Number.Float */ +.highlight .mh { color: #666 } /* Literal.Number.Hex */ +.highlight .mi { color: #666 } /* Literal.Number.Integer */ +.highlight .mo { color: #666 } /* Literal.Number.Oct */ +.highlight .sa { color: #BA2121 } /* Literal.String.Affix */ +.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */ +.highlight .sc { color: #BA2121 } /* Literal.String.Char */ +.highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */ +.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #BA2121 } /* Literal.String.Double */ +.highlight .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */ +.highlight .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */ +.highlight .sx { color: #008000 } /* Literal.String.Other */ +.highlight .sr { color: #A45A77 } /* Literal.String.Regex */ +.highlight .s1 { color: #BA2121 } /* Literal.String.Single */ +.highlight .ss { color: #19177C } /* Literal.String.Symbol */ +.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */ +.highlight .fm { color: #00F } /* Name.Function.Magic */ +.highlight .vc { color: #19177C } /* Name.Variable.Class */ +.highlight .vg { color: #19177C } /* Name.Variable.Global */ +.highlight .vi { color: #19177C } /* Name.Variable.Instance */ +.highlight .vm { color: #19177C } /* Name.Variable.Magic */ +.highlight .il { color: #666 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/docs/5.2.0/_static/searchtools.js b/docs/5.2.0/_static/searchtools.js new file mode 100644 index 00000000..91f4be57 --- /dev/null +++ b/docs/5.2.0/_static/searchtools.js @@ -0,0 +1,635 @@ +/* + * 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 = []; + // find documents, if any, containing the query word in their text/title term indices + // use Object.hasOwnProperty to avoid mismatching against prototype properties + const arr = [ + { files: terms.hasOwnProperty(word) ? terms[word] : undefined, score: Scorer.term }, + { files: titleTerms.hasOwnProperty(word) ? titleTerms[word] : undefined, 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, new Map()); + const fileScores = scoreMap.get(file); + fileScores.set(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).get(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/docs/5.2.0/_static/sphinx_highlight.js b/docs/5.2.0/_static/sphinx_highlight.js new file mode 100644 index 00000000..8a96c69a --- /dev/null +++ b/docs/5.2.0/_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/docs/5.2.0/distinct_counting/cpc.html b/docs/5.2.0/distinct_counting/cpc.html new file mode 100644 index 00000000..2d87ef58 --- /dev/null +++ b/docs/5.2.0/distinct_counting/cpc.html @@ -0,0 +1,268 @@ + + + + + + + + + Compressed Probabilistic Counting (CPC) — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Compressed Probabilistic Counting (CPC)

+

High performance C++ implementation of Compressed Probabilistic Counting (CPC) Sketch. +This is a unique-counting sketch that implements the Compressed Probabilistic Counting (CPC, a.k.a FM85) algorithms developed by Kevin Lang in his paper +Back to the Future: an Even More Nearly Optimal Cardinality Estimation Algorithm. +This sketch is extremely space-efficient when serialized. +In an apples-to-apples empirical comparison against compressed HyperLogLog sketches, this new algorithm simultaneously wins on the two dimensions of the space/accuracy tradeoff and produces sketches that are smaller than the entropy of HLL, so no possible implementation of compressed HLL can match its space efficiency for a given accuracy. As described in the paper this sketch implements a newly developed ICON estimator algorithm that survives unioning operations, another well-known estimator, the Historical Inverse Probability (HIP) estimator does not. +The update speed performance of this sketch is quite fast and is comparable to the speed of HLL. +The unioning (merging) capability of this sketch also allows for merging of sketches with different configurations of K. +For additional security this sketch can be configured with a user-specified hash seed.

+
+
+class cpc_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.cpc_sketch
+

Reads a bytes object and returns the corresponding cpc_sketch

+
+ +

Non-static Methods:

+
+
+__init__(self, lg_k: int = 11, seed: int = 9001) None
+

Creates a new CPC sketch

+
+
Parameters:
+
    +
  • lg_k (int, optional) – base 2 logarithm of the number of bins in the sketch

  • +
  • seed (int, optional) – seed value for the hash function

  • +
+
+
+
+ +
+
+get_estimate
+

Estimate of the distinct count of the input stream

+
+ +
+
+get_lower_bound
+

Returns an approximate lower bound on the estimate for kappa values in {1, 2, 3}, roughly corresponding to standard deviations

+
+ +
+
+get_upper_bound
+

Returns an approximate upper bound on the estimate for kappa values in {1, 2, 3}, roughly corresponding to standard deviations

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+property lg_k
+

Configured lg_k of this sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, datum: int) -> None

  2. +
+

Updates the sketch with the given 64-bit integer value

+
    +
  1. update(self, datum: float) -> None

  2. +
+

Updates the sketch with the given 64-bit floating point

+
    +
  1. update(self, datum: str) -> None

  2. +
+

Updates the sketch with the given string

+
+ +
+ +
+
+class cpc_union(*args, **kwargs)
+
+
+__init__(self, lg_k: int, seed: int = 9001) None
+
+ +
+
+get_result
+

Returns a CPC sketch with the result of the union

+
+ +
+
+update
+

Updates the union with the provided CPC sketch

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.2.0/distinct_counting/hyper_log_log.html b/docs/5.2.0/distinct_counting/hyper_log_log.html new file mode 100644 index 00000000..a60930eb --- /dev/null +++ b/docs/5.2.0/distinct_counting/hyper_log_log.html @@ -0,0 +1,424 @@ + + + + + + + + + HyperLogLog (HLL) — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

HyperLogLog (HLL)

+

This is a high performance implementation of Phillipe Flajolet’s HLL sketch but with significantly improved error behavior.

+

If the ONLY use case for sketching is counting uniques and merging, the HLL sketch is a reasonable choice, although the highest performing in terms of accuracy for storage space consumed is CPC (Compressed Probabilistic Counting). For large enough counts, this HLL version (with HLL_4) can be 2 to 16 times smaller than the Theta sketch family for the same accuracy.

+

This implementation offers three different types of HLL sketch, each with different trade-offs with accuracy, space and performance. +These types are specified with the target_hll_type parameter.

+

In terms of accuracy, all three types, for the same lg_config_k, have the same error distribution as a function of n, the number of unique values fed to the sketch. +The configuration parameter lg_config_k is the log-base-2 of k, where k is the number of buckets or slots for the sketch.

+

During warmup, when the sketch has only received a small number of unique items (up to about 10% of k), this implementation leverages a new class of estimator algorithms with significantly better accuracy.

+
+
+class tgt_hll_type(*values)
+

Target HLL flavor

+
+
+HLL_4 : 4 bits per entry
+
+ +
+
+HLL_6 : 6 bits per entry
+
+ +
+
+HLL_8 : 8 bits per entry
+
+ +
+ +
+
+class hll_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.hll_sketch
+

Reads a bytes object and returns the corresponding hll_sketch

+
+ +
+
+get_max_updatable_serialization_bytes(lg_k: int, tgt_type: _datasketches.tgt_hll_type) int
+

Provides a likely upper bound on serialization size for the given parameters

+
+ +
+
+get_rel_err(upper_bound: bool, unioned: bool, lg_k: int, num_std_devs: int) float
+

Returns the a priori relative error bound for the given parameters

+
+ +

Non-static Methods:

+
+
+__init__(self, lg_k: int, tgt_type: _datasketches.tgt_hll_type = tgt_hll_type.HLL_8, start_max_size: bool = False) None
+

Constructs a new HLL sketch

+
+
Parameters:
+
    +
  • lg_config_k (int) – A full sketch can hold 2^lg_config_k rows. Must be between 7 and 21, inclusive,

  • +
  • tgt_type (tgt_hll_type) – The HLL mode to use, if/when the sketch reaches estimation mode

  • +
  • start_full_size (bool) – Indicates whether to start in HLL mode, keeping memory use constant (if HLL_6 or HLL_8) at the cost of much higher initial memory use. Default (and recommended) is False.

  • +
+
+
+
+ +
+
+get_compact_serialization_bytes
+

Returns the size of the serialized sketch when compressing the exception table if HLL_4

+
+ +
+
+get_estimate
+

Estimate of the distinct count of the input stream

+
+ +
+
+get_lower_bound
+

Returns the approximate lower error bound given the specified number of standard deviations in {1, 2, 3}

+
+ +
+
+get_updatable_serialization_bytes
+

Returns the size of the serialized sketch

+
+ +
+
+get_upper_bound
+

Returns the approximate upper error bound given the specified number of standard deviations in {1, 2, 3}

+
+ +
+
+is_compact
+

True if the sketch is compact, otherwise False

+
+ +
+
+is_empty
+

True if the sketch is empty, otherwise False

+
+ +
+
+property lg_config_k
+

Configured lg_k value for the sketch

+
+ +
+
+reset
+

Resets the sketch to the empty state in coupon collection mode

+
+ +
+
+serialize_compact
+

Serializes the sketch into a bytes object, compressing the exception table if HLL_4

+
+ +
+
+serialize_updatable
+

Serializes the sketch into a bytes object

+
+ +
+
+property tgt_type
+

The HLL type (4, 6, or 8) when in estimation mode

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, datum: int) -> None

  2. +
+

Updates the sketch with the given integral value

+
    +
  1. update(self, datum: float) -> None

  2. +
+

Updates the sketch with the given floating point value

+
    +
  1. update(self, datum: str) -> None

  2. +
+

Updates the sketch with the given string value

+
+ +
+ +
+
+class hll_union(*args, **kwargs)
+

Static Methods:

+
+
+get_rel_err(upper_bound: bool, unioned: bool, lg_k: int, num_std_devs: int) float
+

Returns the a priori relative error bound for the given parameters

+
+ +

Non-static Methods:

+
+
+__init__(self, lg_max_k: int) None
+

Construct an hll_union object if the given size.

+
+
Parameters:
+

lg_max_k (int) – The maximum size, in log2, of k. Must be between 7 and 21, inclusive.

+
+
+
+ +
+
+get_estimate
+

Estimate of the distinct count of the input stream

+
+ +
+
+get_lower_bound
+

Returns the approximate lower error bound given the specified number of standard deviations in {1, 2, 3}

+
+ +
+
+get_result
+

Returns a sketch of the target type representing the current union state

+
+ +
+
+get_upper_bound
+

Returns the approximate upper error bound given the specified number of standard deviations in {1, 2, 3}

+
+ +
+
+is_empty
+

True if the union is empty, otherwise False

+
+ +
+
+property lg_config_k
+

Configured lg_k value for the union

+
+ +
+
+reset
+

Resets the union to the empty state

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, sketch: _datasketches.hll_sketch) -> None

  2. +
+

Updates the union with the given HLL sketch

+
    +
  1. update(self, datum: int) -> None

  2. +
+

Updates the union with the given integral value

+
    +
  1. update(self, datum: float) -> None

  2. +
+

Updates the union with the given floating point value

+
    +
  1. update(self, datum: str) -> None

  2. +
+

Updates the union with the given string value

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.2.0/distinct_counting/index.html b/docs/5.2.0/distinct_counting/index.html new file mode 100644 index 00000000..ce4493db --- /dev/null +++ b/docs/5.2.0/distinct_counting/index.html @@ -0,0 +1,150 @@ + + + + + + + + + Distinct Counting — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Distinct Counting

+

Distinct counting is one of the earliest tasks to which sketches were applied. The concept is simple: +Provide an estimate of the number of unique elements in a set of data. One of the earliest solutions came +from Flajolet and Martin in 1985 with their seminal work +Probabilistic counting Algorithms for Data Base Applications.

+

The DataSketches library offers several types of distinct counting sketches, each with different properties.

+
+
    +
  • hll_sketch: Hyper Log Log, a well-known sketch for distinct counting but no longer state-of-the-art.

  • +
  • cpc_sketch: Provides a better accuracy-space trade-off than HLL, but with a somewhat larger footprint while in-memory.

  • +
  • theta_sketch: Theta sketch, a type of k-minimum value sketch, which provide good performance with intersection and set difference operations.

  • +
  • tuple_sketch: Tuple sketch, which is similar to a theta sketch but supports additional data stored with each key.

  • +
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.2.0/distinct_counting/theta.html b/docs/5.2.0/distinct_counting/theta.html new file mode 100644 index 00000000..a66a2a9f --- /dev/null +++ b/docs/5.2.0/distinct_counting/theta.html @@ -0,0 +1,438 @@ + + + + + + + + + Theta Sketch — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Theta Sketch

+

Theta sketches are used for distinct counting.

+

The theta package contains the basic sketch classes that are members of the Theta Sketch Framework. +There is a separate Tuple package for many of the sketches that are derived from the same algorithms defined in the Theta Sketch Framework paper.

+

The Theta Sketch sketch is a space-efficient method for estimating cardinalities of sets. +It can also easily handle set operations (such as union, intersection, difference) while maintaining good accuracy. +Theta sketch is a practical variant of the K-Minimum Values sketch which avoids the need to sort the stored +hash values on every insertion to the sketch. +It has better error properties than the HyperLogLog sketch for set operations beyond the simple union.

+

Set operations (union, intersection, A-not-B) are performed through the use of dedicated objects.

+

Several Jaccard similarity +measures can be computed between theta sketches with the theta_jaccard_similarity class.

+
+
+class theta_sketch
+

An abstract base class for theta sketches

+
+
+get_estimate
+

Estimate of the distinct count of the input stream

+
+ +
+
+get_lower_bound
+

Returns an approximate lower bound on the estimate at standard deviations in {1, 2, 3}

+
+ +
+
+get_seed_hash
+

Returns a hash of the seed used in the sketch

+
+ +
+
+get_upper_bound
+

Returns an approximate upper bound on the estimate at standard deviations in {1, 2, 3}

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if sketch is in estimation mode, otherwise False

+
+ +
+
+is_ordered
+

Returns True if the sketch entries are sorted, otherwise False

+
+ +
+
+property num_retained
+

The number of items currently in the sketch

+
+ +
+
+property theta
+

Theta (effective sampling rate) as a fraction from 0 to 1

+
+ +
+
+property theta64
+

Theta as 64-bit value

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+ +
+
+class update_theta_sketch(*args, **kwargs)
+
+
+__init__(self, lg_k: int = 12, p: float = 1.0, seed: int = 9001) None
+

Creates an update_theta_sketch using the provided parameters

+
+
Parameters:
+
    +
  • lg_k (int, optional) – base 2 logarithm of the maximum size of the sketch. Default 12.

  • +
  • p (float, optional) – an initial sampling rate to use. Default 1.0

  • +
  • seed (int, optional) – the seed to use when hashing values

  • +
+
+
+
+ +
+
+compact
+

Returns a compacted form of the sketch, optionally sorting it

+
+ +
+
+reset
+

Resets the sketch to the initial empty state

+
+ +
+
+trim
+

Removes retained entries in excess of the nominal size k (if any)

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, datum: int) -> None

  2. +
+

Updates the sketch with the given integral value

+
    +
  1. update(self, datum: float) -> None

  2. +
+

Updates the sketch with the given floating point value

+
    +
  1. update(self, datum: str) -> None

  2. +
+

Updates the sketch with the given string

+
+ +
+ +
+
+class compact_theta_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, seed: int = 9001) _datasketches.compact_theta_sketch
+

Reads a bytes object and returns the corresponding compact_theta_sketch

+
+ +

Non-static Methods:

+
+
+__init__(self, arg0: _datasketches.theta_sketch, arg1: bool, /) None
+

Creates a compact_theta_sketch from an existing theta_sketch.

+
+
Parameters:
+
    +
  • other (theta_sketch) – a source theta_sketch

  • +
  • ordered (bool) – whether the incoming sketch entries are sorted. Default True

  • +
+
+
+
+ +
+
+serialize
+

Serializes the sketch into a bytes object, optionally compressing the data

+
+ +
+ +
+
+class theta_union(*args, **kwargs)
+
+
+__init__(self, lg_k: int = 12, p: float = 1.0, seed: int = 9001) None
+

Creates a theta_union using the provided parameters

+
+
Parameters:
+
    +
  • lg_k (int, optional) – base 2 logarithm of the maximum size of the union. Default 12.

  • +
  • p (float, optional) – an initial sampling rate to use. Default 1.0

  • +
  • seed (int, optional) – the seed to use when hashing values. Must match all sketch seeds.

  • +
+
+
+
+ +
+
+get_result
+

Returns the sketch corresponding to the union result

+
+ +
+
+update
+

Updates the union with the given sketch

+
+ +
+ +
+
+class theta_intersection(*args, **kwargs)
+
+
+__init__(self, seed: int = 9001) None
+

Creates a theta_intersection using the provided parameters

+
+
Parameters:
+

seed (int, optional) – the seed to use when hashing values. Must match all sketch seeds

+
+
+
+ +
+
+get_result
+

Returns the sketch corresponding to the intersection result

+
+ +
+
+has_result
+

Returns True if the intersection has a valid result, otherwise False

+
+ +
+
+update
+

Intersections the provided sketch with the current intersection state

+
+ +
+ +
+
+class theta_a_not_b(*args, **kwargs)
+
+
+__init__(self, seed: int = 9001) None
+

Creates a tuple_a_not_b object

+
+
Parameters:
+

seed (int, optional) – the seed to use when hashing values. Must match all sketch seeds.

+
+
+
+ +
+
+compute
+

Returns a sketch with the result of applying the A-not-B operation on the given inputs

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.2.0/distinct_counting/tuple.html b/docs/5.2.0/distinct_counting/tuple.html new file mode 100644 index 00000000..aa619a73 --- /dev/null +++ b/docs/5.2.0/distinct_counting/tuple.html @@ -0,0 +1,512 @@ + + + + + + + + + Tuple Sketch — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Tuple Sketch

+

Tuple sketches are an extension of Theta sketches, meaning they provide estimate of distinct counts, that +allow the keeping of arbitrary summaries associated with each retained key +(for example, a count for every key). The use of a tuple_sketch requires a TuplePolicy which +defines how summaries are created, updated, merged, or intersected. The library provides a few basic +examples of TuplePolicy implementations, but the right custom summary and policy can allow very +complicated analysis to be performed quite easily.

+

Set operations (union, intersection, A-not-B) are performed through the use of dedicated objects.

+

Several Jaccard similarity +measures can be computed between theta sketches with the tuple_jaccard_similarity class.

+
+

Note

+

Serializing and deserializing this sketch requires the use of a PyObjectSerDe.

+
+
+
+class tuple_sketch
+

An abstract base class for tuple sketches.

+
+
+DEFAULT_SEED = 9001
+
+ +
+
+get_estimate
+

Estimate of the distinct count of the input stream

+
+ +
+
+get_lower_bound
+

Returns an approximate lower bound on the estimate at standard deviations in {1, 2, 3}

+
+ +
+
+get_seed_hash
+

Returns a hash of the seed used in the sketch

+
+ +
+
+get_upper_bound
+

Returns an approximate upper bound on the estimate at standard deviations in {1, 2, 3}

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if sketch is in estimation mode, otherwise False

+
+ +
+
+is_ordered
+

Returns True if the sketch entries are sorted, otherwise False

+
+ +
+
+property num_retained
+

The number of items currently in the sketch

+
+ +
+
+property theta
+

Theta (effective sampling rate) as a fraction from 0 to 1

+
+ +
+
+property theta64
+

Theta as 64-bit value

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+ +
+
+class update_tuple_sketch(*args, **kwargs)
+
+
+__init__(self, policy: _datasketches.TuplePolicy, lg_k: int = 12, p: float = 1.0, seed: int = 9001) None
+

Creates an update_tuple_sketch using the provided parameters

+
+
Parameters:
+
    +
  • policy (TuplePolicy) – a policy to use when updating

  • +
  • lg_k (int, optional) – base 2 logarithm of the maximum size of the sketch. Default 12.

  • +
  • p (float, optional) – an initial sampling rate to use. Default 1.0

  • +
  • seed (int, optional) – the seed to use when hashing values

  • +
+
+
+
+ +
+
+compact
+

Returns a compacted form of the sketch, optionally sorting it

+
+ +
+
+filter
+

Produces a compact_tuple_sketch from the given sketch by applying a predicate to the summary in each entry.

+
+
Parameters:
+

predicate – A function returning true or value evaluated on each tuple summary

+
+
Returns:
+

A compact_tuple_sketch with the selected entries

+
+
Return type:
+

compact_tuple_sketch

+
+
+
+ +
+
+reset
+

Resets the sketch to the initial empty state

+
+ +
+
+trim
+

Removes retained entries in excess of the nominal size k (if any)

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, datum: int, value: object) -> None

  2. +
+

Updates the sketch with the given integral item and summary value

+
    +
  1. update(self, datum: float, value: object) -> None

  2. +
+

Updates the sketch with the given floating point item and summary value

+
    +
  1. update(self, datum: str, value: object) -> None

  2. +
+

Updates the sketch with the given string item and summary value

+
+ +
+ +
+
+class compact_tuple_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe, seed: int = 9001) _datasketches.compact_tuple_sketch
+

Reads a bytes object and returns the corresponding compact_tuple_sketch

+
+ +

Non-static Methods:

+
+
+__init__(self, other: _datasketches.tuple_sketch, ordered: bool = True) None
+
+__init__(self, other: _datasketches.theta_sketch, summary: object) None
+

Overloaded function.

+
    +
  1. __init__(self, other: _datasketches.tuple_sketch, ordered: bool = True) -> None

  2. +
+

Creates a compact_tuple_sketch from an existing tuple_sketch.

+
+
Parameters:
+
    +
  • other (tuple_sketch) – a sourch tuple_sketch

  • +
  • ordered (bool, optional) – whether the incoming sketch entries are sorted. Default True

  • +
+
+
+
    +
  1. __init__(self, other: _datasketches.theta_sketch, summary: object) -> None

  2. +
+

Creates a compact_tuple_sketch from a theta_sketch using a fixed summary value.

+
+
Parameters:
+
    +
  • other (theta_sketch) – a source theta sketch

  • +
  • summary (object) – a summary to use for every sketch entry

  • +
+
+
+
+ +
+
+filter
+

Produces a compact_tuple_sketch from the given sketch by applying a predicate to the summary in each entry.

+
+
Parameters:
+

predicate – A function returning true or value evaluated on each tuple summary

+
+
Returns:
+

A compact_tuple_sketch with the selected entries

+
+
Return type:
+

compact_tuple_sketch

+
+
+
+ +
+
+serialize
+

Serializes the sketch into a bytes object

+
+ +
+ +
+
+class tuple_union(*args, **kwargs)
+
+
+__init__(self, policy: _datasketches.TuplePolicy, lg_k: int = 12, p: float = 1.0, seed: int = 9001) None
+

Creates a tuple_union using the provided parameters

+
+
Parameters:
+
    +
  • policy (TuplePolicy) – a policy to use when unioning entries

  • +
  • lg_k (int, optional) – base 2 logarithm of the maximum size of the union. Default 12.

  • +
  • p (float, optional) – an initial sampling rate to use. Default 1.0

  • +
  • seed (int, optional) – the seed to use when hashing values. Must match any sketch seeds.

  • +
+
+
+
+ +
+
+get_result
+

Returns the sketch corresponding to the union result

+
+ +
+
+reset
+

Resets the sketch to the initial empty

+
+ +
+
+update
+

Updates the union with the given sketch

+
+ +
+ +
+
+class tuple_intersection(*args, **kwargs)
+
+
+__init__(self, policy: _datasketches.TuplePolicy, seed: int = 9001) None
+

Creates a tuple_intersection using the provided parameters

+
+
Parameters:
+
    +
  • policy (TuplePolicy) – a policy to use when intersecting entries

  • +
  • seed (int, optional) – the seed to use when hashing values. Must match any sketch seeds

  • +
+
+
+
+ +
+
+get_result
+

Returns the sketch corresponding to the intersection result

+
+ +
+
+has_result
+

Returns True if the intersection has a valid result, otherwise False

+
+ +
+
+update
+

Intersects the provided sketch with the current intersection state

+
+ +
+ +
+
+class tuple_a_not_b(*args, **kwargs)
+
+
+__init__(self, seed: int = 9001) None
+

Creates a tuple_a_not_b object

+
+
Parameters:
+

seed (int, optional) – the seed to use when hashing values. Must match any sketch seeds.

+
+
+
+ +
+
+compute
+

Returns a sketch with the result of applying the A-not-B operation on the given inputs

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.2.0/frequency/count_min_sketch.html b/docs/5.2.0/frequency/count_min_sketch.html new file mode 100644 index 00000000..934d24d1 --- /dev/null +++ b/docs/5.2.0/frequency/count_min_sketch.html @@ -0,0 +1,301 @@ + + + + + + + + + CountMin Sketch — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

CountMin Sketch

+

The CountMin sketch, as described in Cormode and Muthukrishnan in +http://dimacs.rutgers.edu/~graham/pubs/papers/cm-full.pdf, +is used for approximate Frequency Estimation. +For an item \(x\) with frequency \(f_x\), the sketch provides an estimate, \(\hat{f_x}\), +such that \(f_x \approx \hat{f_x}.\) +The sketch guarantees that \(f_x \le \hat{f_x}\) and provides a probabilistic upper bound which is dependent on the size parameters. +The sketch provides an estimate of the occurrence frequency for any queried item but, in contrast +to the Frequent Items Sketch, this sketch does not provide a list of +heavy hitters.

+
+
+class count_min_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.count_min_sketch
+

Reads a bytes object and returns the corresponding count_min_sketch

+
+ +
+
+suggest_num_buckets(relative_error: float) int
+

Suggests the number of buckets needed to achieve an accuracy within the provided relative_error. For example, when relative_error = 0.05, the returned frequency estimates satisfy the ‘relative_error’ guarantee that never overestimates the weights but may underestimate the weights by 5% of the total weight in the sketch. Returns the number of hash buckets at every level of the sketch required in order to obtain the specified relative error.

+
+ +
+
+suggest_num_hashes(confidence: float) int
+

Suggests the number of hashes needed to achieve the provided confidence. For example, with 95% confidence, frequency estimates satisfy the ‘relative_error’ guarantee. Returns the number of hash functions that are required in order to achieve the specified confidence of the sketch. confidence = 1 - delta, with delta denoting the sketch failure probability.

+
+ +

Non-static Methods:

+
+
+get_estimate
+

Overloaded function.

+
    +
  1. get_estimate(self, item: int) -> float

  2. +
+

Returns an estimate of the frequency of the provided 64-bit integer value

+
    +
  1. get_estimate(self, item: str) -> float

  2. +
+

Returns an estimate of the frequency of the provided string

+
+ +
+
+get_lower_bound
+

Overloaded function.

+
    +
  1. get_lower_bound(self, item: int) -> float

  2. +
+

Returns a lower bound on the estimate for the given 64-bit integer value

+
    +
  1. get_lower_bound(self, item: str) -> float

  2. +
+

Returns a lower bound on the estimate for the provided string

+
+ +
+
+get_relative_error
+

Returns the maximum permissible error for any frequency estimate query

+
+ +
+
+get_serialized_size_bytes
+

Returns the size in bytes of the serialized image of the sketch

+
+ +
+
+get_upper_bound
+

Overloaded function.

+
    +
  1. get_upper_bound(self, item: int) -> float

  2. +
+

Returns an upper bound on the estimate for the given 64-bit integer value

+
    +
  1. get_upper_bound(self, item: str) -> float

  2. +
+

Returns an upper bound on the estimate for the provided string

+
+ +
+
+is_empty
+

Returns True if the sketch has seen no items, otherwise False

+
+ +
+
+merge
+

Merges the provided other sketch into this one

+
+ +
+
+property num_buckets
+

The configured number of buckets for the sketch

+
+ +
+
+property num_hashes
+

The configured number of hashes for the sketch

+
+ +
+
+property seed
+

The base hash seed for the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+property total_weight
+

The total weight currently inserted into the stream

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: int, weight: float = 1.0) -> None

  2. +
+

Updates the sketch with the given 64-bit integer value

+
    +
  1. update(self, item: str, weight: float = 1.0) -> None

  2. +
+

Updates the sketch with the given string

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.2.0/frequency/frequent_items.html b/docs/5.2.0/frequency/frequent_items.html new file mode 100644 index 00000000..77da8961 --- /dev/null +++ b/docs/5.2.0/frequency/frequent_items.html @@ -0,0 +1,477 @@ + + + + + + + + + Frequent Items — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Frequent Items

+

This sketch is useful for tracking approximate frequencies of items (object or string) with optional associated +integer counts that are members of a multiset of such items. +The true frequency of an item is defined to be the sum of associated counts.

+

This implementation provides the following capabilities:

+
    +
  • Estimate the frequency of an item.

  • +
  • Return upper and lower bounds of any item, such that the true frequency is always between the upper and lower bounds.

  • +
  • Return a global maximum error that holds for all items in the stream.

  • +
  • Return an array of frequent items that qualify either a NO_FALSE_POSITIVES or a NO_FALSE_NEGATIVES error type.

  • +
  • Merge itself with another sketch object created from this class.

  • +
  • Serialize/Deserialize to/from a byte array.

  • +
+

Space Usage

+

The sketch is initialized with a maximum map size, maxMapSize, that specifies the maximum physical length of the internal hash map of the form (object item, int count). +The maximum map size is always a power of 2, defined through the variables lg_max_map_size.

+

The hash map starts at a very small size (8 entries) and grows as needed up to the specified maximum map size.

+

Excluding external space required for the item objects, the internal memory space usage of this sketch is 18 * mapSize bytes (assuming 8 bytes for each reference), +plus a small constant number of additional bytes. +The internal memory space usage of this sketch will never exceed 18 * maxMapSize bytes, plus a small constant number of additional bytes.

+

Maximum Capacity of the Sketch

+

The LOAD_FACTOR for the hash map is internally set at \(75\%\), which means at any time the map capacity of (item, count) pairs is mapCap = 0.75 * mapSize. +The maximum capacity of (item, count) pairs of the sketch is maxMapCap = 0.75 * maxMapSize.

+

Updating the sketch with ``(item, count)`` pairs

+

If the item is found in the hash map, the mapped count field (the “counter”) is incremented by the incoming count; otherwise, a new counter (item, count) pair is created. +If the number of tracked counters reaches the maximum capacity of the hash map, the sketch decrements all of the counters (by an approximately computed median) +and removes any non-positive counters.

+

Accuracy

+

If fewer than 0.75 * maxMapSize different items are inserted into the sketch, the estimated frequencies returned by the sketch will be exact.

+

The logic of the frequent items sketch is such that the stored counts and true counts are never too different. +More specifically, for any item, the sketch can return an estimate of the true frequency of item, along with upper and lower bounds on the frequency (that hold deterministically).

+

For this implementation and for a specific active item, it is guaranteed that the true frequency will be between the Upper Bound (UB) and the Lower Bound (LB) computed for that item. +Specifically, (UB- LB) W * epsilon, where \(W\) denotes the sum of all item counts, and \(epsilon = 3.5/M\), where \(epsilon = M\) is the maxMapSize.

+

This is a worst-case guarantee that applies to arbitrary inputs. +For inputs typically seen in practice, (UB-LB) is usually much smaller.

+

Background

+

This code implements a variant of what is commonly known as the “Misra-Gries algorithm”. +Variants of it were discovered and rediscovered and redesigned several times over the years:

+
    +
  • Finding repeated elements, Misra, Gries, 1982

  • +
  • Frequency estimation of Internet packet streams with limited space Demaine, Lopez-Ortiz, Munro, 2002

  • +
  • A simple algorithm for finding frequent elements in streams and bags Karp, Shenker, Papadimitriou, 2003

  • +
  • Efficient Computation of Frequent and Top-k Elements in Data Streams Metwally, Agrawal, Abbadi, 2006

  • +
+

For speed, we do employ some randomization that introduces a small probability that our proof of the worst-case bound might not apply to a given run. +However, we have ensured that this probability is extremely small. +For example, if the stream causes one table purge (rebuild), our proof of the worst-case bound applies with a probability of at least 1 - 1E-14. +If the stream causes 1E9 purges, our proof applies with a probability of at least 1 - 1E-5.

+

There are two flavors of Frequent Items Sketches, one with generic items (objects) and another specific to strings. +The string version is a legacy name from before the library supported generic objects and is retained +only for backwards compatibility.

+
+

Note

+

The frequent_items_sketch uses an input object’s __hash__ and __eq__ methods.

+
+
+

Note

+

Serializing and deserializing the frequent_items_sketch requires the use of a PyObjectSerDe.

+
+
+
+class frequent_items_error_type(*values)
+
+
+NO_FALSE_POSITIVES : Returns only true positives but may miss some heavy hitters.
+
+ +
+
+NO_FALSE_NEGATIVES : Does not miss any heavy hitters but may return false positives.
+
+ +
+ +
+
+class frequent_items_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe) _datasketches.frequent_items_sketch
+

Reads a bytes object using the provided serde and returns the corresponding frequent_strings_sketch.

+
+ +
+
+get_epsilon_for_lg_size(lg_max_map_size: int) float
+

Returns the epsilon value used to compute a priori error for a given log2(max_map_size)

+
+ +
+
+get_apriori_error(lg_max_map_size: int, estimated_total_weight: int) float
+

Returns the estimated a priori error given the max_map_size for the sketch and the estimated_total_stream_weight.

+
+ +

Non-static Methods:

+
+
+__init__(self, lg_max_k: int) None
+

Creates an instance of the sketch

+
+
Parameters:
+

lg_max_k (int) – base 2 logarithm of the maximum size of the internal hash map of the sketch. Maximum capacity is 0.75 of this value, which is the maximum number of distinct items the sketch can contain.

+
+
+
+ +
+
+property epsilon
+

The epsilon value used by the sketch to compute error

+
+ +
+
+get_estimate
+

Returns the estimate of the weight (frequency) of the given item. +Note: The true frequency of a item would be the sum of the counts as a result of the two update functions.

+
+ +
+
+get_frequent_items
+
+ +
+
+get_lower_bound
+

Returns the guaranteed lower bound weight (frequency) of the given item.

+
+ +
+
+get_serialized_size_bytes
+

Computes the size needed to serialize the current state of the sketch using the provided serde. This can be expensive since every item needs to be looked at.

+
+ +
+
+get_upper_bound
+

Returns the guaranteed upper bound weight (frequency) of the given item.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+merge
+

Merges the given sketch into this one

+
+ +
+
+property num_active_items
+

The number of active items in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object using the provided serde.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+property total_weight
+

The sum of the weights (frequencies) in the stream seen so far by the sketch

+
+ +
+
+update
+

Updates the sketch with the given string and, optionally, a weight

+
+ +
+ +
+
+class frequent_strings_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.frequent_strings_sketch
+

Reads a bytes object and returns the corresponding frequent_strings_sketch.

+
+ +
+
+get_epsilon_for_lg_size(lg_max_map_size: int) float
+

Returns the epsilon value used to compute a priori error for a given log2(max_map_size)

+
+ +
+
+get_apriori_error(lg_max_map_size: int, estimated_total_weight: int) float
+

Returns the estimated a priori error given the max_map_size for the sketch and the estimated_total_stream_weight.

+
+ +

Non-static Methods:

+
+
+__init__(self, lg_max_k: int) None
+

Creates an instance of the sketch

+
+
Parameters:
+

lg_max_k (int) – base 2 logarithm of the maximum size of the internal hash map of the sketch. Maximum capacity is 0.75 of this value, which is the maximum number of distinct items the sketch can contain.

+
+
+
+ +
+
+property epsilon
+

The epsilon value used by the sketch to compute error

+
+ +
+
+get_estimate
+

Returns the estimate of the weight (frequency) of the given item. +Note: The true frequency of a item would be the sum of the counts as a result of the two update functions.

+
+ +
+
+get_frequent_items
+
+ +
+
+get_lower_bound
+

Returns the guaranteed lower bound weight (frequency) of the given item.

+
+ +
+
+get_serialized_size_bytes
+

Computes the size needed to serialize the current state of the sketch. This can be expensive since every item needs to be looked at.

+
+ +
+
+get_upper_bound
+

Returns the guaranteed upper bound weight (frequency) of the given item.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+merge
+

Merges the given sketch into this one

+
+ +
+
+property num_active_items
+

The number of active items in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+property total_weight
+

The sum of the weights (frequencies) in the stream seen so far by the sketch

+
+ +
+
+update
+

Updates the sketch with the given string and, optionally, a weight

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.2.0/frequency/index.html b/docs/5.2.0/frequency/index.html new file mode 100644 index 00000000..1f38065c --- /dev/null +++ b/docs/5.2.0/frequency/index.html @@ -0,0 +1,142 @@ + + + + + + + + + Frequency Sketches — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Frequency Sketches

+

Frequency estimation involves determining how often an item has been seen in a stream. The library currently +offers two types of sketches for frequency estimation, one of which has two closely-related variants.

+
+
    +
  • frequent_items_sketch: Identifies the Top K or heavy hitters in a stream, those items whose weight is above a certain percentage of the entire stream. Does not necessarily provide an estimate for most items outside the heavy hitters.

  • +
  • frequent_strings_sketch: Like the items version but containing snly strings (an implementation from before the library handled generic objects).

  • +
  • count_min_sketch: Provides an estimate for any item, regardless of relative weight, but does not maintain a list of the heaviest items.

  • +
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.2.0/genindex.html b/docs/5.2.0/genindex.html new file mode 100644 index 00000000..8c4b4532 --- /dev/null +++ b/docs/5.2.0/genindex.html @@ -0,0 +1,1464 @@ + + + + + + + + Index — datasketches 0.1 documentation + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ + +

Index

+ +
+ _ + | A + | C + | D + | E + | F + | G + | H + | I + | J + | K + | L + | M + | N + | P + | Q + | R + | S + | T + | U + | V + +
+

_

+ + +
+ +

A

+ + +
+ +

C

+ + + +
+ +

D

+ + + +
+ +

E

+ + + +
+ +

F

+ + + +
+ +

G

+ + + +
+ +

H

+ + + +
+ +

I

+ + + +
+ +

J

+ + +
+ +

K

+ + + +
+ +

L

+ + + +
+ +

M

+ + + +
+ +

N

+ + + +
+ +

P

+ + + +
+ +

Q

+ + + +
+ +

R

+ + +
+ +

S

+ + + +
+ +

T

+ + + +
+ +

U

+ + + +
+ +

V

+ + + +
+ + + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.2.0/helper/index.html b/docs/5.2.0/helper/index.html new file mode 100644 index 00000000..dc74ac3f --- /dev/null +++ b/docs/5.2.0/helper/index.html @@ -0,0 +1,152 @@ + + + + + + + + + Helper Classes — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Helper Classes

+

These classes are required for certain sketches or specific +functionality within sketches. +Some of them are abstract base classes, but in those cases there is at +least one reference example of a concrete class.

+
+
    +
  • serde is used when serializing and deserializing sketches.

  • +
  • jaccard is used to compute the Jaccard similarity between pairs of theta or tuple sketches.

  • +
  • tuple_policy is required to use a tuple_sketch by specifying how summaries are combined.

  • +
  • ks_test() performs a Kolmogorov-Smirnov test on absolute-error quantiles family sketches.

  • +
  • kernel_function is required when using a kernel_sketch for Kernel Density Estimation.

  • +
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.2.0/helper/jaccard.html b/docs/5.2.0/helper/jaccard.html new file mode 100644 index 00000000..d36838a3 --- /dev/null +++ b/docs/5.2.0/helper/jaccard.html @@ -0,0 +1,210 @@ + + + + + + + + + Jaccard Similarity — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Jaccard Similarity

+

These objects provide measures related to the Jaccard similarity +of theta_sketch and tuple_sketch objects.

+

Note that there are separate classes to be used for theta and tuple sketches.

+
+
+class theta_jaccard_similarity
+

An object to help compute Jaccard similarity between theta sketches.

+
+
+jaccard(sketch_a: _datasketches.theta_sketch, sketch_b: _datasketches.theta_sketch, seed: int = 9001) list[float]
+

Returns a list with {lower_bound, estimate, upper_bound} of the Jaccard similarity between sketches

+
+ +
+
+exactly_equal(sketch_a: _datasketches.theta_sketch, sketch_b: _datasketches.theta_sketch, seed: int = 9001) bool
+

Returns True if sketch_a and sketch_b are equivalent, otherwise False

+
+ +
+
+similarity_test(actual: _datasketches.theta_sketch, expected: _datasketches.theta_sketch, threshold: float, seed: int = 9001) bool
+

Tests similarity of an actual sketch against an expected sketch. Computers the lower bound of the Jaccard index J_{LB} of the actual and expected sketches. If J_{LB} >= threshold, then the sketches are considered to be similar with a confidence of 97.7% and returns True, otherwise False.

+
+ +
+
+dissimilarity_test(actual: _datasketches.theta_sketch, expected: _datasketches.theta_sketch, threshold: float, seed: int = 9001) bool
+

Tests dissimilarity of an actual sketch against an expected sketch. Computers the lower bound of the Jaccard index J_{UB} of the actual and expected sketches. If J_{UB} <= threshold, then the sketches are considered to be dissimilar with a confidence of 97.7% and returns True, otherwise False.

+
+ +
+ +
+
+class tuple_jaccard_similarity
+

An object to help compute Jaccard similarity between tuple sketches.

+
+
+jaccard(sketch_a: _datasketches.tuple_sketch, sketch_b: _datasketches.tuple_sketch, seed: int = 9001) list[float]
+

Returns a list with {lower_bound, estimate, upper_bound} of the Jaccard similarity between sketches

+
+ +
+
+exactly_equal(sketch_a: _datasketches.tuple_sketch, sketch_b: _datasketches.tuple_sketch, seed: int = 9001) bool
+

Returns True if sketch_a and sketch_b are equivalent, otherwise False

+
+ +
+
+similarity_test(actual: _datasketches.tuple_sketch, expected: _datasketches.tuple_sketch, threshold: float, seed: int = 9001) bool
+

Tests similarity of an actual sketch against an expected sketch. Computes the lower bound of the Jaccard index J_{LB} of the actual and expected sketches. If J_{LB} >= threshold, then the sketches are considered to be similar with a confidence of 97.7% and returns True, otherwise False.

+
+ +
+
+dissimilarity_test(actual: _datasketches.tuple_sketch, expected: _datasketches.tuple_sketch, threshold: float, seed: int = 9001) bool
+

Tests dissimilarity of an actual sketch against an expected sketch. Computes the upper bound of the Jaccard index J_{UB} of the actual and expected sketches. If J_{UB} <= threshold, then the sketches are considered to be dissimilar with a confidence of 97.7% and returns True, otherwise False.

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.2.0/helper/kernel.html b/docs/5.2.0/helper/kernel.html new file mode 100644 index 00000000..f3a8af8c --- /dev/null +++ b/docs/5.2.0/helper/kernel.html @@ -0,0 +1,182 @@ + + + + + + + + + Kernel Function — datasketches 0.1 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Kernel Function

+

A kernel function is a specific type of +mathematical funciton that is particularly useful in certain machine learning and pattern recognition +contexts. The density_sketch performs approximate +kernel density estimation which, unsurprisingly, +relies on the use of such a kernel function.

+

The library provides an abstract base class KernelFunction and an example implementation of a +Gaussian (also known as a Radial Basis Function) kernel. Custom classes must override the base class +and provide a floating point value as a score indicating the similarity of two input vectors.

+
+
+class KernelFunction(*args, **kwargs)
+

A generic base class from which user-defined kernels must inherit.

+
+
+__call__(self, a: object, b: object) float
+

A method to evaluate a kernel with given inputs a and b.

+
+
Parameters:
+
    +
  • a (numpy array) – An input vector

  • +
  • b (numpy array) – An input vector

  • +
+
+
Returns:
+

A vector similarity score

+
+
Return type:
+

float

+
+
+
+ +
+ +
+
+class GaussianKernel(bandwidth: float = 1.0)
+

Bases: KernelFunction

+

Implements a basic Gaussian kernel

+
+
Parameters:
+

bandwidth (float) – The kernel bandwidth, default 1.0

+
+
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.2.0/helper/ks_test.html b/docs/5.2.0/helper/ks_test.html new file mode 100644 index 00000000..598de348 --- /dev/null +++ b/docs/5.2.0/helper/ks_test.html @@ -0,0 +1,208 @@ + + + + + + + + + Kolmogorov-Smirnov Test — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Kolmogorov-Smirnov Test

+

A Kolmogorov-Smirnov Test <https://en.wikipedia.org/wiki/Kolmogorov%E2%80%93Smirnov_test>`_ is +a test of equality of two distributions to determine if they are likely to have come from the same +underlying distribution. +The DataSketches library provides a modified form of the test that takes into account the error +in each underlying sketch in the analysis.

+

Currently, the test assumes both input sketches are of the same family and data type.

+
+
+ks_test(sk_1: _datasketches.kll_ints_sketch, sk_2: _datasketches.kll_ints_sketch, p: float) bool
+
+ks_test(sk_1: _datasketches.kll_floats_sketch, sk_2: _datasketches.kll_floats_sketch, p: float) bool
+
+ks_test(sk_1: _datasketches.kll_doubles_sketch, sk_2: _datasketches.kll_doubles_sketch, p: float) bool
+
+ks_test(sk_1: _datasketches.kll_items_sketch, sk_2: _datasketches.kll_items_sketch, p: float) bool
+
+ks_test(sk_1: _datasketches.quantiles_ints_sketch, sk_2: _datasketches.quantiles_ints_sketch, p: float) bool
+
+ks_test(sk_1: _datasketches.quantiles_floats_sketch, sk_2: _datasketches.quantiles_floats_sketch, p: float) bool
+
+ks_test(sk_1: _datasketches.quantiles_doubles_sketch, sk_2: _datasketches.quantiles_doubles_sketch, p: float) bool
+
+ks_test(sk_1: _datasketches.quantiles_items_sketch, sk_2: _datasketches.quantiles_items_sketch, p: float) bool
+

Overloaded function.

+
    +
  1. ks_test(sk_1: _datasketches.kll_ints_sketch, sk_2: _datasketches.kll_ints_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for kll_ints_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
    +
  1. ks_test(sk_1: _datasketches.kll_floats_sketch, sk_2: _datasketches.kll_floats_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for kll_floats_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
    +
  1. ks_test(sk_1: _datasketches.kll_doubles_sketch, sk_2: _datasketches.kll_doubles_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for kll_doubles_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
    +
  1. ks_test(sk_1: _datasketches.kll_items_sketch, sk_2: _datasketches.kll_items_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for kll_items_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
    +
  1. ks_test(sk_1: _datasketches.quantiles_ints_sketch, sk_2: _datasketches.quantiles_ints_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for quantiles_ints_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
    +
  1. ks_test(sk_1: _datasketches.quantiles_floats_sketch, sk_2: _datasketches.quantiles_floats_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for quantiles_floats_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +:Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
    +
  1. ks_test(sk_1: _datasketches.quantiles_doubles_sketch, sk_2: _datasketches.quantiles_doubles_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for quantiles_doubles_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
    +
  1. ks_test(sk_1: _datasketches.quantiles_items_sketch, sk_2: _datasketches.quantiles_items_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for quantiles_items_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.2.0/helper/serde.html b/docs/5.2.0/helper/serde.html new file mode 100644 index 00000000..95cfd2e5 --- /dev/null +++ b/docs/5.2.0/helper/serde.html @@ -0,0 +1,251 @@ + + + + + + + + + Serialize/Deserialize (SerDe) — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Serialize/Deserialize (SerDe)

+

A SerDe is a class used to serialize items sketches to a bytes object in binary. +Several example SerDes are provided as references.

+

The use of binary-compatible SerDes in different languages is critical for cross-language compatibility.

+

Each implementation must extend the PyObjectSerDe class and override all three of its methods.

+
+
+class PyObjectSerDe(*args, **kwargs)
+

An abstract base class for serde objects. All custom serdes must extend this class.

+
+
+get_size(self, item: object) int
+

Returns the size in bytes of an item

+
+
Parameters:
+

item (object) – The specified object

+
+
Returns:
+

The size of the item in bytes

+
+
Return type:
+

int

+
+
+
+ +
+
+to_bytes(self, item: object) bytes
+

Retuns a bytes object with a serialized version of an item

+
+
Parameters:
+

item (object) – The specified object

+
+
Returns:
+

A bytes object with the serialized object

+
+
Return type:
+

bytes

+
+
+
+ +
+
+from_bytes(self, data: bytes, offset: int) tuple
+

Reads a bytes object starting from the given offest and returns a tuple of the reconstructed object and the number of additional bytes read

+
+
Parameters:
+
    +
  • data (bytes) – A bytes object from which to deserialize

  • +
  • offset (int) – The offset, in bytes, at which to start reading

  • +
+
+
Returns:
+

A tuple with the reconstructed object and the number of bytes read

+
+
Return type:
+

tuple(object, int)

+
+
+
+ +
+ +

The provided SerDes are:

+
+
+class PyStringsSerDe(*args, **kwargs)
+

Bases: PyObjectSerDe

+

Implements a simple string-encoding scheme where a string is +written as <num_bytes> <string_contents>, with no null termination. +This format allows pre-allocating each string, at the cost of +additional storage. Using this format, the serialized string consumes +4 + len(item) bytes.

+
+ +
+
+class PyIntsSerDe(*args, **kwargs)
+

Bases: PyObjectSerDe

+

Implements an integer encoding scheme where each integer is written +as a 32-bit (4 byte) little-endian value.

+
+ +
+
+class PyLongsSerDe(*args, **kwargs)
+

Bases: PyObjectSerDe

+

Implements an integer encoding scheme where each integer is written +as a 64-bit (8 byte) little-endian value.

+
+ +
+
+class PyFloatsSerDe(*args, **kwargs)
+

Bases: PyObjectSerDe

+

Implements a floating point encoding scheme where each value is written +as a 32-bit floating point value.

+
+ +
+
+class PyDoublesSerDe(*args, **kwargs)
+

Implements a floating point encoding scheme where each value is written +as a 64-bit floating point value.

+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.2.0/helper/tuple_policy.html b/docs/5.2.0/helper/tuple_policy.html new file mode 100644 index 00000000..f1e065bc --- /dev/null +++ b/docs/5.2.0/helper/tuple_policy.html @@ -0,0 +1,228 @@ + + + + + + + + + Tuple Policy — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Tuple Policy

+

A Tuple Policy is needed when using a tuple_sketch in order to specify how the +summary values should be created, updated, combined, or intersected. A summary can consist of +any python object.

+

Each implementation must extend the abstract base class TuplePolicy.

+
+
+class TuplePolicy(*args, **kwargs)
+

An abstract base class for Tuple Policy objects. All custom policies must extend this class.

+
+
+create_summary(self) object
+

Creates a new Summary object

+
+
Returns:
+

a Summary object

+
+
Return type:
+

object

+
+
+
+ +
+
+update_summary(self, summary: object, update: object) object
+

Applies the relevant policy to update the provided summary with the data in update.

+
+
Parameters:
+
    +
  • summary (object) – An existing Summary

  • +
  • update (object) – An update to apply to the Summary

  • +
+
+
Returns:
+

The updated Summary

+
+
Return type:
+

object

+
+
+
+ +
+
+__call__(self, summary: object, update: object) object
+

Similar to update_summary but allows a different implementation for set operations (union and intersection)

+
+
Parameters:
+
    +
  • summary (object) – An existing Summary

  • +
  • update (object) – An update to apply to the Summary

  • +
+
+
Returns:
+

The updated Summary

+
+
Return type:
+

object

+
+
+
+ +
+ +
+
+class AccumulatorPolicy
+

Bases: TuplePolicy

+

Implements an accumulatory summary policy, where new values +are added to the existing value.

+
+ +
+
+class MinIntPolicy
+

Bases: TuplePolicy

+

Implements a MIN rule, where the smallest integer value is always kept.

+
+ +
+
+class MaxIntPolicy
+

Bases: TuplePolicy

+

Implements a MAX rule, where the largest integer value is always kept.

+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.2.0/index.html b/docs/5.2.0/index.html new file mode 100644 index 00000000..df3fafab --- /dev/null +++ b/docs/5.2.0/index.html @@ -0,0 +1,213 @@ + + + + + + + + + Apache DataSketches — datasketches 0.1 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Apache DataSketches

+

DataSketches are highly-efficient algorithms to analyze big data quickly.

+
+

Counting Distincts

+ +
+
+

Quantile Estimation

+ +
+
+

Frequency Sketches

+

This problem may also be known as heavy hitters or TopK

+ +
+
+

Vector Sketches

+ +
+
+

Random Sampling

+ +
+
+

Helper Classes

+ +
+

Note

+

This project is under active development.

+
+
+
+
+

Indices and tables

+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.2.0/objects.inv b/docs/5.2.0/objects.inv new file mode 100644 index 00000000..4e57db77 Binary files /dev/null and b/docs/5.2.0/objects.inv differ diff --git a/docs/5.2.0/quantiles/index.html b/docs/5.2.0/quantiles/index.html new file mode 100644 index 00000000..c94ed2e3 --- /dev/null +++ b/docs/5.2.0/quantiles/index.html @@ -0,0 +1,157 @@ + + + + + + + + + Quantiles Sketches — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Quantiles Sketches

+

Quantile estimation is useful for understanding the distribution of data values in a stream. The sketches currently +in the library are designed to answer queries about the rank of an item in the stream of items. That is, when +applying a global ordering on all the items, what is the portion of items seen so far that are less than (alternatively, +less-than-or-equal-to) the given item. Using straightforward logic, they can also estimate the item at a given rank +in the stream.

+

These sketches may be used to compute approximate histograms, Probability Mass Functions (PMFs), or +Cumulative Distribution Functions (CDFs).

+

The library provides four types of quantiles sketches, three of which have generic items as well as versions +specific to a given numeric type (e.g. integer or floating point values). Those three types provide error +bounds on rank estimation with proven probabilistic error distributions. t-digest is a heuristic-based sketch +that works only on numeric data, and while the error properties are not guaranteed, the sketch typically +does a good job with small storage.

+
+
    +
  • KLL: Provides uniform rank estimation error over the entire range.

  • +
  • REQ: Provides relative rank error estimates, which decreases approaching either the high or low end values.

  • +
  • t-digest: Relative rank error estimates, heuristic-based without guarantees but quite compact with generally very good error properties.

  • +
  • Classic quantiles: Largely deprecated in favor of KLL, also provides uniform rank estimation error. Included largely for backwards compatibility with historic data.

  • +
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.2.0/quantiles/kll.html b/docs/5.2.0/quantiles/kll.html new file mode 100644 index 00000000..d8867ed7 --- /dev/null +++ b/docs/5.2.0/quantiles/kll.html @@ -0,0 +1,960 @@ + + + + + + + + + KLL Sketch — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

KLL Sketch

+

Implementation of a very compact quantiles sketch with lazy compaction scheme +and nearly optimal accuracy per retained item. +See Optimal Quantile Approximation in Streams.

+

This is a stochastic streaming sketch that enables near real-time analysis of the +approximate distribution of items from a very large stream in a single pass, requiring only +that the items are comparable. +The analysis is obtained using get_quantile() function or the +inverse functions get_rank(), get_pmf() (Probability Mass Function), and get_cdf() +(Cumulative Distribution Function).

+

Given an input stream of N items, the natural rank of any specific +item is defined as its index (1 to N) in inclusive mode +or (0 to N-1) in exclusive mode +in the hypothetical sorted stream of all N input items.

+

The normalized rank (rank) of any specific item is defined as its +natural rank divided by N. +Thus, the normalized rank is between zero and one. +In the documentation for this sketch natural rank is never used so any +reference to just rank should be interpreted to mean normalized rank.

+

This sketch is configured with a parameter k, which affects the size of the sketch +and its estimation error.

+

The estimation error is commonly called epsilon (or eps) and is a fraction +between zero and one. Larger values of k result in smaller values of epsilon. +Epsilon is always with respect to the rank and cannot be applied to the +corresponding items.

+

The relationship between the normalized rank and the corresponding items can be viewed +as a two-dimensional monotonic plot with the normalized rank on one axis and the +corresponding items on the other axis. If the y-axis is specified as the item-axis and +the x-axis as the normalized rank, then y = get_quantile(x) is a monotonically +increasing function.

+

The function get_quantile(rank) translates ranks into +corresponding quantiles. The functions get_rank(item), +get_cdf(…) (Cumulative Distribution Function), and get_pmf(…) +(Probability Mass Function) perform the opposite operation and translate items into ranks.

+

The get_pmf(…) function has about 13 to 47% worse rank error (depending +on k) than the other queries because the mass of each “bin” of the PMF has +“double-sided” error from the upper and lower edges of the bin as a result of a subtraction, +as the errors from the two edges can sometimes add.

+

The default k of 200 yields a “single-sided” epsilon of about 1.33% and a +“double-sided” (PMF) epsilon of about 1.65%.

+

A get_quantile(rank) query has the following guarantees: +- Let q = get_quantile(r) where r is the rank between zero and one. +- The quantile q will be an item from the input stream. +- Let true_rank be the true rank of q derived from the hypothetical sorted +stream of all N items. +- Let eps = get_normalized_rank_error(false). +- Then r - eps ≤ true_rank ≤ r + eps with a confidence of 99%. Note that the +error is on the rank, not the quantile.

+

A get_rank(item) query has the following guarantees: +- Let r = get_rank(i) where i is an item between the min and max items of +the input stream. +- Let true_rank be the true rank of i derived from the hypothetical sorted +stream of all N items. +- Let eps = get_normalized_rank_error(false). +- Then r - eps ≤ true_rank ≤ r + eps with a confidence of 99%.

+

A get_pmf() query has the following guarantees: +- Let {r1, r2, …, r(m+1)} = get_pmf(s1, s2, …, sm) where s1, s2 are +split points (items from the input domain) between the min and max items of +the input stream. +- Let mass_i = estimated mass between s_i and s_i+1. +- Let true_mass be the true mass between the items of s_i, +s_i+1 derived from the hypothetical sorted stream of all N items. +- Let eps = get_normalized_rank_error(true). +- then mass - eps ≤ true_mass ≤ mass + eps with a confidence of 99%. +- r(m+1) includes the mass of all points larger than s_m.

+

A get_cdf(…) query has the following guarantees; +- Let {r1, r2, …, r(m+1)} = get_cdf(s1, s2, …, sm) where s1, s2, … are +split points (items from the input domain) between the min and max items of +the input stream. +- Let mass_i = r_(i+1) - r_i. +- Let true_mass be the true mass between the true ranks of s_i, +s_i+1 derived from the hypothetical sorted stream of all N items. +- Let eps = get_normalized_rank_error(true). +- then mass - eps ≤ true_mass ≤ mass + eps with a confidence of 99%. +- 1 - r(m+1) includes the mass of all points larger than s_m.

+

From the above, it might seem like we could make some estimates to bound the +item returned from a call to get_quantile(). The sketch, however, does not +let us derive error bounds or confidences around items. Because errors are independent, we +can approximately bracket a value as shown below, but there are no error estimates available. +Additionally, the interval may be quite large for certain distributions. +- Let q = get_quantile(r), the estimated quantile of rank r. +- Let eps = get_normalized_rank_error(false). +- Let q_lo = estimated quantile of rank (r - eps). +- Let q_hi = estimated quantile of rank (r + eps). +- Then q_lo ≤ q ≤ q_hi, with 99% confidence.

+
+

Note

+

For the kll_items_sketch, objects must be comparable with __lt__.

+
+
+

Note

+

Serializing and deserializing a kll_items_sketch requires the use of a PyObjectSerDe.

+
+
+
+class kll_ints_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.kll_ints_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 200) None
+

Creates a KLL sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 200.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given normalized rank in a hypothetical sorted version of the input stream so far. +For kll_floats_sketch: if the sketch is empty this returns nan. For kll_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: int) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=int32]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class kll_floats_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.kll_floats_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 200) None
+

Creates a KLL sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 200.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given normalized rank in a hypothetical sorted version of the input stream so far. +For kll_floats_sketch: if the sketch is empty this returns nan. For kll_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: float) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=float32]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class kll_doubles_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.kll_doubles_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 200) None
+

Creates a KLL sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 200.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given normalized rank in a hypothetical sorted version of the input stream so far. +For kll_floats_sketch: if the sketch is empty this returns nan. For kll_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: float) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=float64]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class kll_items_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe) _datasketches.kll_items_sketch
+

Deserializes the sketch from a bytes object using the provided serde.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 200) None
+

Creates a KLL sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 200.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given normalized rank in a hypothetical sorted version of the input stream so far. +For kll_floats_sketch: if the sketch is empty this returns nan. For kll_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object using the provided serde.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Updates the sketch with the given value

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.2.0/quantiles/quantiles_depr.html b/docs/5.2.0/quantiles/quantiles_depr.html new file mode 100644 index 00000000..9b5605ee --- /dev/null +++ b/docs/5.2.0/quantiles/quantiles_depr.html @@ -0,0 +1,902 @@ + + + + + + + + + Quantiles Sketch (Deprecated) — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Quantiles Sketch (Deprecated)

+

This is a deprecated quantiles sketch that is included for cross-language compatibility. +Most new projects will favor the KLL sketch over this one, or the REQ sketch for higher accuracy +at the very edge of a distribution.

+

This is a stochastic streaming sketch that enables near-real time analysis of the +approximate distribution from a very large stream in a single pass. +The analysis is obtained using get_rank() and get_quantile() functions, +the Probability Mass Function from get_pmf()` and the Cumulative Distribution Function from get_cdf.

+

Consider a large stream of one million values such as packet sizes coming into a network node. +The natural rank of any specific size value is its index in the hypothetical sorted +array of values. +The normalized rank is the natural rank divided by the stream size, +in this case one million. +The value corresponding to the normalized rank of 0.5 represents the 50th percentile or median +value of the distribution, or get_quantile(0.5). +Similarly, the 95th percentile is obtained from get_quantile(0.95).

+

From the min and max values, for example, 1 and 1000 bytes, +you can obtain the PMF from get_pmf(100, 500, 900) that will result in an array of +4 fractional values such as {.4, .3, .2, .1}, which means that +40% of the values were < 100, +30% of the values were ≥ 100 and < 500, +20% of the values were ≥ 500 and < 900, and +10% of the values were ≥ 900. +A frequency histogram can be obtained by multiplying these fractions by get_n(), +which is the total count of values received. +The get_cdf()` works similarly, but produces the cumulative distribution instead.

+

As of November 2021, this implementation produces serialized sketches which are binary-compatible +with the equivalent Java implementation only when template parameter T = double +(64-bit double precision values).

+

The accuracy of this sketch is a function of the configured value k, which also affects +the overall size of the sketch. Accuracy of this quantile sketch is always with respect to +the normalized rank. A k of 128 produces a normalized, rank error of about 1.7%. +For example, the median item returned from get_quantile(0.5) will be between the actual items +from the hypothetically sorted array of input items at normalized ranks of 0.483 and 0.517, with +a confidence of about 99%.

+
+

Note

+

For the quantiles_items_sketch, objects must be comparable with __lt__.

+
+
+

Note

+

Serializing and deserializing a quantiles_items_sketch requires the use of a PyObjectSerDe.

+
+
+
+class quantiles_ints_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.quantiles_ints_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 128) None
+

Creates a classic quantiles sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 128.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given rank in a hypothetical sorted version of the input stream so far. +For quantiles_floats_sketch: if the sketch is empty this returns nan. For quantiles_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: int) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=int32]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class quantiles_floats_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.quantiles_floats_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 128) None
+

Creates a classic quantiles sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 128.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given rank in a hypothetical sorted version of the input stream so far. +For quantiles_floats_sketch: if the sketch is empty this returns nan. For quantiles_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: float) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=float32]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class quantiles_doubles_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.quantiles_doubles_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 128) None
+

Creates a classic quantiles sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 128.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given rank in a hypothetical sorted version of the input stream so far. +For quantiles_floats_sketch: if the sketch is empty this returns nan. For quantiles_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: float) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=float64]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class quantiles_items_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe) _datasketches.quantiles_items_sketch
+

Deserializes the sketch from a bytes object using the provided serde.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 128) None
+

Creates a classic quantiles sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 128.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given rank in a hypothetical sorted version of the input stream so far. +For quantiles_floats_sketch: if the sketch is empty this returns nan. For quantiles_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object using the provided serde.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Updates the sketch with the given value

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.2.0/quantiles/req.html b/docs/5.2.0/quantiles/req.html new file mode 100644 index 00000000..c81e563a --- /dev/null +++ b/docs/5.2.0/quantiles/req.html @@ -0,0 +1,753 @@ + + + + + + + + + Relative Error Quantiles (REQ) Sketch — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Relative Error Quantiles (REQ) Sketch

+

This is an implementation based on the paper “Relative Error Streaming Quantiles” by Graham Cormode, Zohar Karnin, Edo Liberty, Justin Thaler, Pavel Veselý, and loosely derived from a Python prototype written by Pavel Veselý.

+

This implementation differs from the algorithm described in the paper in the following:

+

The algorithm requires no upper bound on the stream length. +Instead, each relative-compactor counts the number of compaction operations performed so far (via variable state). +Initially, the relative-compactor starts with INIT_NUMBER_OF_SECTIONS. +Each time the number of compactions (variable state) exceeds 2^{numSections - 1}, we double numSections. +Note that after merging the sketch with another one variable state may not correspond to the number of compactions performed at a particular level, however, +since the state variable never exceeds the number of compactions, the guarantees of the sketch remain valid.

+

The size of each section (variable k and section_size in the code and parameter k in the paper) is +initialized with a number set by the user via variable k. +When the number of sections doubles, we decrease section_size by a factor of sqrt(2). +This is applied at each level separately. +Thus, when we double the number of sections, the nominal compactor size increases by a factor of approx. sqrt(2) (+/- rounding).

+

The merge operation here does not perform “special compactions”, which are used in the paper to allow for a tight mathematical analysis of the sketch. +This implementation provides a number of capabilities not discussed in the paper or provided in the Python prototype.

+

The Python prototype only implemented high accuracy for low ranks. This implementation provides the user with the ability to +choose either high rank accuracy or low rank accuracy at the time of sketch construction. +The Python prototype only implemented a comparison criterion of INCLUSIVE. +This implementation allows the user to use both the INCLUSIVE criterion and the EXCLUSIVE criterion. +This implementation provides extensive debug visibility into the operation of the sketch with two levels of detail output. +This is not only useful for debugging, but is a powerful tool to help users understand how the sketch works.

+
+

Note

+

For the req_items_sketch, objects must be comparable with __lt__.

+
+
+

Note

+

Serializing and deserializing a req_items_sketch requires the use of a PyObjectSerDe.

+
+
+
+class req_ints_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.req_ints_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_RSE(k: int, rank: float, is_hra: bool, n: int) float
+

Returns an a priori estimate of relative standard error (RSE, expressed as a number in [0,1]). Derived from Lemma 12 in http://arxiv.org/abs/2004.01668v2, but the constant factors have been modified based on empirical measurements, for a given value of parameter k. +Normalized rank must be a value between 0.0 and 1.0 (inclusive). If is_hra is True, uses high rank accuracy mode, else low rank accuracy. N is an estimate of the total number of points provided to the sketch.

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 12, is_hra: bool = True) None
+

Creates an REQ sketch instance with the given value of k.

+
+
Parameters:
+
    +
  • k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 12.

  • +
  • is_hra (bool, optional) – Specifies whether the skech has High Rank Accuracy (True) or Low Rank Accuracy. Default True.

  • +
+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, req_floats_sketch returns nan; req_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, req_floats_sketch returns nan; req_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given normalized rank in a hypothetical sorted version of the input stream so far. +For req_floats_sketch: if the sketch is empty this returns nan. For req_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+get_rank_lower_bound
+

Returns an approximate lower bound on the given normalized rank. +Normalized rank must be a value between 0.0 and 1.0 (inclusive); the number of standard deviations must be 1, 2, or 3.

+
+ +
+
+get_rank_upper_bound
+

Returns an approximate upper bound on the given normalized rank. +Normalized rank must be a value between 0.0 and 1.0 (inclusive); the number of standard deviations must be 1, 2, or 3.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+is_hra
+

Returns True if the sketch is in High Rank Accuracy mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: int) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=int32]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class req_floats_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.req_floats_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_RSE(k: int, rank: float, is_hra: bool, n: int) float
+

Returns an a priori estimate of relative standard error (RSE, expressed as a number in [0,1]). Derived from Lemma 12 in http://arxiv.org/abs/2004.01668v2, but the constant factors have been modified based on empirical measurements, for a given value of parameter k. +Normalized rank must be a value between 0.0 and 1.0 (inclusive). If is_hra is True, uses high rank accuracy mode, else low rank accuracy. N is an estimate of the total number of points provided to the sketch.

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 12, is_hra: bool = True) None
+

Creates an REQ sketch instance with the given value of k.

+
+
Parameters:
+
    +
  • k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 12.

  • +
  • is_hra (bool, optional) – Specifies whether the skech has High Rank Accuracy (True) or Low Rank Accuracy. Default True.

  • +
+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, req_floats_sketch returns nan; req_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, req_floats_sketch returns nan; req_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given normalized rank in a hypothetical sorted version of the input stream so far. +For req_floats_sketch: if the sketch is empty this returns nan. For req_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+get_rank_lower_bound
+

Returns an approximate lower bound on the given normalized rank. +Normalized rank must be a value between 0.0 and 1.0 (inclusive); the number of standard deviations must be 1, 2, or 3.

+
+ +
+
+get_rank_upper_bound
+

Returns an approximate upper bound on the given normalized rank. +Normalized rank must be a value between 0.0 and 1.0 (inclusive); the number of standard deviations must be 1, 2, or 3.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+is_hra
+

Returns True if the sketch is in High Rank Accuracy mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: float) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=float32]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class req_items_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe) _datasketches.req_items_sketch
+

Deserializes the sketch from a bytes object using the provided serde.

+
+ +
+
+get_RSE(k: int, rank: float, is_hra: bool, n: int) float
+

Returns an a priori estimate of relative standard error (RSE, expressed as a number in [0,1]). Derived from Lemma 12 in http://arxiv.org/abs/2004.01668v2, but the constant factors have been modified based on empirical measurements, for a given value of parameter k. +Normalized rank must be a value between 0.0 and 1.0 (inclusive). If is_hra is True, uses high rank accuracy mode, else low rank accuracy. N is an estimate of the total number of points provided to the sketch.

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 12, is_hra: bool = True) None
+

Creates an REQ sketch instance with the given value of k.

+
+
Parameters:
+
    +
  • k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 12.

  • +
  • is_hra (bool, optional) – Specifies whether the skech has High Rank Accuracy (True) or Low Rank Accuracy. Default True.

  • +
+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, req_floats_sketch returns nan; req_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, req_floats_sketch returns nan; req_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given normalized rank in a hypothetical sorted version of the input stream so far. +For req_floats_sketch: if the sketch is empty this returns nan. For req_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+get_rank_lower_bound
+

Returns an approximate lower bound on the given normalized rank. +Normalized rank must be a value between 0.0 and 1.0 (inclusive); the number of standard deviations must be 1, 2, or 3.

+
+ +
+
+get_rank_upper_bound
+

Returns an approximate upper bound on the given normalized rank. +Normalized rank must be a value between 0.0 and 1.0 (inclusive); the number of standard deviations must be 1, 2, or 3.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+is_hra
+

Returns True if the sketch is in High Rank Accuracy mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object using the provided serde.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Updates the sketch with the given value

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.2.0/quantiles/tdigest.html b/docs/5.2.0/quantiles/tdigest.html new file mode 100644 index 00000000..dde4f4b8 --- /dev/null +++ b/docs/5.2.0/quantiles/tdigest.html @@ -0,0 +1,445 @@ + + + + + + + + + t-digest — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

t-digest

+

The implementation in this library is based on the MergingDigest described in +Computing Extremely Accurate Quantiles Using t-Digests by Ted Dunning and Otmar Ertl.

+

The implementation in this library has a few differences from the reference implementation associated with that paper:

+
    +
  • Merge does not modify the input

  • +
  • Derialization similar to other sketches in this library, although reading the reference implementation format is supported

  • +
+

Unlike all other algorithms in the library, t-digest is empirical and has no mathematical basis for estimating its error +and its results are dependent on the input data. However, for many common data distributions, it can produce excellent results. +t-digest also operates only on numeric data and, unlike the quantiles family algorithms in the library which return quantile +approximations from the input domain, t-digest interpolates values and will hold and return data points not seen in the input.

+

The closest alternative to t-digest in this library is REQ sketch. It prioritizes one chosen side of the rank domain: +either low rank accuracy or high rank accuracy. t-digest (in this implementation) prioritizes both ends of the rank domain +and has lower accuracy towards the middle of the rank domain (median).

+

Measurements show that t-digest is slightly biased (tends to underestimate low ranks and overestimate high ranks), while still +doing very well close to the extremes. The effect seems to be more pronounced with more input values.

+

For more information on the performance characteristics, see the Datasketches page on t-digest.

+
+
+class tdigest_float(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.tdigest_float
+

Deserializes the sketch from a bytes object.

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 200) None
+

Creates a tdigest instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 200.

+
+
+
+ +
+
+compress
+

Process buffered values and merge centroids, if necesssary

+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given rank in a hypothetical sorted version of the input stream so far.

+
+ +
+
+get_rank
+

Computes the approximate normalized rank of the given value

+
+ +
+
+get_serialized_size_bytes
+

Returns the size of the serialized sketch, in bytes

+
+ +
+
+get_total_weight
+

The total weight processed by the sketch

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: float) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=float32]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class tdigest_double(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.tdigest_double
+

Deserializes the sketch from a bytes object.

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 200) None
+

Creates a tdigest instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 200.

+
+
+
+ +
+
+compress
+

Process buffered values and merge centroids, if necesssary

+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given rank in a hypothetical sorted version of the input stream so far.

+
+ +
+
+get_rank
+

Computes the approximate normalized rank of the given value

+
+ +
+
+get_serialized_size_bytes
+

Returns the size of the serialized sketch, in bytes

+
+ +
+
+get_total_weight
+

The total weight processed by the sketch

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: float) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=float64]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.2.0/sampling/ebpps.html b/docs/5.2.0/sampling/ebpps.html new file mode 100644 index 00000000..8702d120 --- /dev/null +++ b/docs/5.2.0/sampling/ebpps.html @@ -0,0 +1,236 @@ + + + + + + + + + Exact and Bounded, Probabilitiy Proportional to Size (EBPPS) Sampling — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Exact and Bounded, Probabilitiy Proportional to Size (EBPPS) Sampling

+

An EBPPS sketch produces a randome sample of data from a stream of items, ensuring that the probability +of including an item is always exactly equal to the item’s size. The size of an item is defined as its +weight relative to the total weight of all items seen so far by the sketch. In contrast to VarOpt sampling, +this sketch may return fewer than k items in order to keep the probability of including an item strictly +proportional to its size.

+

This sketch is based on: B. Hentschel, P. J. Haas, Y. Tian +“Exact PPS Sampling with Bounded Sample Size”, +Information Processing Letters, 2023.

+

EBPPS sampling is related to reservoir sampling, but handles unequal item weights. +Feeding the sketch items with a uniform weight value will produce a sample equivalent to reservoir sampling.

+
+

Note

+

Serializing and deserializing this sketch requires the use of a PyObjectSerDe.

+
+
+
+class ebpps_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe) _datasketches.ebpps_sketch
+

Reads a bytes object and returns the corresponding ebpps_sketch

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int) None
+

Creates a new EBPPS sketch instance

+
+
Parameters:
+

k (int) – Maximum number of samples in the sketch

+
+
+
+ +
+
+property c
+

The expected number of samples returned upon a call to get_result() or the creation of an iterator. The number is a floating point value, where the fractional portion represents the probability of including a “partial item” from the sample. The value C should be no larger than the sketch’s configured value of k, although numerical precision limitations mean it may exceed k by double precision floating point error margins in certain cases.

+
+ +
+
+get_serialized_size_bytes
+

Computes the size in bytes needed to serialize the current sketch

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+property k
+

The sketch’s maximum configured sample size

+
+ +
+
+merge
+

Merges the sketch with the given sketch

+
+ +
+
+property n
+

The total stream length

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object

+
+ +
+
+to_string
+

Produces a string summary of the sketch and optionally prints the items

+
+ +
+
+update
+

Updates the sketch with the given value and weight

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.2.0/sampling/index.html b/docs/5.2.0/sampling/index.html new file mode 100644 index 00000000..8bb64355 --- /dev/null +++ b/docs/5.2.0/sampling/index.html @@ -0,0 +1,145 @@ + + + + + + + + + Random Sampling Sketches — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Random Sampling Sketches

+

These sketches are used to randomly sample items. The length of the input +stream does not need to be known in advance.

+

Both VarOpt (Variance Optimal) and EBPPS (Exact and Bounded, +Probability Proportional to Size) sketches will include sample items based on +each item’s weight relative to the weight of the entire stream but +they differ in details:

+
+
    +
  • ebpps_sketch ensures that the probability of including an item is always exactly proportional to the item’s weight.

  • +
  • var_opt_sketch optimizes for applying a predicate to the resulting sample such that the variance of the subset sum after applying the predicate is minimized, even if the inclusion probability differs somewhat from being proportional to the item’s weight.

  • +
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.2.0/sampling/varopt.html b/docs/5.2.0/sampling/varopt.html new file mode 100644 index 00000000..6a988363 --- /dev/null +++ b/docs/5.2.0/sampling/varopt.html @@ -0,0 +1,298 @@ + + + + + + + + + Variance Optimal Sampling (VarOpt) — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Variance Optimal Sampling (VarOpt)

+

A VarOpt sketch samples data from a stream of items. The sketch is desinged for optimal (minimum) +variance when querying the sketch to estimate subset sums of items matching a provided predicate. +The sketch will produce a sample of size k (or smaller if fewer items have been presented), with +the probability of including an item roughly corresponding it the item’s weight relative to the total +weight of all items presented to the sketch.

+

VarOpt sampling is related to reservoir sampling, with improved error bounds for subset sum estimation. +Feeding the sketch items with a uniform weight value will produce a sample equivalent to reservoir sampling.

+
+

Note

+

Serializing and deserializing this sketch requires the use of a PyObjectSerDe.

+
+
+
+class var_opt_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe) _datasketches.var_opt_sketch
+

Reads a bytes object and returns the corresponding var opt sketch

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int) None
+

Creates a new Var Opt sketch instance

+
+
Parameters:
+

k (int) – Maximum number of samples in the sketch

+
+
+
+ +
+
+estimate_subset_sum
+

Applies a provided predicate to the sketch and returns the estimated total weight matching the predicate, as well as upper and lower bounds on the estimate and the total weight processed by the sketch

+
+ +
+
+get_serialized_size_bytes
+

Computes the size in bytes needed to serialize the current sketch

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+property k
+

Returns the sketch’s maximum configured sample size

+
+ +
+
+property n
+

Returns the total stream length

+
+ +
+
+property num_samples
+

Returns the number of samples currently in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object

+
+ +
+
+to_string
+

Produces a string summary of the sketch and optionally prints the items

+
+ +
+
+update
+

Updates the sketch with the given value and weight

+
+ +
+ +
+
+class var_opt_union(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe) _datasketches.var_opt_union
+

Constructs a var opt union from the given bytes using the provided serde

+
+ +

Non-static Methods:

+
+
+__init__(self, max_k: int) None
+
+ +
+
+get_result
+

Returns a sketch corresponding to the union result

+
+ +
+
+get_serialized_size_bytes
+

Computes the size in bytes needed to serialize the current union

+
+ +
+
+reset
+

Resets the union to the empty state

+
+ +
+
+serialize
+

Serializes the union into a bytes object with the provided serde

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Updates the union with the given sketch

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.2.0/search.html b/docs/5.2.0/search.html new file mode 100644 index 00000000..d26add38 --- /dev/null +++ b/docs/5.2.0/search.html @@ -0,0 +1,134 @@ + + + + + + + + Search — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ + + + +
+ +
+ +
+
+ +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/docs/5.2.0/searchindex.js b/docs/5.2.0/searchindex.js new file mode 100644 index 00000000..e0046614 --- /dev/null +++ b/docs/5.2.0/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"alltitles":{"Apache DataSketches":[[14,null]],"Compressed Probabilistic Counting (CPC)":[[0,null]],"CountMin Sketch":[[5,null]],"Counting Distincts":[[14,"counting-distincts"]],"Density Sketch":[[23,null]],"Distinct Counting":[[2,null]],"Exact and Bounded, Probabilitiy Proportional to Size (EBPPS) Sampling":[[20,null]],"Frequency Sketches":[[7,null],[14,"frequency-sketches"]],"Frequent Items":[[6,null]],"Helper Classes":[[8,null],[14,"helper-classes"]],"HyperLogLog (HLL)":[[1,null]],"Indices and tables":[[14,"indices-and-tables"]],"Jaccard Similarity":[[9,null]],"KLL Sketch":[[16,null]],"Kernel Function":[[10,null]],"Kolmogorov-Smirnov Test":[[11,null]],"Quantile Estimation":[[14,"quantile-estimation"]],"Quantiles Sketch (Deprecated)":[[17,null]],"Quantiles Sketches":[[15,null]],"Random Sampling":[[14,"random-sampling"]],"Random Sampling Sketches":[[21,null]],"Relative Error Quantiles (REQ) Sketch":[[18,null]],"Serialize/Deserialize (SerDe)":[[12,null]],"Theta Sketch":[[3,null]],"Tuple Policy":[[13,null]],"Tuple Sketch":[[4,null]],"Variance Optimal Sampling (VarOpt)":[[22,null]],"Vector Sketches":[[14,"vector-sketches"],[24,null]],"t-digest":[[19,null]]},"docnames":["distinct_counting/cpc","distinct_counting/hyper_log_log","distinct_counting/index","distinct_counting/theta","distinct_counting/tuple","frequency/count_min_sketch","frequency/frequent_items","frequency/index","helper/index","helper/jaccard","helper/kernel","helper/ks_test","helper/serde","helper/tuple_policy","index","quantiles/index","quantiles/kll","quantiles/quantiles_depr","quantiles/req","quantiles/tdigest","sampling/ebpps","sampling/index","sampling/varopt","vector/density_sketch","vector/index"],"envversion":{"sphinx":65,"sphinx.domains.c":3,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":9,"sphinx.domains.index":1,"sphinx.domains.javascript":3,"sphinx.domains.math":2,"sphinx.domains.python":4,"sphinx.domains.rst":2,"sphinx.domains.std":2},"filenames":["distinct_counting/cpc.rst","distinct_counting/hyper_log_log.rst","distinct_counting/index.rst","distinct_counting/theta.rst","distinct_counting/tuple.rst","frequency/count_min_sketch.rst","frequency/frequent_items.rst","frequency/index.rst","helper/index.rst","helper/jaccard.rst","helper/kernel.rst","helper/ks_test.rst","helper/serde.rst","helper/tuple_policy.rst","index.rst","quantiles/index.rst","quantiles/kll.rst","quantiles/quantiles_depr.rst","quantiles/req.rst","quantiles/tdigest.rst","sampling/ebpps.rst","sampling/index.rst","sampling/varopt.rst","vector/density_sketch.rst","vector/index.rst"],"indexentries":{"__call__() (kernelfunction method)":[[10,"datasketches.KernelFunction.__call__",false]],"__call__() (tuplepolicy method)":[[13,"datasketches.TuplePolicy.__call__",false]],"__init__() (compact_theta_sketch method)":[[3,"datasketches.compact_theta_sketch.__init__",false]],"__init__() (compact_tuple_sketch method)":[[4,"datasketches.compact_tuple_sketch.__init__",false]],"__init__() (cpc_sketch method)":[[0,"datasketches.cpc_sketch.__init__",false]],"__init__() (cpc_union method)":[[0,"datasketches.cpc_union.__init__",false]],"__init__() (density_sketch method)":[[23,"datasketches.density_sketch.__init__",false]],"__init__() (ebpps_sketch method)":[[20,"datasketches.ebpps_sketch.__init__",false]],"__init__() (frequent_items_sketch method)":[[6,"datasketches.frequent_items_sketch.__init__",false]],"__init__() (frequent_strings_sketch method)":[[6,"datasketches.frequent_strings_sketch.__init__",false]],"__init__() (hll_sketch method)":[[1,"datasketches.hll_sketch.__init__",false]],"__init__() (hll_union method)":[[1,"datasketches.hll_union.__init__",false]],"__init__() (kll_doubles_sketch method)":[[16,"datasketches.kll_doubles_sketch.__init__",false]],"__init__() (kll_floats_sketch method)":[[16,"datasketches.kll_floats_sketch.__init__",false]],"__init__() (kll_ints_sketch method)":[[16,"datasketches.kll_ints_sketch.__init__",false]],"__init__() (kll_items_sketch method)":[[16,"datasketches.kll_items_sketch.__init__",false]],"__init__() (quantiles_doubles_sketch method)":[[17,"datasketches.quantiles_doubles_sketch.__init__",false]],"__init__() (quantiles_floats_sketch method)":[[17,"datasketches.quantiles_floats_sketch.__init__",false]],"__init__() (quantiles_ints_sketch method)":[[17,"datasketches.quantiles_ints_sketch.__init__",false]],"__init__() (quantiles_items_sketch method)":[[17,"datasketches.quantiles_items_sketch.__init__",false]],"__init__() (req_floats_sketch method)":[[18,"datasketches.req_floats_sketch.__init__",false]],"__init__() (req_ints_sketch method)":[[18,"datasketches.req_ints_sketch.__init__",false]],"__init__() (req_items_sketch method)":[[18,"datasketches.req_items_sketch.__init__",false]],"__init__() (tdigest_double method)":[[19,"datasketches.tdigest_double.__init__",false]],"__init__() (tdigest_float method)":[[19,"datasketches.tdigest_float.__init__",false]],"__init__() (theta_a_not_b method)":[[3,"datasketches.theta_a_not_b.__init__",false]],"__init__() (theta_intersection method)":[[3,"datasketches.theta_intersection.__init__",false]],"__init__() (theta_union method)":[[3,"datasketches.theta_union.__init__",false]],"__init__() (tuple_a_not_b method)":[[4,"datasketches.tuple_a_not_b.__init__",false]],"__init__() (tuple_intersection method)":[[4,"datasketches.tuple_intersection.__init__",false]],"__init__() (tuple_union method)":[[4,"datasketches.tuple_union.__init__",false]],"__init__() (update_theta_sketch method)":[[3,"datasketches.update_theta_sketch.__init__",false]],"__init__() (update_tuple_sketch method)":[[4,"datasketches.update_tuple_sketch.__init__",false]],"__init__() (var_opt_sketch method)":[[22,"datasketches.var_opt_sketch.__init__",false]],"__init__() (var_opt_union method)":[[22,"datasketches.var_opt_union.__init__",false]],"accumulatorpolicy (class in datasketches)":[[13,"datasketches.AccumulatorPolicy",false]],"c (ebpps_sketch property)":[[20,"datasketches.ebpps_sketch.c",false]],"compact (update_theta_sketch attribute)":[[3,"datasketches.update_theta_sketch.compact",false]],"compact (update_tuple_sketch attribute)":[[4,"datasketches.update_tuple_sketch.compact",false]],"compact_theta_sketch (class in datasketches)":[[3,"datasketches.compact_theta_sketch",false]],"compact_tuple_sketch (class in datasketches)":[[4,"datasketches.compact_tuple_sketch",false]],"compress (tdigest_double attribute)":[[19,"datasketches.tdigest_double.compress",false]],"compress (tdigest_float attribute)":[[19,"datasketches.tdigest_float.compress",false]],"compute (theta_a_not_b attribute)":[[3,"datasketches.theta_a_not_b.compute",false]],"compute (tuple_a_not_b attribute)":[[4,"datasketches.tuple_a_not_b.compute",false]],"count_min_sketch (class in _datasketches)":[[5,"datasketches.count_min_sketch",false]],"cpc_sketch (class in _datasketches)":[[0,"datasketches.cpc_sketch",false]],"cpc_union (class in _datasketches)":[[0,"datasketches.cpc_union",false]],"create_summary() (tuplepolicy method)":[[13,"datasketches.TuplePolicy.create_summary",false]],"default_seed (tuple_sketch attribute)":[[4,"datasketches.tuple_sketch.DEFAULT_SEED",false]],"density_sketch (class in datasketches)":[[23,"datasketches.density_sketch",false]],"deserialize() (compact_theta_sketch method)":[[3,"datasketches.compact_theta_sketch.deserialize",false]],"deserialize() (compact_tuple_sketch method)":[[4,"datasketches.compact_tuple_sketch.deserialize",false]],"deserialize() (count_min_sketch method)":[[5,"datasketches.count_min_sketch.deserialize",false]],"deserialize() (cpc_sketch method)":[[0,"datasketches.cpc_sketch.deserialize",false]],"deserialize() (density_sketch method)":[[23,"datasketches.density_sketch.deserialize",false]],"deserialize() (ebpps_sketch method)":[[20,"datasketches.ebpps_sketch.deserialize",false]],"deserialize() (frequent_items_sketch method)":[[6,"datasketches.frequent_items_sketch.deserialize",false]],"deserialize() (frequent_strings_sketch method)":[[6,"datasketches.frequent_strings_sketch.deserialize",false]],"deserialize() (hll_sketch method)":[[1,"datasketches.hll_sketch.deserialize",false]],"deserialize() (kll_doubles_sketch method)":[[16,"datasketches.kll_doubles_sketch.deserialize",false]],"deserialize() (kll_floats_sketch method)":[[16,"datasketches.kll_floats_sketch.deserialize",false]],"deserialize() (kll_ints_sketch method)":[[16,"datasketches.kll_ints_sketch.deserialize",false]],"deserialize() (kll_items_sketch method)":[[16,"datasketches.kll_items_sketch.deserialize",false]],"deserialize() (quantiles_doubles_sketch method)":[[17,"datasketches.quantiles_doubles_sketch.deserialize",false]],"deserialize() (quantiles_floats_sketch method)":[[17,"datasketches.quantiles_floats_sketch.deserialize",false]],"deserialize() (quantiles_ints_sketch method)":[[17,"datasketches.quantiles_ints_sketch.deserialize",false]],"deserialize() (quantiles_items_sketch method)":[[17,"datasketches.quantiles_items_sketch.deserialize",false]],"deserialize() (req_floats_sketch method)":[[18,"datasketches.req_floats_sketch.deserialize",false]],"deserialize() (req_ints_sketch method)":[[18,"datasketches.req_ints_sketch.deserialize",false]],"deserialize() (req_items_sketch method)":[[18,"datasketches.req_items_sketch.deserialize",false]],"deserialize() (tdigest_double method)":[[19,"datasketches.tdigest_double.deserialize",false]],"deserialize() (tdigest_float method)":[[19,"datasketches.tdigest_float.deserialize",false]],"deserialize() (var_opt_sketch method)":[[22,"datasketches.var_opt_sketch.deserialize",false]],"deserialize() (var_opt_union method)":[[22,"datasketches.var_opt_union.deserialize",false]],"dim (density_sketch property)":[[23,"datasketches.density_sketch.dim",false]],"dissimilarity_test() (theta_jaccard_similarity method)":[[9,"datasketches.theta_jaccard_similarity.dissimilarity_test",false]],"dissimilarity_test() (tuple_jaccard_similarity method)":[[9,"datasketches.tuple_jaccard_similarity.dissimilarity_test",false]],"ebpps_sketch (class in datasketches)":[[20,"datasketches.ebpps_sketch",false]],"epsilon (frequent_items_sketch property)":[[6,"datasketches.frequent_items_sketch.epsilon",false]],"epsilon (frequent_strings_sketch property)":[[6,"datasketches.frequent_strings_sketch.epsilon",false]],"estimate_subset_sum (var_opt_sketch attribute)":[[22,"datasketches.var_opt_sketch.estimate_subset_sum",false]],"exactly_equal() (theta_jaccard_similarity method)":[[9,"datasketches.theta_jaccard_similarity.exactly_equal",false]],"exactly_equal() (tuple_jaccard_similarity method)":[[9,"datasketches.tuple_jaccard_similarity.exactly_equal",false]],"filter (compact_tuple_sketch attribute)":[[4,"datasketches.compact_tuple_sketch.filter",false]],"filter (update_tuple_sketch attribute)":[[4,"datasketches.update_tuple_sketch.filter",false]],"frequent_items_error_type (class in datasketches)":[[6,"datasketches.frequent_items_error_type",false]],"frequent_items_sketch (class in datasketches)":[[6,"datasketches.frequent_items_sketch",false]],"frequent_strings_sketch (class in datasketches)":[[6,"datasketches.frequent_strings_sketch",false]],"from_bytes() (pyobjectserde method)":[[12,"datasketches.PyObjectSerDe.from_bytes",false]],"gaussiankernel (class in datasketches)":[[10,"datasketches.GaussianKernel",false]],"get_apriori_error() (frequent_items_sketch method)":[[6,"datasketches.frequent_items_sketch.get_apriori_error",false]],"get_apriori_error() (frequent_strings_sketch method)":[[6,"datasketches.frequent_strings_sketch.get_apriori_error",false]],"get_cdf (kll_doubles_sketch attribute)":[[16,"datasketches.kll_doubles_sketch.get_cdf",false]],"get_cdf (kll_floats_sketch attribute)":[[16,"datasketches.kll_floats_sketch.get_cdf",false]],"get_cdf (kll_ints_sketch attribute)":[[16,"datasketches.kll_ints_sketch.get_cdf",false]],"get_cdf (kll_items_sketch attribute)":[[16,"datasketches.kll_items_sketch.get_cdf",false]],"get_cdf (quantiles_doubles_sketch attribute)":[[17,"datasketches.quantiles_doubles_sketch.get_cdf",false]],"get_cdf (quantiles_floats_sketch attribute)":[[17,"datasketches.quantiles_floats_sketch.get_cdf",false]],"get_cdf (quantiles_ints_sketch attribute)":[[17,"datasketches.quantiles_ints_sketch.get_cdf",false]],"get_cdf (quantiles_items_sketch attribute)":[[17,"datasketches.quantiles_items_sketch.get_cdf",false]],"get_cdf (req_floats_sketch attribute)":[[18,"datasketches.req_floats_sketch.get_cdf",false]],"get_cdf (req_ints_sketch attribute)":[[18,"datasketches.req_ints_sketch.get_cdf",false]],"get_cdf (req_items_sketch attribute)":[[18,"datasketches.req_items_sketch.get_cdf",false]],"get_cdf (tdigest_double attribute)":[[19,"datasketches.tdigest_double.get_cdf",false]],"get_cdf (tdigest_float attribute)":[[19,"datasketches.tdigest_float.get_cdf",false]],"get_compact_serialization_bytes (hll_sketch attribute)":[[1,"datasketches.hll_sketch.get_compact_serialization_bytes",false]],"get_epsilon_for_lg_size() (frequent_items_sketch method)":[[6,"datasketches.frequent_items_sketch.get_epsilon_for_lg_size",false]],"get_epsilon_for_lg_size() (frequent_strings_sketch method)":[[6,"datasketches.frequent_strings_sketch.get_epsilon_for_lg_size",false]],"get_estimate (count_min_sketch attribute)":[[5,"datasketches.count_min_sketch.get_estimate",false]],"get_estimate (cpc_sketch attribute)":[[0,"datasketches.cpc_sketch.get_estimate",false]],"get_estimate (density_sketch attribute)":[[23,"datasketches.density_sketch.get_estimate",false]],"get_estimate (frequent_items_sketch attribute)":[[6,"datasketches.frequent_items_sketch.get_estimate",false]],"get_estimate (frequent_strings_sketch attribute)":[[6,"datasketches.frequent_strings_sketch.get_estimate",false]],"get_estimate (hll_sketch attribute)":[[1,"datasketches.hll_sketch.get_estimate",false]],"get_estimate (hll_union attribute)":[[1,"datasketches.hll_union.get_estimate",false]],"get_estimate (theta_sketch attribute)":[[3,"datasketches.theta_sketch.get_estimate",false]],"get_estimate (tuple_sketch attribute)":[[4,"datasketches.tuple_sketch.get_estimate",false]],"get_frequent_items (frequent_items_sketch attribute)":[[6,"datasketches.frequent_items_sketch.get_frequent_items",false]],"get_frequent_items (frequent_strings_sketch attribute)":[[6,"datasketches.frequent_strings_sketch.get_frequent_items",false]],"get_lower_bound (count_min_sketch attribute)":[[5,"datasketches.count_min_sketch.get_lower_bound",false]],"get_lower_bound (cpc_sketch attribute)":[[0,"datasketches.cpc_sketch.get_lower_bound",false]],"get_lower_bound (frequent_items_sketch attribute)":[[6,"datasketches.frequent_items_sketch.get_lower_bound",false]],"get_lower_bound (frequent_strings_sketch attribute)":[[6,"datasketches.frequent_strings_sketch.get_lower_bound",false]],"get_lower_bound (hll_sketch attribute)":[[1,"datasketches.hll_sketch.get_lower_bound",false]],"get_lower_bound (hll_union attribute)":[[1,"datasketches.hll_union.get_lower_bound",false]],"get_lower_bound (theta_sketch attribute)":[[3,"datasketches.theta_sketch.get_lower_bound",false]],"get_lower_bound (tuple_sketch attribute)":[[4,"datasketches.tuple_sketch.get_lower_bound",false]],"get_max_updatable_serialization_bytes() (hll_sketch method)":[[1,"datasketches.hll_sketch.get_max_updatable_serialization_bytes",false]],"get_max_value (kll_doubles_sketch attribute)":[[16,"datasketches.kll_doubles_sketch.get_max_value",false]],"get_max_value (kll_floats_sketch attribute)":[[16,"datasketches.kll_floats_sketch.get_max_value",false]],"get_max_value (kll_ints_sketch attribute)":[[16,"datasketches.kll_ints_sketch.get_max_value",false]],"get_max_value (kll_items_sketch attribute)":[[16,"datasketches.kll_items_sketch.get_max_value",false]],"get_max_value (quantiles_doubles_sketch attribute)":[[17,"datasketches.quantiles_doubles_sketch.get_max_value",false]],"get_max_value (quantiles_floats_sketch attribute)":[[17,"datasketches.quantiles_floats_sketch.get_max_value",false]],"get_max_value (quantiles_ints_sketch attribute)":[[17,"datasketches.quantiles_ints_sketch.get_max_value",false]],"get_max_value (quantiles_items_sketch attribute)":[[17,"datasketches.quantiles_items_sketch.get_max_value",false]],"get_max_value (req_floats_sketch attribute)":[[18,"datasketches.req_floats_sketch.get_max_value",false]],"get_max_value (req_ints_sketch attribute)":[[18,"datasketches.req_ints_sketch.get_max_value",false]],"get_max_value (req_items_sketch attribute)":[[18,"datasketches.req_items_sketch.get_max_value",false]],"get_max_value (tdigest_double attribute)":[[19,"datasketches.tdigest_double.get_max_value",false]],"get_max_value (tdigest_float attribute)":[[19,"datasketches.tdigest_float.get_max_value",false]],"get_min_value (kll_doubles_sketch attribute)":[[16,"datasketches.kll_doubles_sketch.get_min_value",false]],"get_min_value (kll_floats_sketch attribute)":[[16,"datasketches.kll_floats_sketch.get_min_value",false]],"get_min_value (kll_ints_sketch attribute)":[[16,"datasketches.kll_ints_sketch.get_min_value",false]],"get_min_value (kll_items_sketch attribute)":[[16,"datasketches.kll_items_sketch.get_min_value",false]],"get_min_value (quantiles_doubles_sketch attribute)":[[17,"datasketches.quantiles_doubles_sketch.get_min_value",false]],"get_min_value (quantiles_floats_sketch attribute)":[[17,"datasketches.quantiles_floats_sketch.get_min_value",false]],"get_min_value (quantiles_ints_sketch attribute)":[[17,"datasketches.quantiles_ints_sketch.get_min_value",false]],"get_min_value (quantiles_items_sketch attribute)":[[17,"datasketches.quantiles_items_sketch.get_min_value",false]],"get_min_value (req_floats_sketch attribute)":[[18,"datasketches.req_floats_sketch.get_min_value",false]],"get_min_value (req_ints_sketch attribute)":[[18,"datasketches.req_ints_sketch.get_min_value",false]],"get_min_value (req_items_sketch attribute)":[[18,"datasketches.req_items_sketch.get_min_value",false]],"get_min_value (tdigest_double attribute)":[[19,"datasketches.tdigest_double.get_min_value",false]],"get_min_value (tdigest_float attribute)":[[19,"datasketches.tdigest_float.get_min_value",false]],"get_normalized_rank_error() (kll_doubles_sketch method)":[[16,"datasketches.kll_doubles_sketch.get_normalized_rank_error",false]],"get_normalized_rank_error() (kll_floats_sketch method)":[[16,"datasketches.kll_floats_sketch.get_normalized_rank_error",false]],"get_normalized_rank_error() (kll_ints_sketch method)":[[16,"datasketches.kll_ints_sketch.get_normalized_rank_error",false]],"get_normalized_rank_error() (kll_items_sketch method)":[[16,"datasketches.kll_items_sketch.get_normalized_rank_error",false]],"get_normalized_rank_error() (quantiles_doubles_sketch method)":[[17,"datasketches.quantiles_doubles_sketch.get_normalized_rank_error",false]],"get_normalized_rank_error() (quantiles_floats_sketch method)":[[17,"datasketches.quantiles_floats_sketch.get_normalized_rank_error",false]],"get_normalized_rank_error() (quantiles_ints_sketch method)":[[17,"datasketches.quantiles_ints_sketch.get_normalized_rank_error",false]],"get_normalized_rank_error() (quantiles_items_sketch method)":[[17,"datasketches.quantiles_items_sketch.get_normalized_rank_error",false]],"get_pmf (kll_doubles_sketch attribute)":[[16,"datasketches.kll_doubles_sketch.get_pmf",false]],"get_pmf (kll_floats_sketch attribute)":[[16,"datasketches.kll_floats_sketch.get_pmf",false]],"get_pmf (kll_ints_sketch attribute)":[[16,"datasketches.kll_ints_sketch.get_pmf",false]],"get_pmf (kll_items_sketch attribute)":[[16,"datasketches.kll_items_sketch.get_pmf",false]],"get_pmf (quantiles_doubles_sketch attribute)":[[17,"datasketches.quantiles_doubles_sketch.get_pmf",false]],"get_pmf (quantiles_floats_sketch attribute)":[[17,"datasketches.quantiles_floats_sketch.get_pmf",false]],"get_pmf (quantiles_ints_sketch attribute)":[[17,"datasketches.quantiles_ints_sketch.get_pmf",false]],"get_pmf (quantiles_items_sketch attribute)":[[17,"datasketches.quantiles_items_sketch.get_pmf",false]],"get_pmf (req_floats_sketch attribute)":[[18,"datasketches.req_floats_sketch.get_pmf",false]],"get_pmf (req_ints_sketch attribute)":[[18,"datasketches.req_ints_sketch.get_pmf",false]],"get_pmf (req_items_sketch attribute)":[[18,"datasketches.req_items_sketch.get_pmf",false]],"get_pmf (tdigest_double attribute)":[[19,"datasketches.tdigest_double.get_pmf",false]],"get_pmf (tdigest_float attribute)":[[19,"datasketches.tdigest_float.get_pmf",false]],"get_quantile (kll_doubles_sketch attribute)":[[16,"datasketches.kll_doubles_sketch.get_quantile",false]],"get_quantile (kll_floats_sketch attribute)":[[16,"datasketches.kll_floats_sketch.get_quantile",false]],"get_quantile (kll_ints_sketch attribute)":[[16,"datasketches.kll_ints_sketch.get_quantile",false]],"get_quantile (kll_items_sketch attribute)":[[16,"datasketches.kll_items_sketch.get_quantile",false]],"get_quantile (quantiles_doubles_sketch attribute)":[[17,"datasketches.quantiles_doubles_sketch.get_quantile",false]],"get_quantile (quantiles_floats_sketch attribute)":[[17,"datasketches.quantiles_floats_sketch.get_quantile",false]],"get_quantile (quantiles_ints_sketch attribute)":[[17,"datasketches.quantiles_ints_sketch.get_quantile",false]],"get_quantile (quantiles_items_sketch attribute)":[[17,"datasketches.quantiles_items_sketch.get_quantile",false]],"get_quantile (req_floats_sketch attribute)":[[18,"datasketches.req_floats_sketch.get_quantile",false]],"get_quantile (req_ints_sketch attribute)":[[18,"datasketches.req_ints_sketch.get_quantile",false]],"get_quantile (req_items_sketch attribute)":[[18,"datasketches.req_items_sketch.get_quantile",false]],"get_quantile (tdigest_double attribute)":[[19,"datasketches.tdigest_double.get_quantile",false]],"get_quantile (tdigest_float attribute)":[[19,"datasketches.tdigest_float.get_quantile",false]],"get_quantiles (kll_doubles_sketch attribute)":[[16,"datasketches.kll_doubles_sketch.get_quantiles",false]],"get_quantiles (kll_floats_sketch attribute)":[[16,"datasketches.kll_floats_sketch.get_quantiles",false]],"get_quantiles (kll_ints_sketch attribute)":[[16,"datasketches.kll_ints_sketch.get_quantiles",false]],"get_quantiles (kll_items_sketch attribute)":[[16,"datasketches.kll_items_sketch.get_quantiles",false]],"get_quantiles (quantiles_doubles_sketch attribute)":[[17,"datasketches.quantiles_doubles_sketch.get_quantiles",false]],"get_quantiles (quantiles_floats_sketch attribute)":[[17,"datasketches.quantiles_floats_sketch.get_quantiles",false]],"get_quantiles (quantiles_ints_sketch attribute)":[[17,"datasketches.quantiles_ints_sketch.get_quantiles",false]],"get_quantiles (quantiles_items_sketch attribute)":[[17,"datasketches.quantiles_items_sketch.get_quantiles",false]],"get_quantiles (req_floats_sketch attribute)":[[18,"datasketches.req_floats_sketch.get_quantiles",false]],"get_quantiles (req_ints_sketch attribute)":[[18,"datasketches.req_ints_sketch.get_quantiles",false]],"get_quantiles (req_items_sketch attribute)":[[18,"datasketches.req_items_sketch.get_quantiles",false]],"get_rank (kll_doubles_sketch attribute)":[[16,"datasketches.kll_doubles_sketch.get_rank",false]],"get_rank (kll_floats_sketch attribute)":[[16,"datasketches.kll_floats_sketch.get_rank",false]],"get_rank (kll_ints_sketch attribute)":[[16,"datasketches.kll_ints_sketch.get_rank",false]],"get_rank (kll_items_sketch attribute)":[[16,"datasketches.kll_items_sketch.get_rank",false]],"get_rank (quantiles_doubles_sketch attribute)":[[17,"datasketches.quantiles_doubles_sketch.get_rank",false]],"get_rank (quantiles_floats_sketch attribute)":[[17,"datasketches.quantiles_floats_sketch.get_rank",false]],"get_rank (quantiles_ints_sketch attribute)":[[17,"datasketches.quantiles_ints_sketch.get_rank",false]],"get_rank (quantiles_items_sketch attribute)":[[17,"datasketches.quantiles_items_sketch.get_rank",false]],"get_rank (req_floats_sketch attribute)":[[18,"datasketches.req_floats_sketch.get_rank",false]],"get_rank (req_ints_sketch attribute)":[[18,"datasketches.req_ints_sketch.get_rank",false]],"get_rank (req_items_sketch attribute)":[[18,"datasketches.req_items_sketch.get_rank",false]],"get_rank (tdigest_double attribute)":[[19,"datasketches.tdigest_double.get_rank",false]],"get_rank (tdigest_float attribute)":[[19,"datasketches.tdigest_float.get_rank",false]],"get_rank_lower_bound (req_floats_sketch attribute)":[[18,"datasketches.req_floats_sketch.get_rank_lower_bound",false]],"get_rank_lower_bound (req_ints_sketch attribute)":[[18,"datasketches.req_ints_sketch.get_rank_lower_bound",false]],"get_rank_lower_bound (req_items_sketch attribute)":[[18,"datasketches.req_items_sketch.get_rank_lower_bound",false]],"get_rank_upper_bound (req_floats_sketch attribute)":[[18,"datasketches.req_floats_sketch.get_rank_upper_bound",false]],"get_rank_upper_bound (req_ints_sketch attribute)":[[18,"datasketches.req_ints_sketch.get_rank_upper_bound",false]],"get_rank_upper_bound (req_items_sketch attribute)":[[18,"datasketches.req_items_sketch.get_rank_upper_bound",false]],"get_rel_err() (hll_sketch method)":[[1,"datasketches.hll_sketch.get_rel_err",false]],"get_rel_err() (hll_union method)":[[1,"datasketches.hll_union.get_rel_err",false]],"get_relative_error (count_min_sketch attribute)":[[5,"datasketches.count_min_sketch.get_relative_error",false]],"get_result (cpc_union attribute)":[[0,"datasketches.cpc_union.get_result",false]],"get_result (hll_union attribute)":[[1,"datasketches.hll_union.get_result",false]],"get_result (theta_intersection attribute)":[[3,"datasketches.theta_intersection.get_result",false]],"get_result (theta_union attribute)":[[3,"datasketches.theta_union.get_result",false]],"get_result (tuple_intersection attribute)":[[4,"datasketches.tuple_intersection.get_result",false]],"get_result (tuple_union attribute)":[[4,"datasketches.tuple_union.get_result",false]],"get_result (var_opt_union attribute)":[[22,"datasketches.var_opt_union.get_result",false]],"get_rse() (req_floats_sketch method)":[[18,"datasketches.req_floats_sketch.get_RSE",false]],"get_rse() (req_ints_sketch method)":[[18,"datasketches.req_ints_sketch.get_RSE",false]],"get_rse() (req_items_sketch method)":[[18,"datasketches.req_items_sketch.get_RSE",false]],"get_seed_hash (theta_sketch attribute)":[[3,"datasketches.theta_sketch.get_seed_hash",false]],"get_seed_hash (tuple_sketch attribute)":[[4,"datasketches.tuple_sketch.get_seed_hash",false]],"get_serialized_size_bytes (count_min_sketch attribute)":[[5,"datasketches.count_min_sketch.get_serialized_size_bytes",false]],"get_serialized_size_bytes (ebpps_sketch attribute)":[[20,"datasketches.ebpps_sketch.get_serialized_size_bytes",false]],"get_serialized_size_bytes (frequent_items_sketch attribute)":[[6,"datasketches.frequent_items_sketch.get_serialized_size_bytes",false]],"get_serialized_size_bytes (frequent_strings_sketch attribute)":[[6,"datasketches.frequent_strings_sketch.get_serialized_size_bytes",false]],"get_serialized_size_bytes (tdigest_double attribute)":[[19,"datasketches.tdigest_double.get_serialized_size_bytes",false]],"get_serialized_size_bytes (tdigest_float attribute)":[[19,"datasketches.tdigest_float.get_serialized_size_bytes",false]],"get_serialized_size_bytes (var_opt_sketch attribute)":[[22,"datasketches.var_opt_sketch.get_serialized_size_bytes",false]],"get_serialized_size_bytes (var_opt_union attribute)":[[22,"datasketches.var_opt_union.get_serialized_size_bytes",false]],"get_size() (pyobjectserde method)":[[12,"datasketches.PyObjectSerDe.get_size",false]],"get_total_weight (tdigest_double attribute)":[[19,"datasketches.tdigest_double.get_total_weight",false]],"get_total_weight (tdigest_float attribute)":[[19,"datasketches.tdigest_float.get_total_weight",false]],"get_updatable_serialization_bytes (hll_sketch attribute)":[[1,"datasketches.hll_sketch.get_updatable_serialization_bytes",false]],"get_upper_bound (count_min_sketch attribute)":[[5,"datasketches.count_min_sketch.get_upper_bound",false]],"get_upper_bound (cpc_sketch attribute)":[[0,"datasketches.cpc_sketch.get_upper_bound",false]],"get_upper_bound (frequent_items_sketch attribute)":[[6,"datasketches.frequent_items_sketch.get_upper_bound",false]],"get_upper_bound (frequent_strings_sketch attribute)":[[6,"datasketches.frequent_strings_sketch.get_upper_bound",false]],"get_upper_bound (hll_sketch attribute)":[[1,"datasketches.hll_sketch.get_upper_bound",false]],"get_upper_bound (hll_union attribute)":[[1,"datasketches.hll_union.get_upper_bound",false]],"get_upper_bound (theta_sketch attribute)":[[3,"datasketches.theta_sketch.get_upper_bound",false]],"get_upper_bound (tuple_sketch attribute)":[[4,"datasketches.tuple_sketch.get_upper_bound",false]],"has_result (theta_intersection attribute)":[[3,"datasketches.theta_intersection.has_result",false]],"has_result (tuple_intersection attribute)":[[4,"datasketches.tuple_intersection.has_result",false]],"hll_4 (tgt_hll_type attribute)":[[1,"datasketches.tgt_hll_type.HLL_4",false]],"hll_6 (tgt_hll_type attribute)":[[1,"datasketches.tgt_hll_type.HLL_6",false]],"hll_8 (tgt_hll_type attribute)":[[1,"datasketches.tgt_hll_type.HLL_8",false]],"hll_sketch (class in _datasketches)":[[1,"datasketches.hll_sketch",false]],"hll_union (class in _datasketches)":[[1,"datasketches.hll_union",false]],"is_compact (hll_sketch attribute)":[[1,"datasketches.hll_sketch.is_compact",false]],"is_empty (count_min_sketch attribute)":[[5,"datasketches.count_min_sketch.is_empty",false]],"is_empty (cpc_sketch attribute)":[[0,"datasketches.cpc_sketch.is_empty",false]],"is_empty (density_sketch attribute)":[[23,"datasketches.density_sketch.is_empty",false]],"is_empty (ebpps_sketch attribute)":[[20,"datasketches.ebpps_sketch.is_empty",false]],"is_empty (frequent_items_sketch attribute)":[[6,"datasketches.frequent_items_sketch.is_empty",false]],"is_empty (frequent_strings_sketch attribute)":[[6,"datasketches.frequent_strings_sketch.is_empty",false]],"is_empty (hll_sketch attribute)":[[1,"datasketches.hll_sketch.is_empty",false]],"is_empty (hll_union attribute)":[[1,"datasketches.hll_union.is_empty",false]],"is_empty (kll_doubles_sketch attribute)":[[16,"datasketches.kll_doubles_sketch.is_empty",false]],"is_empty (kll_floats_sketch attribute)":[[16,"datasketches.kll_floats_sketch.is_empty",false]],"is_empty (kll_ints_sketch attribute)":[[16,"datasketches.kll_ints_sketch.is_empty",false]],"is_empty (kll_items_sketch attribute)":[[16,"datasketches.kll_items_sketch.is_empty",false]],"is_empty (quantiles_doubles_sketch attribute)":[[17,"datasketches.quantiles_doubles_sketch.is_empty",false]],"is_empty (quantiles_floats_sketch attribute)":[[17,"datasketches.quantiles_floats_sketch.is_empty",false]],"is_empty (quantiles_ints_sketch attribute)":[[17,"datasketches.quantiles_ints_sketch.is_empty",false]],"is_empty (quantiles_items_sketch attribute)":[[17,"datasketches.quantiles_items_sketch.is_empty",false]],"is_empty (req_floats_sketch attribute)":[[18,"datasketches.req_floats_sketch.is_empty",false]],"is_empty (req_ints_sketch attribute)":[[18,"datasketches.req_ints_sketch.is_empty",false]],"is_empty (req_items_sketch attribute)":[[18,"datasketches.req_items_sketch.is_empty",false]],"is_empty (tdigest_double attribute)":[[19,"datasketches.tdigest_double.is_empty",false]],"is_empty (tdigest_float attribute)":[[19,"datasketches.tdigest_float.is_empty",false]],"is_empty (theta_sketch attribute)":[[3,"datasketches.theta_sketch.is_empty",false]],"is_empty (tuple_sketch attribute)":[[4,"datasketches.tuple_sketch.is_empty",false]],"is_empty (var_opt_sketch attribute)":[[22,"datasketches.var_opt_sketch.is_empty",false]],"is_estimation_mode (density_sketch attribute)":[[23,"datasketches.density_sketch.is_estimation_mode",false]],"is_estimation_mode (kll_doubles_sketch attribute)":[[16,"datasketches.kll_doubles_sketch.is_estimation_mode",false]],"is_estimation_mode (kll_floats_sketch attribute)":[[16,"datasketches.kll_floats_sketch.is_estimation_mode",false]],"is_estimation_mode (kll_ints_sketch attribute)":[[16,"datasketches.kll_ints_sketch.is_estimation_mode",false]],"is_estimation_mode (kll_items_sketch attribute)":[[16,"datasketches.kll_items_sketch.is_estimation_mode",false]],"is_estimation_mode (quantiles_doubles_sketch attribute)":[[17,"datasketches.quantiles_doubles_sketch.is_estimation_mode",false]],"is_estimation_mode (quantiles_floats_sketch attribute)":[[17,"datasketches.quantiles_floats_sketch.is_estimation_mode",false]],"is_estimation_mode (quantiles_ints_sketch attribute)":[[17,"datasketches.quantiles_ints_sketch.is_estimation_mode",false]],"is_estimation_mode (quantiles_items_sketch attribute)":[[17,"datasketches.quantiles_items_sketch.is_estimation_mode",false]],"is_estimation_mode (req_floats_sketch attribute)":[[18,"datasketches.req_floats_sketch.is_estimation_mode",false]],"is_estimation_mode (req_ints_sketch attribute)":[[18,"datasketches.req_ints_sketch.is_estimation_mode",false]],"is_estimation_mode (req_items_sketch attribute)":[[18,"datasketches.req_items_sketch.is_estimation_mode",false]],"is_estimation_mode (theta_sketch attribute)":[[3,"datasketches.theta_sketch.is_estimation_mode",false]],"is_estimation_mode (tuple_sketch attribute)":[[4,"datasketches.tuple_sketch.is_estimation_mode",false]],"is_hra (req_floats_sketch attribute)":[[18,"datasketches.req_floats_sketch.is_hra",false]],"is_hra (req_ints_sketch attribute)":[[18,"datasketches.req_ints_sketch.is_hra",false]],"is_hra (req_items_sketch attribute)":[[18,"datasketches.req_items_sketch.is_hra",false]],"is_ordered (theta_sketch attribute)":[[3,"datasketches.theta_sketch.is_ordered",false]],"is_ordered (tuple_sketch attribute)":[[4,"datasketches.tuple_sketch.is_ordered",false]],"jaccard() (theta_jaccard_similarity method)":[[9,"datasketches.theta_jaccard_similarity.jaccard",false]],"jaccard() (tuple_jaccard_similarity method)":[[9,"datasketches.tuple_jaccard_similarity.jaccard",false]],"k (density_sketch property)":[[23,"datasketches.density_sketch.k",false]],"k (ebpps_sketch property)":[[20,"datasketches.ebpps_sketch.k",false]],"k (kll_doubles_sketch property)":[[16,"datasketches.kll_doubles_sketch.k",false]],"k (kll_floats_sketch property)":[[16,"datasketches.kll_floats_sketch.k",false]],"k (kll_ints_sketch property)":[[16,"datasketches.kll_ints_sketch.k",false]],"k (kll_items_sketch property)":[[16,"datasketches.kll_items_sketch.k",false]],"k (quantiles_doubles_sketch property)":[[17,"datasketches.quantiles_doubles_sketch.k",false]],"k (quantiles_floats_sketch property)":[[17,"datasketches.quantiles_floats_sketch.k",false]],"k (quantiles_ints_sketch property)":[[17,"datasketches.quantiles_ints_sketch.k",false]],"k (quantiles_items_sketch property)":[[17,"datasketches.quantiles_items_sketch.k",false]],"k (req_floats_sketch property)":[[18,"datasketches.req_floats_sketch.k",false]],"k (req_ints_sketch property)":[[18,"datasketches.req_ints_sketch.k",false]],"k (req_items_sketch property)":[[18,"datasketches.req_items_sketch.k",false]],"k (tdigest_double property)":[[19,"datasketches.tdigest_double.k",false]],"k (tdigest_float property)":[[19,"datasketches.tdigest_float.k",false]],"k (var_opt_sketch property)":[[22,"datasketches.var_opt_sketch.k",false]],"kernelfunction (class in datasketches)":[[10,"datasketches.KernelFunction",false]],"kll_doubles_sketch (class in datasketches)":[[16,"datasketches.kll_doubles_sketch",false]],"kll_floats_sketch (class in datasketches)":[[16,"datasketches.kll_floats_sketch",false]],"kll_ints_sketch (class in datasketches)":[[16,"datasketches.kll_ints_sketch",false]],"kll_items_sketch (class in datasketches)":[[16,"datasketches.kll_items_sketch",false]],"ks_test() (in module datasketches)":[[11,"datasketches.ks_test",false]],"lg_config_k (hll_sketch property)":[[1,"datasketches.hll_sketch.lg_config_k",false]],"lg_config_k (hll_union property)":[[1,"datasketches.hll_union.lg_config_k",false]],"lg_k (cpc_sketch property)":[[0,"datasketches.cpc_sketch.lg_k",false]],"maxintpolicy (class in datasketches)":[[13,"datasketches.MaxIntPolicy",false]],"merge (count_min_sketch attribute)":[[5,"datasketches.count_min_sketch.merge",false]],"merge (density_sketch attribute)":[[23,"datasketches.density_sketch.merge",false]],"merge (ebpps_sketch attribute)":[[20,"datasketches.ebpps_sketch.merge",false]],"merge (frequent_items_sketch attribute)":[[6,"datasketches.frequent_items_sketch.merge",false]],"merge (frequent_strings_sketch attribute)":[[6,"datasketches.frequent_strings_sketch.merge",false]],"merge (kll_doubles_sketch attribute)":[[16,"datasketches.kll_doubles_sketch.merge",false]],"merge (kll_floats_sketch attribute)":[[16,"datasketches.kll_floats_sketch.merge",false]],"merge (kll_ints_sketch attribute)":[[16,"datasketches.kll_ints_sketch.merge",false]],"merge (kll_items_sketch attribute)":[[16,"datasketches.kll_items_sketch.merge",false]],"merge (quantiles_doubles_sketch attribute)":[[17,"datasketches.quantiles_doubles_sketch.merge",false]],"merge (quantiles_floats_sketch attribute)":[[17,"datasketches.quantiles_floats_sketch.merge",false]],"merge (quantiles_ints_sketch attribute)":[[17,"datasketches.quantiles_ints_sketch.merge",false]],"merge (quantiles_items_sketch attribute)":[[17,"datasketches.quantiles_items_sketch.merge",false]],"merge (req_floats_sketch attribute)":[[18,"datasketches.req_floats_sketch.merge",false]],"merge (req_ints_sketch attribute)":[[18,"datasketches.req_ints_sketch.merge",false]],"merge (req_items_sketch attribute)":[[18,"datasketches.req_items_sketch.merge",false]],"merge (tdigest_double attribute)":[[19,"datasketches.tdigest_double.merge",false]],"merge (tdigest_float attribute)":[[19,"datasketches.tdigest_float.merge",false]],"minintpolicy (class in datasketches)":[[13,"datasketches.MinIntPolicy",false]],"n (density_sketch property)":[[23,"datasketches.density_sketch.n",false]],"n (ebpps_sketch property)":[[20,"datasketches.ebpps_sketch.n",false]],"n (kll_doubles_sketch property)":[[16,"datasketches.kll_doubles_sketch.n",false]],"n (kll_floats_sketch property)":[[16,"datasketches.kll_floats_sketch.n",false]],"n (kll_ints_sketch property)":[[16,"datasketches.kll_ints_sketch.n",false]],"n (kll_items_sketch property)":[[16,"datasketches.kll_items_sketch.n",false]],"n (quantiles_doubles_sketch property)":[[17,"datasketches.quantiles_doubles_sketch.n",false]],"n (quantiles_floats_sketch property)":[[17,"datasketches.quantiles_floats_sketch.n",false]],"n (quantiles_ints_sketch property)":[[17,"datasketches.quantiles_ints_sketch.n",false]],"n (quantiles_items_sketch property)":[[17,"datasketches.quantiles_items_sketch.n",false]],"n (req_floats_sketch property)":[[18,"datasketches.req_floats_sketch.n",false]],"n (req_ints_sketch property)":[[18,"datasketches.req_ints_sketch.n",false]],"n (req_items_sketch property)":[[18,"datasketches.req_items_sketch.n",false]],"n (var_opt_sketch property)":[[22,"datasketches.var_opt_sketch.n",false]],"no_false_negatives (frequent_items_error_type attribute)":[[6,"datasketches.frequent_items_error_type.NO_FALSE_NEGATIVES",false]],"no_false_positives (frequent_items_error_type attribute)":[[6,"datasketches.frequent_items_error_type.NO_FALSE_POSITIVES",false]],"normalized_rank_error (kll_doubles_sketch attribute)":[[16,"datasketches.kll_doubles_sketch.normalized_rank_error",false]],"normalized_rank_error (kll_floats_sketch attribute)":[[16,"datasketches.kll_floats_sketch.normalized_rank_error",false]],"normalized_rank_error (kll_ints_sketch attribute)":[[16,"datasketches.kll_ints_sketch.normalized_rank_error",false]],"normalized_rank_error (kll_items_sketch attribute)":[[16,"datasketches.kll_items_sketch.normalized_rank_error",false]],"normalized_rank_error (quantiles_doubles_sketch attribute)":[[17,"datasketches.quantiles_doubles_sketch.normalized_rank_error",false]],"normalized_rank_error (quantiles_floats_sketch attribute)":[[17,"datasketches.quantiles_floats_sketch.normalized_rank_error",false]],"normalized_rank_error (quantiles_ints_sketch attribute)":[[17,"datasketches.quantiles_ints_sketch.normalized_rank_error",false]],"normalized_rank_error (quantiles_items_sketch attribute)":[[17,"datasketches.quantiles_items_sketch.normalized_rank_error",false]],"num_active_items (frequent_items_sketch property)":[[6,"datasketches.frequent_items_sketch.num_active_items",false]],"num_active_items (frequent_strings_sketch property)":[[6,"datasketches.frequent_strings_sketch.num_active_items",false]],"num_buckets (count_min_sketch property)":[[5,"datasketches.count_min_sketch.num_buckets",false]],"num_hashes (count_min_sketch property)":[[5,"datasketches.count_min_sketch.num_hashes",false]],"num_retained (density_sketch property)":[[23,"datasketches.density_sketch.num_retained",false]],"num_retained (kll_doubles_sketch property)":[[16,"datasketches.kll_doubles_sketch.num_retained",false]],"num_retained (kll_floats_sketch property)":[[16,"datasketches.kll_floats_sketch.num_retained",false]],"num_retained (kll_ints_sketch property)":[[16,"datasketches.kll_ints_sketch.num_retained",false]],"num_retained (kll_items_sketch property)":[[16,"datasketches.kll_items_sketch.num_retained",false]],"num_retained (quantiles_doubles_sketch property)":[[17,"datasketches.quantiles_doubles_sketch.num_retained",false]],"num_retained (quantiles_floats_sketch property)":[[17,"datasketches.quantiles_floats_sketch.num_retained",false]],"num_retained (quantiles_ints_sketch property)":[[17,"datasketches.quantiles_ints_sketch.num_retained",false]],"num_retained (quantiles_items_sketch property)":[[17,"datasketches.quantiles_items_sketch.num_retained",false]],"num_retained (req_floats_sketch property)":[[18,"datasketches.req_floats_sketch.num_retained",false]],"num_retained (req_ints_sketch property)":[[18,"datasketches.req_ints_sketch.num_retained",false]],"num_retained (req_items_sketch property)":[[18,"datasketches.req_items_sketch.num_retained",false]],"num_retained (theta_sketch property)":[[3,"datasketches.theta_sketch.num_retained",false]],"num_retained (tuple_sketch property)":[[4,"datasketches.tuple_sketch.num_retained",false]],"num_samples (var_opt_sketch property)":[[22,"datasketches.var_opt_sketch.num_samples",false]],"pydoublesserde (class in datasketches)":[[12,"datasketches.PyDoublesSerDe",false]],"pyfloatsserde (class in datasketches)":[[12,"datasketches.PyFloatsSerDe",false]],"pyintsserde (class in datasketches)":[[12,"datasketches.PyIntsSerDe",false]],"pylongsserde (class in datasketches)":[[12,"datasketches.PyLongsSerDe",false]],"pyobjectserde (class in datasketches)":[[12,"datasketches.PyObjectSerDe",false]],"pystringsserde (class in datasketches)":[[12,"datasketches.PyStringsSerDe",false]],"quantiles_doubles_sketch (class in datasketches)":[[17,"datasketches.quantiles_doubles_sketch",false]],"quantiles_floats_sketch (class in datasketches)":[[17,"datasketches.quantiles_floats_sketch",false]],"quantiles_ints_sketch (class in datasketches)":[[17,"datasketches.quantiles_ints_sketch",false]],"quantiles_items_sketch (class in datasketches)":[[17,"datasketches.quantiles_items_sketch",false]],"req_floats_sketch (class in datasketches)":[[18,"datasketches.req_floats_sketch",false]],"req_ints_sketch (class in datasketches)":[[18,"datasketches.req_ints_sketch",false]],"req_items_sketch (class in datasketches)":[[18,"datasketches.req_items_sketch",false]],"reset (hll_sketch attribute)":[[1,"datasketches.hll_sketch.reset",false]],"reset (hll_union attribute)":[[1,"datasketches.hll_union.reset",false]],"reset (tuple_union attribute)":[[4,"datasketches.tuple_union.reset",false]],"reset (update_theta_sketch attribute)":[[3,"datasketches.update_theta_sketch.reset",false]],"reset (update_tuple_sketch attribute)":[[4,"datasketches.update_tuple_sketch.reset",false]],"reset (var_opt_union attribute)":[[22,"datasketches.var_opt_union.reset",false]],"seed (count_min_sketch property)":[[5,"datasketches.count_min_sketch.seed",false]],"serialize (compact_theta_sketch attribute)":[[3,"datasketches.compact_theta_sketch.serialize",false]],"serialize (compact_tuple_sketch attribute)":[[4,"datasketches.compact_tuple_sketch.serialize",false]],"serialize (count_min_sketch attribute)":[[5,"datasketches.count_min_sketch.serialize",false]],"serialize (cpc_sketch attribute)":[[0,"datasketches.cpc_sketch.serialize",false]],"serialize (density_sketch attribute)":[[23,"datasketches.density_sketch.serialize",false]],"serialize (ebpps_sketch attribute)":[[20,"datasketches.ebpps_sketch.serialize",false]],"serialize (frequent_items_sketch attribute)":[[6,"datasketches.frequent_items_sketch.serialize",false]],"serialize (frequent_strings_sketch attribute)":[[6,"datasketches.frequent_strings_sketch.serialize",false]],"serialize (kll_doubles_sketch attribute)":[[16,"datasketches.kll_doubles_sketch.serialize",false]],"serialize (kll_floats_sketch attribute)":[[16,"datasketches.kll_floats_sketch.serialize",false]],"serialize (kll_ints_sketch attribute)":[[16,"datasketches.kll_ints_sketch.serialize",false]],"serialize (kll_items_sketch attribute)":[[16,"datasketches.kll_items_sketch.serialize",false]],"serialize (quantiles_doubles_sketch attribute)":[[17,"datasketches.quantiles_doubles_sketch.serialize",false]],"serialize (quantiles_floats_sketch attribute)":[[17,"datasketches.quantiles_floats_sketch.serialize",false]],"serialize (quantiles_ints_sketch attribute)":[[17,"datasketches.quantiles_ints_sketch.serialize",false]],"serialize (quantiles_items_sketch attribute)":[[17,"datasketches.quantiles_items_sketch.serialize",false]],"serialize (req_floats_sketch attribute)":[[18,"datasketches.req_floats_sketch.serialize",false]],"serialize (req_ints_sketch attribute)":[[18,"datasketches.req_ints_sketch.serialize",false]],"serialize (req_items_sketch attribute)":[[18,"datasketches.req_items_sketch.serialize",false]],"serialize (tdigest_double attribute)":[[19,"datasketches.tdigest_double.serialize",false]],"serialize (tdigest_float attribute)":[[19,"datasketches.tdigest_float.serialize",false]],"serialize (var_opt_sketch attribute)":[[22,"datasketches.var_opt_sketch.serialize",false]],"serialize (var_opt_union attribute)":[[22,"datasketches.var_opt_union.serialize",false]],"serialize_compact (hll_sketch attribute)":[[1,"datasketches.hll_sketch.serialize_compact",false]],"serialize_updatable (hll_sketch attribute)":[[1,"datasketches.hll_sketch.serialize_updatable",false]],"similarity_test() (theta_jaccard_similarity method)":[[9,"datasketches.theta_jaccard_similarity.similarity_test",false]],"similarity_test() (tuple_jaccard_similarity method)":[[9,"datasketches.tuple_jaccard_similarity.similarity_test",false]],"suggest_num_buckets() (count_min_sketch method)":[[5,"datasketches.count_min_sketch.suggest_num_buckets",false]],"suggest_num_hashes() (count_min_sketch method)":[[5,"datasketches.count_min_sketch.suggest_num_hashes",false]],"tdigest_double (class in datasketches)":[[19,"datasketches.tdigest_double",false]],"tdigest_float (class in datasketches)":[[19,"datasketches.tdigest_float",false]],"tgt_hll_type (class in _datasketches)":[[1,"datasketches.tgt_hll_type",false]],"tgt_type (hll_sketch property)":[[1,"datasketches.hll_sketch.tgt_type",false]],"theta (theta_sketch property)":[[3,"datasketches.theta_sketch.theta",false]],"theta (tuple_sketch property)":[[4,"datasketches.tuple_sketch.theta",false]],"theta64 (theta_sketch property)":[[3,"datasketches.theta_sketch.theta64",false]],"theta64 (tuple_sketch property)":[[4,"datasketches.tuple_sketch.theta64",false]],"theta_a_not_b (class in datasketches)":[[3,"datasketches.theta_a_not_b",false]],"theta_intersection (class in datasketches)":[[3,"datasketches.theta_intersection",false]],"theta_jaccard_similarity (class in datasketches)":[[9,"datasketches.theta_jaccard_similarity",false]],"theta_sketch (class in datasketches)":[[3,"datasketches.theta_sketch",false]],"theta_union (class in datasketches)":[[3,"datasketches.theta_union",false]],"to_bytes() (pyobjectserde method)":[[12,"datasketches.PyObjectSerDe.to_bytes",false]],"to_string (count_min_sketch attribute)":[[5,"datasketches.count_min_sketch.to_string",false]],"to_string (cpc_sketch attribute)":[[0,"datasketches.cpc_sketch.to_string",false]],"to_string (density_sketch attribute)":[[23,"datasketches.density_sketch.to_string",false]],"to_string (ebpps_sketch attribute)":[[20,"datasketches.ebpps_sketch.to_string",false]],"to_string (frequent_items_sketch attribute)":[[6,"datasketches.frequent_items_sketch.to_string",false]],"to_string (frequent_strings_sketch attribute)":[[6,"datasketches.frequent_strings_sketch.to_string",false]],"to_string (hll_sketch attribute)":[[1,"datasketches.hll_sketch.to_string",false]],"to_string (kll_doubles_sketch attribute)":[[16,"datasketches.kll_doubles_sketch.to_string",false]],"to_string (kll_floats_sketch attribute)":[[16,"datasketches.kll_floats_sketch.to_string",false]],"to_string (kll_ints_sketch attribute)":[[16,"datasketches.kll_ints_sketch.to_string",false]],"to_string (kll_items_sketch attribute)":[[16,"datasketches.kll_items_sketch.to_string",false]],"to_string (quantiles_doubles_sketch attribute)":[[17,"datasketches.quantiles_doubles_sketch.to_string",false]],"to_string (quantiles_floats_sketch attribute)":[[17,"datasketches.quantiles_floats_sketch.to_string",false]],"to_string (quantiles_ints_sketch attribute)":[[17,"datasketches.quantiles_ints_sketch.to_string",false]],"to_string (quantiles_items_sketch attribute)":[[17,"datasketches.quantiles_items_sketch.to_string",false]],"to_string (req_floats_sketch attribute)":[[18,"datasketches.req_floats_sketch.to_string",false]],"to_string (req_ints_sketch attribute)":[[18,"datasketches.req_ints_sketch.to_string",false]],"to_string (req_items_sketch attribute)":[[18,"datasketches.req_items_sketch.to_string",false]],"to_string (tdigest_double attribute)":[[19,"datasketches.tdigest_double.to_string",false]],"to_string (tdigest_float attribute)":[[19,"datasketches.tdigest_float.to_string",false]],"to_string (theta_sketch attribute)":[[3,"datasketches.theta_sketch.to_string",false]],"to_string (tuple_sketch attribute)":[[4,"datasketches.tuple_sketch.to_string",false]],"to_string (var_opt_sketch attribute)":[[22,"datasketches.var_opt_sketch.to_string",false]],"to_string (var_opt_union attribute)":[[22,"datasketches.var_opt_union.to_string",false]],"total_weight (count_min_sketch property)":[[5,"datasketches.count_min_sketch.total_weight",false]],"total_weight (frequent_items_sketch property)":[[6,"datasketches.frequent_items_sketch.total_weight",false]],"total_weight (frequent_strings_sketch property)":[[6,"datasketches.frequent_strings_sketch.total_weight",false]],"trim (update_theta_sketch attribute)":[[3,"datasketches.update_theta_sketch.trim",false]],"trim (update_tuple_sketch attribute)":[[4,"datasketches.update_tuple_sketch.trim",false]],"tuple_a_not_b (class in datasketches)":[[4,"datasketches.tuple_a_not_b",false]],"tuple_intersection (class in datasketches)":[[4,"datasketches.tuple_intersection",false]],"tuple_jaccard_similarity (class in datasketches)":[[9,"datasketches.tuple_jaccard_similarity",false]],"tuple_sketch (class in datasketches)":[[4,"datasketches.tuple_sketch",false]],"tuple_union (class in datasketches)":[[4,"datasketches.tuple_union",false]],"tuplepolicy (class in datasketches)":[[13,"datasketches.TuplePolicy",false]],"update (count_min_sketch attribute)":[[5,"datasketches.count_min_sketch.update",false]],"update (cpc_sketch attribute)":[[0,"datasketches.cpc_sketch.update",false]],"update (cpc_union attribute)":[[0,"datasketches.cpc_union.update",false]],"update (density_sketch attribute)":[[23,"datasketches.density_sketch.update",false]],"update (ebpps_sketch attribute)":[[20,"datasketches.ebpps_sketch.update",false]],"update (frequent_items_sketch attribute)":[[6,"datasketches.frequent_items_sketch.update",false]],"update (frequent_strings_sketch attribute)":[[6,"datasketches.frequent_strings_sketch.update",false]],"update (hll_sketch attribute)":[[1,"datasketches.hll_sketch.update",false]],"update (hll_union attribute)":[[1,"datasketches.hll_union.update",false]],"update (kll_doubles_sketch attribute)":[[16,"datasketches.kll_doubles_sketch.update",false]],"update (kll_floats_sketch attribute)":[[16,"datasketches.kll_floats_sketch.update",false]],"update (kll_ints_sketch attribute)":[[16,"datasketches.kll_ints_sketch.update",false]],"update (kll_items_sketch attribute)":[[16,"datasketches.kll_items_sketch.update",false]],"update (quantiles_doubles_sketch attribute)":[[17,"datasketches.quantiles_doubles_sketch.update",false]],"update (quantiles_floats_sketch attribute)":[[17,"datasketches.quantiles_floats_sketch.update",false]],"update (quantiles_ints_sketch attribute)":[[17,"datasketches.quantiles_ints_sketch.update",false]],"update (quantiles_items_sketch attribute)":[[17,"datasketches.quantiles_items_sketch.update",false]],"update (req_floats_sketch attribute)":[[18,"datasketches.req_floats_sketch.update",false]],"update (req_ints_sketch attribute)":[[18,"datasketches.req_ints_sketch.update",false]],"update (req_items_sketch attribute)":[[18,"datasketches.req_items_sketch.update",false]],"update (tdigest_double attribute)":[[19,"datasketches.tdigest_double.update",false]],"update (tdigest_float attribute)":[[19,"datasketches.tdigest_float.update",false]],"update (theta_intersection attribute)":[[3,"datasketches.theta_intersection.update",false]],"update (theta_union attribute)":[[3,"datasketches.theta_union.update",false]],"update (tuple_intersection attribute)":[[4,"datasketches.tuple_intersection.update",false]],"update (tuple_union attribute)":[[4,"datasketches.tuple_union.update",false]],"update (update_theta_sketch attribute)":[[3,"datasketches.update_theta_sketch.update",false]],"update (update_tuple_sketch attribute)":[[4,"datasketches.update_tuple_sketch.update",false]],"update (var_opt_sketch attribute)":[[22,"datasketches.var_opt_sketch.update",false]],"update (var_opt_union attribute)":[[22,"datasketches.var_opt_union.update",false]],"update_summary() (tuplepolicy method)":[[13,"datasketches.TuplePolicy.update_summary",false]],"update_theta_sketch (class in datasketches)":[[3,"datasketches.update_theta_sketch",false]],"update_tuple_sketch (class in datasketches)":[[4,"datasketches.update_tuple_sketch",false]],"var_opt_sketch (class in datasketches)":[[22,"datasketches.var_opt_sketch",false]],"var_opt_union (class in datasketches)":[[22,"datasketches.var_opt_union",false]]},"objects":{"_datasketches":[[5,0,1,"datasketches.count_min_sketch","count_min_sketch"],[0,0,1,"datasketches.cpc_sketch","cpc_sketch"],[0,0,1,"datasketches.cpc_union","cpc_union"],[1,0,1,"datasketches.hll_sketch","hll_sketch"],[1,0,1,"datasketches.hll_union","hll_union"],[1,0,1,"datasketches.tgt_hll_type","tgt_hll_type"]],"_datasketches.count_min_sketch":[[5,1,1,"datasketches.count_min_sketch.deserialize","deserialize"],[5,2,1,"datasketches.count_min_sketch.get_estimate","get_estimate"],[5,2,1,"datasketches.count_min_sketch.get_lower_bound","get_lower_bound"],[5,2,1,"datasketches.count_min_sketch.get_relative_error","get_relative_error"],[5,2,1,"datasketches.count_min_sketch.get_serialized_size_bytes","get_serialized_size_bytes"],[5,2,1,"datasketches.count_min_sketch.get_upper_bound","get_upper_bound"],[5,2,1,"datasketches.count_min_sketch.is_empty","is_empty"],[5,2,1,"datasketches.count_min_sketch.merge","merge"],[5,3,1,"datasketches.count_min_sketch.num_buckets","num_buckets"],[5,3,1,"datasketches.count_min_sketch.num_hashes","num_hashes"],[5,3,1,"datasketches.count_min_sketch.seed","seed"],[5,2,1,"datasketches.count_min_sketch.serialize","serialize"],[5,1,1,"datasketches.count_min_sketch.suggest_num_buckets","suggest_num_buckets"],[5,1,1,"datasketches.count_min_sketch.suggest_num_hashes","suggest_num_hashes"],[5,2,1,"datasketches.count_min_sketch.to_string","to_string"],[5,3,1,"datasketches.count_min_sketch.total_weight","total_weight"],[5,2,1,"datasketches.count_min_sketch.update","update"]],"_datasketches.cpc_sketch":[[0,1,1,"datasketches.cpc_sketch.__init__","__init__"],[0,1,1,"datasketches.cpc_sketch.deserialize","deserialize"],[0,2,1,"datasketches.cpc_sketch.get_estimate","get_estimate"],[0,2,1,"datasketches.cpc_sketch.get_lower_bound","get_lower_bound"],[0,2,1,"datasketches.cpc_sketch.get_upper_bound","get_upper_bound"],[0,2,1,"datasketches.cpc_sketch.is_empty","is_empty"],[0,3,1,"datasketches.cpc_sketch.lg_k","lg_k"],[0,2,1,"datasketches.cpc_sketch.serialize","serialize"],[0,2,1,"datasketches.cpc_sketch.to_string","to_string"],[0,2,1,"datasketches.cpc_sketch.update","update"]],"_datasketches.cpc_union":[[0,1,1,"datasketches.cpc_union.__init__","__init__"],[0,2,1,"datasketches.cpc_union.get_result","get_result"],[0,2,1,"datasketches.cpc_union.update","update"]],"_datasketches.hll_sketch":[[1,1,1,"datasketches.hll_sketch.__init__","__init__"],[1,1,1,"datasketches.hll_sketch.deserialize","deserialize"],[1,2,1,"datasketches.hll_sketch.get_compact_serialization_bytes","get_compact_serialization_bytes"],[1,2,1,"datasketches.hll_sketch.get_estimate","get_estimate"],[1,2,1,"datasketches.hll_sketch.get_lower_bound","get_lower_bound"],[1,1,1,"datasketches.hll_sketch.get_max_updatable_serialization_bytes","get_max_updatable_serialization_bytes"],[1,1,1,"datasketches.hll_sketch.get_rel_err","get_rel_err"],[1,2,1,"datasketches.hll_sketch.get_updatable_serialization_bytes","get_updatable_serialization_bytes"],[1,2,1,"datasketches.hll_sketch.get_upper_bound","get_upper_bound"],[1,2,1,"datasketches.hll_sketch.is_compact","is_compact"],[1,2,1,"datasketches.hll_sketch.is_empty","is_empty"],[1,3,1,"datasketches.hll_sketch.lg_config_k","lg_config_k"],[1,2,1,"datasketches.hll_sketch.reset","reset"],[1,2,1,"datasketches.hll_sketch.serialize_compact","serialize_compact"],[1,2,1,"datasketches.hll_sketch.serialize_updatable","serialize_updatable"],[1,3,1,"datasketches.hll_sketch.tgt_type","tgt_type"],[1,2,1,"datasketches.hll_sketch.to_string","to_string"],[1,2,1,"datasketches.hll_sketch.update","update"]],"_datasketches.hll_union":[[1,1,1,"datasketches.hll_union.__init__","__init__"],[1,2,1,"datasketches.hll_union.get_estimate","get_estimate"],[1,2,1,"datasketches.hll_union.get_lower_bound","get_lower_bound"],[1,1,1,"datasketches.hll_union.get_rel_err","get_rel_err"],[1,2,1,"datasketches.hll_union.get_result","get_result"],[1,2,1,"datasketches.hll_union.get_upper_bound","get_upper_bound"],[1,2,1,"datasketches.hll_union.is_empty","is_empty"],[1,3,1,"datasketches.hll_union.lg_config_k","lg_config_k"],[1,2,1,"datasketches.hll_union.reset","reset"],[1,2,1,"datasketches.hll_union.update","update"]],"_datasketches.tgt_hll_type":[[1,2,1,"datasketches.tgt_hll_type.HLL_4","HLL_4"],[1,2,1,"datasketches.tgt_hll_type.HLL_6","HLL_6"],[1,2,1,"datasketches.tgt_hll_type.HLL_8","HLL_8"]],"datasketches":[[13,0,1,"","AccumulatorPolicy"],[10,0,1,"","GaussianKernel"],[10,0,1,"","KernelFunction"],[13,0,1,"","MaxIntPolicy"],[13,0,1,"","MinIntPolicy"],[12,0,1,"","PyDoublesSerDe"],[12,0,1,"","PyFloatsSerDe"],[12,0,1,"","PyIntsSerDe"],[12,0,1,"","PyLongsSerDe"],[12,0,1,"","PyObjectSerDe"],[12,0,1,"","PyStringsSerDe"],[13,0,1,"","TuplePolicy"],[3,0,1,"","compact_theta_sketch"],[4,0,1,"","compact_tuple_sketch"],[23,0,1,"","density_sketch"],[20,0,1,"","ebpps_sketch"],[6,0,1,"","frequent_items_error_type"],[6,0,1,"","frequent_items_sketch"],[6,0,1,"","frequent_strings_sketch"],[16,0,1,"","kll_doubles_sketch"],[16,0,1,"","kll_floats_sketch"],[16,0,1,"","kll_ints_sketch"],[16,0,1,"","kll_items_sketch"],[11,4,1,"","ks_test"],[17,0,1,"","quantiles_doubles_sketch"],[17,0,1,"","quantiles_floats_sketch"],[17,0,1,"","quantiles_ints_sketch"],[17,0,1,"","quantiles_items_sketch"],[18,0,1,"","req_floats_sketch"],[18,0,1,"","req_ints_sketch"],[18,0,1,"","req_items_sketch"],[19,0,1,"","tdigest_double"],[19,0,1,"","tdigest_float"],[3,0,1,"","theta_a_not_b"],[3,0,1,"","theta_intersection"],[9,0,1,"","theta_jaccard_similarity"],[3,0,1,"","theta_sketch"],[3,0,1,"","theta_union"],[4,0,1,"","tuple_a_not_b"],[4,0,1,"","tuple_intersection"],[9,0,1,"","tuple_jaccard_similarity"],[4,0,1,"","tuple_sketch"],[4,0,1,"","tuple_union"],[3,0,1,"","update_theta_sketch"],[4,0,1,"","update_tuple_sketch"],[22,0,1,"","var_opt_sketch"],[22,0,1,"","var_opt_union"]],"datasketches.KernelFunction":[[10,1,1,"","__call__"]],"datasketches.PyObjectSerDe":[[12,1,1,"","from_bytes"],[12,1,1,"","get_size"],[12,1,1,"","to_bytes"]],"datasketches.TuplePolicy":[[13,1,1,"","__call__"],[13,1,1,"","create_summary"],[13,1,1,"","update_summary"]],"datasketches.compact_theta_sketch":[[3,1,1,"","__init__"],[3,1,1,"","deserialize"],[3,2,1,"","serialize"]],"datasketches.compact_tuple_sketch":[[4,1,1,"","__init__"],[4,1,1,"","deserialize"],[4,2,1,"","filter"],[4,2,1,"","serialize"]],"datasketches.density_sketch":[[23,1,1,"","__init__"],[23,1,1,"","deserialize"],[23,3,1,"","dim"],[23,2,1,"","get_estimate"],[23,2,1,"","is_empty"],[23,2,1,"","is_estimation_mode"],[23,3,1,"","k"],[23,2,1,"","merge"],[23,3,1,"","n"],[23,3,1,"","num_retained"],[23,2,1,"","serialize"],[23,2,1,"","to_string"],[23,2,1,"","update"]],"datasketches.ebpps_sketch":[[20,1,1,"","__init__"],[20,3,1,"","c"],[20,1,1,"","deserialize"],[20,2,1,"","get_serialized_size_bytes"],[20,2,1,"","is_empty"],[20,3,1,"","k"],[20,2,1,"","merge"],[20,3,1,"","n"],[20,2,1,"","serialize"],[20,2,1,"","to_string"],[20,2,1,"","update"]],"datasketches.frequent_items_error_type":[[6,2,1,"","NO_FALSE_NEGATIVES"],[6,2,1,"","NO_FALSE_POSITIVES"]],"datasketches.frequent_items_sketch":[[6,1,1,"","__init__"],[6,1,1,"","deserialize"],[6,3,1,"","epsilon"],[6,1,1,"","get_apriori_error"],[6,1,1,"","get_epsilon_for_lg_size"],[6,2,1,"","get_estimate"],[6,2,1,"","get_frequent_items"],[6,2,1,"","get_lower_bound"],[6,2,1,"","get_serialized_size_bytes"],[6,2,1,"","get_upper_bound"],[6,2,1,"","is_empty"],[6,2,1,"","merge"],[6,3,1,"","num_active_items"],[6,2,1,"","serialize"],[6,2,1,"","to_string"],[6,3,1,"","total_weight"],[6,2,1,"","update"]],"datasketches.frequent_strings_sketch":[[6,1,1,"","__init__"],[6,1,1,"","deserialize"],[6,3,1,"","epsilon"],[6,1,1,"","get_apriori_error"],[6,1,1,"","get_epsilon_for_lg_size"],[6,2,1,"","get_estimate"],[6,2,1,"","get_frequent_items"],[6,2,1,"","get_lower_bound"],[6,2,1,"","get_serialized_size_bytes"],[6,2,1,"","get_upper_bound"],[6,2,1,"","is_empty"],[6,2,1,"","merge"],[6,3,1,"","num_active_items"],[6,2,1,"","serialize"],[6,2,1,"","to_string"],[6,3,1,"","total_weight"],[6,2,1,"","update"]],"datasketches.kll_doubles_sketch":[[16,1,1,"","__init__"],[16,1,1,"","deserialize"],[16,2,1,"","get_cdf"],[16,2,1,"","get_max_value"],[16,2,1,"","get_min_value"],[16,1,1,"","get_normalized_rank_error"],[16,2,1,"","get_pmf"],[16,2,1,"","get_quantile"],[16,2,1,"","get_quantiles"],[16,2,1,"","get_rank"],[16,2,1,"","is_empty"],[16,2,1,"","is_estimation_mode"],[16,3,1,"","k"],[16,2,1,"","merge"],[16,3,1,"","n"],[16,2,1,"","normalized_rank_error"],[16,3,1,"","num_retained"],[16,2,1,"","serialize"],[16,2,1,"","to_string"],[16,2,1,"","update"]],"datasketches.kll_floats_sketch":[[16,1,1,"","__init__"],[16,1,1,"","deserialize"],[16,2,1,"","get_cdf"],[16,2,1,"","get_max_value"],[16,2,1,"","get_min_value"],[16,1,1,"","get_normalized_rank_error"],[16,2,1,"","get_pmf"],[16,2,1,"","get_quantile"],[16,2,1,"","get_quantiles"],[16,2,1,"","get_rank"],[16,2,1,"","is_empty"],[16,2,1,"","is_estimation_mode"],[16,3,1,"","k"],[16,2,1,"","merge"],[16,3,1,"","n"],[16,2,1,"","normalized_rank_error"],[16,3,1,"","num_retained"],[16,2,1,"","serialize"],[16,2,1,"","to_string"],[16,2,1,"","update"]],"datasketches.kll_ints_sketch":[[16,1,1,"","__init__"],[16,1,1,"","deserialize"],[16,2,1,"","get_cdf"],[16,2,1,"","get_max_value"],[16,2,1,"","get_min_value"],[16,1,1,"","get_normalized_rank_error"],[16,2,1,"","get_pmf"],[16,2,1,"","get_quantile"],[16,2,1,"","get_quantiles"],[16,2,1,"","get_rank"],[16,2,1,"","is_empty"],[16,2,1,"","is_estimation_mode"],[16,3,1,"","k"],[16,2,1,"","merge"],[16,3,1,"","n"],[16,2,1,"","normalized_rank_error"],[16,3,1,"","num_retained"],[16,2,1,"","serialize"],[16,2,1,"","to_string"],[16,2,1,"","update"]],"datasketches.kll_items_sketch":[[16,1,1,"","__init__"],[16,1,1,"","deserialize"],[16,2,1,"","get_cdf"],[16,2,1,"","get_max_value"],[16,2,1,"","get_min_value"],[16,1,1,"","get_normalized_rank_error"],[16,2,1,"","get_pmf"],[16,2,1,"","get_quantile"],[16,2,1,"","get_quantiles"],[16,2,1,"","get_rank"],[16,2,1,"","is_empty"],[16,2,1,"","is_estimation_mode"],[16,3,1,"","k"],[16,2,1,"","merge"],[16,3,1,"","n"],[16,2,1,"","normalized_rank_error"],[16,3,1,"","num_retained"],[16,2,1,"","serialize"],[16,2,1,"","to_string"],[16,2,1,"","update"]],"datasketches.quantiles_doubles_sketch":[[17,1,1,"","__init__"],[17,1,1,"","deserialize"],[17,2,1,"","get_cdf"],[17,2,1,"","get_max_value"],[17,2,1,"","get_min_value"],[17,1,1,"","get_normalized_rank_error"],[17,2,1,"","get_pmf"],[17,2,1,"","get_quantile"],[17,2,1,"","get_quantiles"],[17,2,1,"","get_rank"],[17,2,1,"","is_empty"],[17,2,1,"","is_estimation_mode"],[17,3,1,"","k"],[17,2,1,"","merge"],[17,3,1,"","n"],[17,2,1,"","normalized_rank_error"],[17,3,1,"","num_retained"],[17,2,1,"","serialize"],[17,2,1,"","to_string"],[17,2,1,"","update"]],"datasketches.quantiles_floats_sketch":[[17,1,1,"","__init__"],[17,1,1,"","deserialize"],[17,2,1,"","get_cdf"],[17,2,1,"","get_max_value"],[17,2,1,"","get_min_value"],[17,1,1,"","get_normalized_rank_error"],[17,2,1,"","get_pmf"],[17,2,1,"","get_quantile"],[17,2,1,"","get_quantiles"],[17,2,1,"","get_rank"],[17,2,1,"","is_empty"],[17,2,1,"","is_estimation_mode"],[17,3,1,"","k"],[17,2,1,"","merge"],[17,3,1,"","n"],[17,2,1,"","normalized_rank_error"],[17,3,1,"","num_retained"],[17,2,1,"","serialize"],[17,2,1,"","to_string"],[17,2,1,"","update"]],"datasketches.quantiles_ints_sketch":[[17,1,1,"","__init__"],[17,1,1,"","deserialize"],[17,2,1,"","get_cdf"],[17,2,1,"","get_max_value"],[17,2,1,"","get_min_value"],[17,1,1,"","get_normalized_rank_error"],[17,2,1,"","get_pmf"],[17,2,1,"","get_quantile"],[17,2,1,"","get_quantiles"],[17,2,1,"","get_rank"],[17,2,1,"","is_empty"],[17,2,1,"","is_estimation_mode"],[17,3,1,"","k"],[17,2,1,"","merge"],[17,3,1,"","n"],[17,2,1,"","normalized_rank_error"],[17,3,1,"","num_retained"],[17,2,1,"","serialize"],[17,2,1,"","to_string"],[17,2,1,"","update"]],"datasketches.quantiles_items_sketch":[[17,1,1,"","__init__"],[17,1,1,"","deserialize"],[17,2,1,"","get_cdf"],[17,2,1,"","get_max_value"],[17,2,1,"","get_min_value"],[17,1,1,"","get_normalized_rank_error"],[17,2,1,"","get_pmf"],[17,2,1,"","get_quantile"],[17,2,1,"","get_quantiles"],[17,2,1,"","get_rank"],[17,2,1,"","is_empty"],[17,2,1,"","is_estimation_mode"],[17,3,1,"","k"],[17,2,1,"","merge"],[17,3,1,"","n"],[17,2,1,"","normalized_rank_error"],[17,3,1,"","num_retained"],[17,2,1,"","serialize"],[17,2,1,"","to_string"],[17,2,1,"","update"]],"datasketches.req_floats_sketch":[[18,1,1,"","__init__"],[18,1,1,"","deserialize"],[18,1,1,"","get_RSE"],[18,2,1,"","get_cdf"],[18,2,1,"","get_max_value"],[18,2,1,"","get_min_value"],[18,2,1,"","get_pmf"],[18,2,1,"","get_quantile"],[18,2,1,"","get_quantiles"],[18,2,1,"","get_rank"],[18,2,1,"","get_rank_lower_bound"],[18,2,1,"","get_rank_upper_bound"],[18,2,1,"","is_empty"],[18,2,1,"","is_estimation_mode"],[18,2,1,"","is_hra"],[18,3,1,"","k"],[18,2,1,"","merge"],[18,3,1,"","n"],[18,3,1,"","num_retained"],[18,2,1,"","serialize"],[18,2,1,"","to_string"],[18,2,1,"","update"]],"datasketches.req_ints_sketch":[[18,1,1,"","__init__"],[18,1,1,"","deserialize"],[18,1,1,"","get_RSE"],[18,2,1,"","get_cdf"],[18,2,1,"","get_max_value"],[18,2,1,"","get_min_value"],[18,2,1,"","get_pmf"],[18,2,1,"","get_quantile"],[18,2,1,"","get_quantiles"],[18,2,1,"","get_rank"],[18,2,1,"","get_rank_lower_bound"],[18,2,1,"","get_rank_upper_bound"],[18,2,1,"","is_empty"],[18,2,1,"","is_estimation_mode"],[18,2,1,"","is_hra"],[18,3,1,"","k"],[18,2,1,"","merge"],[18,3,1,"","n"],[18,3,1,"","num_retained"],[18,2,1,"","serialize"],[18,2,1,"","to_string"],[18,2,1,"","update"]],"datasketches.req_items_sketch":[[18,1,1,"","__init__"],[18,1,1,"","deserialize"],[18,1,1,"","get_RSE"],[18,2,1,"","get_cdf"],[18,2,1,"","get_max_value"],[18,2,1,"","get_min_value"],[18,2,1,"","get_pmf"],[18,2,1,"","get_quantile"],[18,2,1,"","get_quantiles"],[18,2,1,"","get_rank"],[18,2,1,"","get_rank_lower_bound"],[18,2,1,"","get_rank_upper_bound"],[18,2,1,"","is_empty"],[18,2,1,"","is_estimation_mode"],[18,2,1,"","is_hra"],[18,3,1,"","k"],[18,2,1,"","merge"],[18,3,1,"","n"],[18,3,1,"","num_retained"],[18,2,1,"","serialize"],[18,2,1,"","to_string"],[18,2,1,"","update"]],"datasketches.tdigest_double":[[19,1,1,"","__init__"],[19,2,1,"","compress"],[19,1,1,"","deserialize"],[19,2,1,"","get_cdf"],[19,2,1,"","get_max_value"],[19,2,1,"","get_min_value"],[19,2,1,"","get_pmf"],[19,2,1,"","get_quantile"],[19,2,1,"","get_rank"],[19,2,1,"","get_serialized_size_bytes"],[19,2,1,"","get_total_weight"],[19,2,1,"","is_empty"],[19,3,1,"","k"],[19,2,1,"","merge"],[19,2,1,"","serialize"],[19,2,1,"","to_string"],[19,2,1,"","update"]],"datasketches.tdigest_float":[[19,1,1,"","__init__"],[19,2,1,"","compress"],[19,1,1,"","deserialize"],[19,2,1,"","get_cdf"],[19,2,1,"","get_max_value"],[19,2,1,"","get_min_value"],[19,2,1,"","get_pmf"],[19,2,1,"","get_quantile"],[19,2,1,"","get_rank"],[19,2,1,"","get_serialized_size_bytes"],[19,2,1,"","get_total_weight"],[19,2,1,"","is_empty"],[19,3,1,"","k"],[19,2,1,"","merge"],[19,2,1,"","serialize"],[19,2,1,"","to_string"],[19,2,1,"","update"]],"datasketches.theta_a_not_b":[[3,1,1,"","__init__"],[3,2,1,"","compute"]],"datasketches.theta_intersection":[[3,1,1,"","__init__"],[3,2,1,"","get_result"],[3,2,1,"","has_result"],[3,2,1,"","update"]],"datasketches.theta_jaccard_similarity":[[9,1,1,"","dissimilarity_test"],[9,1,1,"","exactly_equal"],[9,1,1,"","jaccard"],[9,1,1,"","similarity_test"]],"datasketches.theta_sketch":[[3,2,1,"","get_estimate"],[3,2,1,"","get_lower_bound"],[3,2,1,"","get_seed_hash"],[3,2,1,"","get_upper_bound"],[3,2,1,"","is_empty"],[3,2,1,"","is_estimation_mode"],[3,2,1,"","is_ordered"],[3,3,1,"","num_retained"],[3,3,1,"","theta"],[3,3,1,"","theta64"],[3,2,1,"","to_string"]],"datasketches.theta_union":[[3,1,1,"","__init__"],[3,2,1,"","get_result"],[3,2,1,"","update"]],"datasketches.tuple_a_not_b":[[4,1,1,"","__init__"],[4,2,1,"","compute"]],"datasketches.tuple_intersection":[[4,1,1,"","__init__"],[4,2,1,"","get_result"],[4,2,1,"","has_result"],[4,2,1,"","update"]],"datasketches.tuple_jaccard_similarity":[[9,1,1,"","dissimilarity_test"],[9,1,1,"","exactly_equal"],[9,1,1,"","jaccard"],[9,1,1,"","similarity_test"]],"datasketches.tuple_sketch":[[4,2,1,"","DEFAULT_SEED"],[4,2,1,"","get_estimate"],[4,2,1,"","get_lower_bound"],[4,2,1,"","get_seed_hash"],[4,2,1,"","get_upper_bound"],[4,2,1,"","is_empty"],[4,2,1,"","is_estimation_mode"],[4,2,1,"","is_ordered"],[4,3,1,"","num_retained"],[4,3,1,"","theta"],[4,3,1,"","theta64"],[4,2,1,"","to_string"]],"datasketches.tuple_union":[[4,1,1,"","__init__"],[4,2,1,"","get_result"],[4,2,1,"","reset"],[4,2,1,"","update"]],"datasketches.update_theta_sketch":[[3,1,1,"","__init__"],[3,2,1,"","compact"],[3,2,1,"","reset"],[3,2,1,"","trim"],[3,2,1,"","update"]],"datasketches.update_tuple_sketch":[[4,1,1,"","__init__"],[4,2,1,"","compact"],[4,2,1,"","filter"],[4,2,1,"","reset"],[4,2,1,"","trim"],[4,2,1,"","update"]],"datasketches.var_opt_sketch":[[22,1,1,"","__init__"],[22,1,1,"","deserialize"],[22,2,1,"","estimate_subset_sum"],[22,2,1,"","get_serialized_size_bytes"],[22,2,1,"","is_empty"],[22,3,1,"","k"],[22,3,1,"","n"],[22,3,1,"","num_samples"],[22,2,1,"","serialize"],[22,2,1,"","to_string"],[22,2,1,"","update"]],"datasketches.var_opt_union":[[22,1,1,"","__init__"],[22,1,1,"","deserialize"],[22,2,1,"","get_result"],[22,2,1,"","get_serialized_size_bytes"],[22,2,1,"","reset"],[22,2,1,"","serialize"],[22,2,1,"","to_string"],[22,2,1,"","update"]]},"objnames":{"0":["py","class","Python class"],"1":["py","method","Python method"],"2":["py","attribute","Python attribute"],"3":["py","property","Python property"],"4":["py","function","Python function"]},"objtypes":{"0":"py:class","1":"py:method","2":"py:attribute","3":"py:property","4":"py:function"},"terms":{"":[1,6,20,21,22],"0":[3,4,5,6,10,16,17,18],"01668v2":18,"05":5,"1":[0,1,3,4,5,6,10,16,17,18,19],"10":[1,17],"100":17,"1000":17,"11":0,"12":[3,4,18],"128":17,"13":16,"14":6,"16":1,"18":6,"1982":6,"1985":2,"1e":6,"1e9":6,"2":[0,1,3,4,6,17,18],"20":17,"200":[16,19],"2002":6,"2003":6,"2004":18,"2006":6,"2021":17,"2023":20,"21":1,"3":[0,1,3,4,6,17,18],"30":17,"32":12,"33":16,"4":[1,12,17],"40":17,"47":16,"483":17,"5":[5,6,17],"500":17,"50th":17,"517":17,"6":1,"64":[0,3,4,5,12,17],"65":16,"7":[1,9,17],"75":6,"8":[1,6,12],"80":11,"900":17,"9001":[0,3,4,9],"93smirnov_test":11,"95":[5,17],"95th":17,"97":9,"99":[16,17],"A":[1,3,4,6,10,11,12,13,16,17,22],"As":[0,17],"For":[0,1,5,6,16,17,18,19,24],"If":[1,6,9,16,17,18,19],"In":[0,1,16,20],"It":[3,16,17,18,19],"One":2,"That":15,"The":[0,1,2,3,4,5,6,7,10,11,12,13,15,16,17,18,19,20,21,22,23],"Then":16,"There":[3,6],"These":[1,8,9,15,21,24],"With":[16,17,18],"_":11,"__call__":[10,13],"__eq__":6,"__hash__":6,"__init__":[0,1,3,4,6,16,17,18,19,20,22,23],"__lt__":[16,17,18],"_datasketch":[0,1,3,4,5,6,9,11,16,17,18,19,20,22,23],"ab":18,"abbadi":6,"abil":18,"about":[1,15,16,17],"abov":[7,16],"absolut":8,"abstract":[3,4,8,10,12,13],"accept":24,"account":11,"accumulatori":13,"accumulatorpolici":13,"accur":19,"accuraci":[0,1,2,3,5,6,16,17,18,19],"achiev":5,"activ":[6,14],"actual":[9,17],"ad":13,"add":16,"addit":[0,2,6,12],"addition":16,"advanc":21,"affect":[16,17],"after":[18,21],"against":[0,9],"agraw":6,"algorithm":[0,1,2,3,6,14,18,19],"all":[1,3,6,12,13,15,16,17,19,20,22],"alloc":12,"allow":[0,4,12,13,18],"along":6,"also":[0,3,10,14,15,17,19],"altern":[15,19],"although":[1,19,20],"alwai":[6,13,16,17,20,21],"an":[0,1,2,3,4,5,6,7,9,10,12,13,15,16,17,18,19,20,21,22,23],"analog":[16,17,18,19],"analysi":[4,11,16,17,18],"analyz":14,"ani":[3,4,5,6,7,13,16,17],"anoth":[0,6,18],"answer":15,"appl":0,"appli":[2,3,4,6,13,15,16,18,21,22],"applic":2,"approach":15,"approx":[5,18],"approxim":[0,1,3,4,5,6,10,15,16,17,18,19,23],"ar":[0,1,3,4,5,6,8,9,11,12,13,14,15,16,17,18,19,21,24],"arbitrari":[4,6],"arg":[0,1,3,4,5,6,10,12,13,16,17,18,19,20,22,23],"arg0":3,"arg1":3,"around":16,"arrai":[6,10,16,17,18,19],"art":2,"arxiv":18,"as_pmf":[16,17],"associ":[4,6,16,17,18,19],"assum":[6,11],"avail":16,"avoid":3,"axi":16,"b":[3,4,10,20],"back":0,"background":6,"backward":[6,15],"bag":6,"bandwidth":10,"base":[0,1,2,3,4,5,6,8,10,12,13,15,18,19,20,21,23],"basi":[10,19],"basic":[3,4,10],"becaus":16,"been":[7,16,17,18,22],"befor":[6,7],"behavior":1,"being":21,"below":16,"best":[16,17],"better":[1,2,3],"between":[1,3,4,6,8,9,16,17,18,23],"beyond":3,"bias":19,"big":14,"bin":[0,16],"binari":[12,17],"bit":[0,1,3,4,5,12,17],"blob":23,"bool":[1,3,4,9,11,16,17,18],"both":[11,18,19,21],"bound":[0,1,3,4,5,6,9,14,15,16,18,21,22],"bracket":16,"bucket":[1,5],"buffer":19,"build":23,"byte":[0,1,3,4,5,6,12,16,17,18,19,20,22,23],"c":[0,20],"call":[16,20],"came":2,"can":[0,1,3,4,6,11,13,15,16,17,18,19],"cannot":16,"capabl":[0,6,18],"capac":6,"cardin":[0,3],"case":[1,6,8,17,20],"caus":6,"cdf":[15,16,17,18,19],"centroid":19,"certain":[7,8,10,16,20],"characterist":19,"choic":1,"choos":18,"chosen":19,"class":[0,1,3,4,5,6,9,10,12,13,16,17,18,19,20,22,23],"classic":[15,17],"close":[7,19],"closest":19,"cm":5,"code":[6,18],"collect":1,"com":23,"combin":[8,13],"come":[11,17],"common":19,"commonli":[6,16],"compact":[1,3,4,15,16,18],"compact_theta_sketch":3,"compact_tuple_sketch":4,"compactor":18,"compar":[0,16,17,18],"comparison":[0,18],"compat":[6,12,15,17],"complic":4,"compress":[1,2,3,14,19],"comput":[3,4,6,8,9,15,19,20,22,23],"concept":2,"concret":8,"confid":[5,9,16,17],"configur":[0,1,5,16,17,18,19,20,22,23],"consecut":[16,17,18,19],"consid":[9,17],"consist":13,"constant":[1,6,16,17,18],"construct":[1,18,22],"consum":[1,12],"contain":[3,6,7],"context":10,"contrast":[5,20],"control":[16,17,18,19,23],"coreset":23,"cormod":[5,18],"correspond":[0,1,3,4,5,6,16,17,18,20,22,23],"cost":[1,12],"could":[16,17,18],"count":[1,3,4,6,17,18],"count_min_sketch":[5,7],"counter":6,"countmin":[7,14],"coupon":1,"cpc":[1,2,14],"cpc_sketch":[0,2],"cpc_union":0,"creat":[0,3,4,6,13,16,17,18,19,20,22,23],"create_summari":13,"creation":20,"criterion":18,"critic":12,"cross":[12,17],"cumul":[15,16,17,18,19],"current":[1,3,4,5,6,7,11,15,20,22],"custom":[4,10,12,13],"data":[2,3,6,11,12,13,14,15,16,17,18,19,20,22,23],"datasketch":[2,11,19],"datum":[0,1,3,4],"debug":18,"decreas":[15,18],"decrement":6,"dedic":[3,4],"default":[1,3,4,10,16,17,18,19],"default_se":4,"defin":[3,4,6,10,16,20],"definit":[16,17,18],"delta":5,"demain":6,"denot":[5,6],"densiti":[8,10,14,24],"density_sketch":[10,23,24],"depend":[5,16,19],"deprec":[14,15],"derial":19,"deriv":[3,16,17,18],"describ":[0,5,18,19],"deseri":[0,1,3,4,5,6,8,14,16,17,18,19,20,22,23],"design":[15,24],"desing":22,"detail":[18,21],"determin":[7,11],"determinist":6,"develop":[0,14],"deviat":[0,1,3,4,18],"differ":[0,1,2,3,6,12,13,18,19,21],"digest":[14,15],"dim":23,"dimac":5,"dimens":[0,23],"dimension":16,"discov":6,"discrep":23,"discuss":18,"disjoint":[16,17,18,19],"dissimilar":9,"dissimilarity_test":9,"distanc":23,"distinct":[0,1,3,4,6],"distribut":[1,11,15,16,17,18,19],"divid":[16,17,18,19],"do":[6,19],"document":16,"doe":[0,5,6,7,15,16,18,19,21],"domain":[16,19],"doubl":[16,17,18,20],"dtype":[16,17,18,19],"dun":19,"dure":1,"e":15,"e2":11,"each":[1,2,4,6,11,12,13,16,17,18,21],"earliest":2,"easili":[3,4],"ebpp":[14,21],"ebpps_sketch":[20,21],"edg":[16,17],"edo":[18,23],"edoliberti":23,"edu":5,"effect":[3,4,19],"effici":[0,3,6,14],"either":[6,15,16,17,18,19],"element":[2,6],"els":18,"empir":[0,16,17,18,19],"emploi":6,"empti":[0,1,3,4,6,16,17,18,19,20,22,23],"en":11,"enabl":[16,17],"encod":12,"end":[15,19],"endian":12,"enough":1,"ensur":[6,20,21],"entir":[7,15,21],"entri":[1,3,4,6],"entropi":0,"ep":16,"epsilon":[6,16],"equal":[11,15,16,17,18,20],"equival":[9,17,20,22],"error":[1,3,5,6,8,11,14,15,16,17,19,20,22,23],"ertl":19,"estim":[0,1,2,3,4,5,6,7,8,9,10,15,16,17,18,19,22,23,24],"estimate_subset_sum":22,"estimated_total_stream_weight":6,"estimated_total_weight":6,"evalu":[4,10],"even":[0,21],"everi":[3,4,5,6],"exact":[6,14,21],"exactli":[20,21],"exactly_equ":9,"exampl":[4,5,6,8,10,12,17],"exce":[6,18,20],"excel":19,"except":[1,16,17,18],"excess":[3,4],"exclud":6,"exclus":[16,17,18],"exist":[3,4,13],"expect":[9,20],"expens":6,"express":18,"extend":[12,13],"extens":[4,18],"extern":6,"extrem":[0,6,19],"f688c8161a25582457b0a09deb4630a81406293b":23,"f_x":5,"factor":18,"failur":5,"fals":[0,1,3,4,5,6,9,11,16,17,18,19,20,22,23],"famili":[1,8,11,19],"far":[6,15,16,17,18,19,20],"fast":0,"favor":[15,17],"fed":1,"feed":[20,22],"few":[4,19],"fewer":[6,20,22],"field":6,"filter":4,"find":6,"fit":[16,17],"fix":4,"flag":[16,17],"flajolet":[1,2],"flavor":[1,6],"float":[0,1,3,4,5,6,9,10,11,12,15,16,17,18,19,20],"float32":[16,17,18,19],"float64":[16,17,19],"fm85":0,"follow":[6,16,18,23],"footprint":2,"form":[3,4,6,11],"format":[12,19],"found":6,"four":15,"fraction":[3,4,16,17,20],"framework":3,"frequenc":[5,6,17],"frequent":[5,7,14],"frequent_items_error_typ":6,"frequent_items_sketch":[6,7],"frequent_strings_sketch":[6,7],"from":[2,3,4,6,7,10,11,12,16,17,18,19,20,21,22,23],"from_byt":12,"full":[1,5],"funciton":10,"function":[0,1,3,4,5,6,8,11,14,15,16,17,18,19],"futur":0,"g":15,"gaussian":10,"gaussiankernel":10,"gde":23,"gener":[6,7,10,15,16,17,18],"get":[16,17],"get_apriori_error":6,"get_cdf":[16,17,18,19],"get_compact_serialization_byt":1,"get_epsilon_for_lg_s":6,"get_estim":[0,1,3,4,5,6,23],"get_frequent_item":6,"get_lower_bound":[0,1,3,4,5,6],"get_max_updatable_serialization_byt":1,"get_max_valu":[16,17,18,19],"get_min_valu":[16,17,18,19],"get_n":17,"get_normalized_rank_error":[16,17,18],"get_pmf":[16,17,18,19],"get_quantil":[16,17,18,19],"get_rank":[16,17,18,19],"get_rank_lower_bound":18,"get_rank_upper_bound":18,"get_rel_err":1,"get_relative_error":5,"get_result":[0,1,3,4,20,22],"get_rs":18,"get_seed_hash":[3,4],"get_serialized_size_byt":[5,6,19,20,22],"get_siz":12,"get_total_weight":19,"get_updatable_serialization_byt":1,"get_upper_bound":[0,1,3,4,5,6],"github":23,"given":[0,1,3,4,5,6,10,11,12,15,16,17,18,19,20,22,23],"global":[6,15],"good":[2,3,15],"graham":[5,18],"gri":6,"grow":6,"guarante":[5,6,15,16,17,18],"ha":[1,3,4,5,7,16,17,18,19],"haa":20,"handl":[3,7,20],"has_result":[3,4],"hash":[0,3,4,5,6],"hat":5,"have":[1,6,11,15,16,17,18,22],"heavi":[5,6,7,14],"heaviest":7,"help":[9,18],"hentschel":20,"here":18,"heurist":15,"hi":0,"high":[0,1,15,18,19],"higher":[1,17],"highest":1,"highli":14,"hip":0,"histogram":[15,17],"histor":[0,15],"hitter":[5,6,7,14],"hll":[0,2,14],"hll_4":1,"hll_6":1,"hll_8":1,"hll_sketch":[1,2],"hll_union":1,"hold":[1,6,19],"how":[4,7,8,13,18],"howev":[6,16,18,19],"http":[5,11,18,23],"hyper":2,"hyperloglog":[0,2,3,14],"hypothesi":11,"hypothet":[16,17,18,19],"i":[0,1,2,3,4,5,6,7,8,10,11,12,13,14,15,16,17,18,19,20,21,22,23],"icon":0,"identifi":7,"imag":5,"implement":[0,1,4,6,7,10,12,13,16,17,18,19,23],"improv":[1,22],"includ":[15,16,17,18,19,20,21,22],"inclus":[1,16,17,18,21],"incom":[3,4,6],"increas":[16,17,18,19],"increment":6,"independ":16,"index":[9,14,16,17],"indic":[1,10],"inform":[19,20],"inherit":10,"init_number_of_sect":18,"initi":[1,3,4,6,18],"input":[0,1,3,4,6,10,11,16,17,18,19,21,23,24],"insert":[3,5,6],"inspir":23,"instanc":[6,16,17,18,19,20,22,23],"instead":[17,18],"insuffici":11,"int":[0,1,3,4,5,6,9,12,16,17,18,19,20,22,23],"int32":[16,17,18],"integ":[0,5,6,12,13,15],"integr":[1,3,4],"intern":6,"internet":6,"interpol":19,"interpret":16,"intersect":[2,3,4,13],"interv":[16,17,18,19],"introduc":6,"invers":[0,16],"involv":7,"is_compact":1,"is_empti":[0,1,3,4,5,6,16,17,18,19,20,22,23],"is_estimation_mod":[3,4,16,17,18,23],"is_hra":18,"is_ord":[3,4],"item":[1,3,4,5,7,12,14,15,16,17,18,19,20,21,22,23],"iter":20,"its":[0,12,16,17,19,20],"itself":6,"j":20,"j_":9,"jaccard":[3,4,8,14],"java":17,"job":15,"just":16,"justin":18,"k":[0,1,2,3,4,6,7,16,17,18,19,20,22,23],"kappa":0,"karnin":[18,23],"karnin19a":23,"karp":6,"keep":[1,4,20],"kei":[2,4],"kept":13,"kernel":[8,14,23,24],"kernel_funct":8,"kernel_sketch":8,"kernelfunct":[10,23],"kevin":0,"kll":[14,15,17],"kll_doubles_sketch":[11,16],"kll_floats_sketch":[11,16],"kll_ints_sketch":[11,16],"kll_items_sketch":[11,16],"known":[0,2,6,10,14,21],"kolmogorov":[8,14],"ks_test":[8,11],"kwarg":[0,1,3,4,5,6,10,12,13,16,17,18,19,20,22,23],"lang":0,"languag":[12,17],"larg":[1,15,16,17],"larger":[2,16,20],"largest":13,"last":[16,17,18],"lazi":16,"lb":[6,9],"le":5,"learn":[10,23],"least":[6,8],"left":[16,17,18],"legaci":6,"lemma":18,"len":12,"length":[6,16,17,18,20,21,22,23],"less":[15,16,17,18],"let":16,"letter":20,"level":[5,18],"leverag":1,"lg_config_k":1,"lg_k":[0,1,3,4],"lg_max_k":[1,6],"lg_max_map_s":6,"liberti":[18,23],"librari":[2,4,6,7,10,11,15,19,24],"like":[1,7,11,16],"limit":[6,20],"line":[16,17,18,19],"list":[5,7,9],"littl":12,"load_factor":6,"log":[1,2],"log2":[1,6],"logarithm":[0,3,4,6],"logic":[6,15],"longer":2,"look":6,"loos":18,"lopez":6,"low":[15,18,19],"lower":[0,1,3,4,5,6,9,16,18,19,22],"lower_bound":9,"m":[6,16,17,18,19],"machin":[10,23],"mai":[5,6,14,15,16,18,20],"maintain":[3,7],"make":16,"mani":[3,19],"map":6,"mapcap":6,"mapsiz":6,"margin":20,"martin":2,"mass":[15,16,17,18,19],"mass_i":16,"match":[0,3,4,22],"mathemat":[10,18,19],"max":[13,16,17,18,19],"max_k":22,"max_map_s":6,"maximum":[1,3,4,5,6,16,17,18,19,20,22],"maxintpolici":13,"maxmapcap":6,"maxmaps":6,"mean":[4,6,16,17,20],"measur":[3,4,9,16,17,18,19],"median":[6,17,19],"member":[3,6],"memori":[1,2,6],"merg":[0,1,4,5,6,16,17,18,19,20,23],"mergingdigest":19,"method":[0,1,3,4,5,6,10,12,16,17,18,19,20,22,23],"metwal":6,"middl":19,"might":[6,16],"million":17,"min":[13,16,17,18,19],"minim":21,"minimum":[2,3,16,17,18,19,22],"minintpolici":13,"misra":6,"miss":6,"mlr":23,"mode":[1,3,4,16,17,18,23],"modifi":[11,18,19],"modul":14,"monoton":[16,17,18,19],"more":[0,6,19],"most":[7,17],"much":[1,6],"multipli":17,"multiset":6,"munro":6,"must":[1,3,4,10,12,13,16,17,18],"muthukrishnan":5,"n":[1,16,17,18,20,22,23],"name":6,"nan":[16,17,18],"natur":[16,17],"ndarrai":[16,17,18,19],"nearli":[0,16],"necessari":[16,17,18,19],"necessarili":7,"necesssari":19,"need":[3,5,6,13,20,21,22],"network":17,"never":[5,6,16,18],"new":[0,1,6,13,17,20,22,23],"newli":0,"no_false_neg":6,"no_false_posit":6,"node":17,"nomin":[3,4,18],"non":[0,1,3,4,5,6,16,17,18,19,20,22,23],"none":[0,1,3,4,5,6,16,17,18,19,20,22,23],"normal":[16,17,18,19],"normalized_rank_error":[16,17],"note":[6,9,11,16,18],"novemb":17,"now":24,"null":[11,12],"num_active_item":6,"num_bucket":5,"num_byt":12,"num_hash":5,"num_retain":[3,4,16,17,18,23],"num_sampl":22,"num_std_dev":1,"number":[0,1,2,3,4,5,6,12,16,17,18,19,20,22,23],"numer":[15,19,20],"numpi":10,"numsect":18,"object":[0,1,3,4,5,6,7,9,10,12,13,16,17,18,19,20,22,23],"obtain":[5,16,17,18],"occurr":5,"off":[1,2,16,17,18,19],"offer":[1,2,7],"offest":12,"offset":12,"often":7,"one":[2,5,6,7,8,16,17,18,19,23],"onli":[1,6,15,16,17,18,19,24],"oper":[0,2,3,4,13,16,18,19],"opposit":16,"opt":22,"optim":[0,14,16,21],"option":[0,3,4,6,16,17,18,19,20,22],"order":[3,4,5,13,15,20],"org":[11,18],"ortiz":6,"other":[3,4,5,16,17,19],"otherwis":[0,1,3,4,5,6,9,11,16,17,18,19,20,22,23],"otmar":19,"our":6,"output":18,"outsid":7,"over":[6,15,17],"overal":17,"overestim":[5,19],"overload":[0,1,3,4,5,11,16,17,18,19],"overrid":[10,12],"p":[3,4,11,20],"packag":3,"packet":[6,17],"page":[14,19],"pair":[6,8,11],"papadimitri":6,"paper":[0,3,5,18,19,23],"paramet":[0,1,3,4,5,6,10,12,13,16,17,18,19,20,22,23],"partial":20,"particular":18,"particularli":10,"pass":[16,17],"pattern":10,"pavel":18,"pdf":[5,23],"per":[1,16],"percentag":7,"percentil":[16,17],"perform":[0,1,2,3,4,8,10,11,16,18,19],"permiss":5,"phillip":1,"physic":6,"plot":16,"plu":6,"pmf":[15,16,17,18,19],"point":[0,1,3,4,10,12,15,16,17,18,19,20,23],"polici":[4,8,14],"portion":[15,20],"posit":6,"possibl":0,"power":[6,18],"pp":20,"practic":[3,6],"pre":12,"precis":[17,20],"predic":[4,21,22],"present":22,"press":23,"print":[20,22],"priori":[1,6,18],"priorit":19,"probabilist":[1,2,5,14,15,16,17,18],"probabilitii":[14,21],"probabl":[0,5,6,15,16,17,18,19,20,21,22],"problem":14,"proceed":23,"process":[19,20,22],"produc":[0,1,3,4,5,6,16,17,18,19,20,22,23],"project":[14,17],"pronounc":19,"proof":6,"properti":[0,1,2,3,4,5,6,15,16,17,18,19,20,22,23],"proport":[14,21],"prototyp":18,"proven":15,"provid":[0,1,2,3,4,5,6,7,9,10,11,12,13,15,16,17,18,19,22,23,24],"pub":5,"purg":6,"py":23,"pydoublesserd":12,"pyfloatsserd":12,"pyintsserd":12,"pylongsserd":12,"pyobjectserd":[4,6,12,16,17,18,20,22],"pystringsserd":12,"python":[13,18],"q":16,"q_hi":16,"q_lo":16,"qualifi":6,"quantil":[8,16,19,23],"quantiles_doubles_sketch":[11,17],"quantiles_floats_sketch":[11,17],"quantiles_ints_sketch":[11,17],"quantiles_items_sketch":[11,17],"queri":[5,15,16,17,22],"quickli":14,"quit":[0,4,15,16],"r":16,"r1":16,"r2":16,"r_":16,"r_i":16,"radial":10,"random":[6,20],"randomli":21,"rang":15,"rank":[15,16,17,18,19],"rate":[3,4],"reach":[1,6],"read":[0,1,3,4,5,6,12,19,20,22,23],"real":[16,17,18,19],"reason":1,"rebuild":6,"receiv":[1,17],"recognit":10,"recommend":1,"reconstruct":12,"redesign":6,"rediscov":6,"refer":[6,8,12,16,19],"reflect":11,"regardless":7,"reject":11,"rel":[1,5,7,14,15,20,21,22],"relat":[7,9,20,22],"relationship":16,"relative_error":5,"relev":13,"reli":10,"remain":18,"remov":[3,4,6],"repeat":6,"repres":[1,17,20],"req":[14,15,17,19],"req_floats_sketch":18,"req_ints_sketch":18,"req_items_sketch":18,"requir":[4,5,6,8,16,17,18,20,22,23],"reservoir":[20,22],"reset":[1,3,4,22],"respect":[16,17],"result":[0,3,4,6,16,17,18,19,21,22],"retain":[3,4,6,16,17,18,23],"retun":12,"return":[0,1,3,4,5,6,9,10,11,12,13,16,17,18,19,20,22,23],"right":[4,16,17,18],"roughli":[0,22],"round":18,"row":1,"rse":18,"rule":13,"run":6,"runtimeerror":[16,17,18,19],"rutger":5,"s1":16,"s2":16,"s_i":16,"s_m":16,"same":[1,3,11],"sampl":[3,4,16,17,18,23],"satisfi":5,"scheme":[12,16],"score":10,"search":14,"section":18,"section_s":18,"secur":0,"see":[16,19],"seed":[0,3,4,5,9],"seem":[16,19],"seen":[5,6,7,15,19,20],"select":4,"self":[0,1,3,4,5,6,10,12,13,16,17,18,19,20,22,23],"semin":2,"separ":[3,9,16,17,18],"serd":[4,6,8,14,16,17,18,20,22],"serial":[0,1,3,4,5,6,8,14,16,17,18,19,20,22,23],"serialize_compact":1,"serialize_updat":1,"set":[2,3,4,6,13,16,17,18,19,23],"sever":[2,3,4,6,12],"shenker":6,"should":[13,16,20],"show":19,"shown":16,"side":[16,17,19],"significantli":1,"similar":[2,3,4,8,10,13,14,19],"similarity_test":9,"similarli":17,"simpl":[2,3,6,12],"simultan":0,"sinc":[6,18],"singl":[16,17],"size":[1,3,4,5,6,11,12,14,16,17,18,19,21,22,23],"sk_1":11,"sk_2":11,"skech":18,"sketch":[0,1,2,6,8,9,11,12,19,20,22],"sketch_a":9,"sketch_b":9,"slightli":19,"slot":1,"sm":16,"small":[1,6,11,15],"smaller":[0,1,6,16,22],"smallest":13,"smirnov":[8,14],"snly":7,"so":[0,6,15,16,17,18,19,20],"solut":2,"some":[6,8,16],"sometim":16,"somewhat":[2,21],"sort":[3,4,16,17,18,19],"sourc":[3,4],"sourch":4,"space":[0,1,2,3,6],"special":18,"specif":[6,8,10,15,16,17],"specifi":[0,1,5,6,8,12,13,16,18],"speed":[0,6],"split":[16,17,18,19],"split_point":[16,17,18,19],"sqrt":18,"standard":[0,1,3,4,18],"start":[1,6,12,18],"start_full_s":1,"start_max_s":1,"state":[1,2,3,4,6,18,22],"static":[0,1,3,4,5,6,16,17,18,19,20,22,23],"still":19,"stochast":[16,17],"storag":[1,12,15],"store":[2,3,6],"str":[0,1,3,4,5],"straightforward":15,"stream":[0,1,3,4,5,6,7,15,16,17,18,19,20,21,22,23],"strictli":20,"string":[0,1,3,4,5,6,7,12,16,17,18,19,20,22,23],"string_cont":12,"subset":[21,22],"subtract":16,"suggest":5,"suggest_num_bucket":5,"suggest_num_hash":5,"sum":[6,16,17,18,21,22],"summari":[0,1,3,4,5,6,8,13,16,17,18,19,20,22,23],"support":[2,6,19],"surviv":0,"t":[14,15,17],"tabl":[1,6],"take":11,"target":1,"target_hll_typ":1,"task":2,"tdigest":19,"tdigest_doubl":19,"tdigest_float":19,"ted":19,"templat":17,"tend":19,"term":1,"termin":12,"test":[8,9,14],"tgt_hll_type":1,"tgt_type":1,"thaler":18,"than":[0,1,2,3,6,15,16,17,18,20],"thei":[4,11,15,21],"them":8,"theta":[1,2,4,8,9,14],"theta64":[3,4],"theta_a_not_b":3,"theta_intersect":3,"theta_jaccard_similar":[3,9],"theta_sketch":[2,3,4,9],"theta_union":3,"thi":[0,1,4,5,6,11,12,13,14,16,17,18,19,20,22,23],"those":[7,8,15],"thousand":[16,17],"three":[1,12,15],"threshold":9,"through":[3,4,6],"throw":[16,17,18,19],"thu":[16,18],"tian":20,"tight":18,"time":[1,6,16,17,18],"to_byt":12,"to_str":[0,1,3,4,5,6,16,17,18,19,20,22,23],"too":[6,11],"tool":18,"top":[6,7],"topk":14,"total":[5,17,18,19,20,22],"total_weight":[5,6],"toward":19,"track":6,"trade":[1,2,16,17,18,19],"tradeoff":0,"translat":16,"trial":[16,17],"trim":[3,4],"true":[0,1,3,4,5,6,9,11,16,17,18,19,20,22,23],"true_mass":16,"true_rank":16,"tupl":[2,3,8,9,12,14],"tuple_a_not_b":[3,4],"tuple_intersect":4,"tuple_jaccard_similar":[4,9],"tuple_polici":8,"tuple_sketch":[2,4,8,9,13],"tuple_union":4,"tuplepolici":[4,13],"two":[0,6,7,10,11,16,18,23],"type":[1,2,4,6,7,10,11,12,13,15],"typic":[6,15],"u":16,"ub":[6,9],"under":14,"underestim":[5,19],"underli":11,"understand":[15,18],"unequ":20,"uniform":[15,20,22],"union":[0,1,3,4,13,22],"uniqu":[0,1,2,16,17,18,19],"unlik":19,"unsurprisingli":10,"up":[1,6],"updat":[0,1,3,4,5,6,13,16,17,18,19,20,22,23],"update_summari":13,"update_theta_sketch":3,"update_tuple_sketch":4,"upon":20,"upper":[0,1,3,4,5,6,9,16,18,22],"upper_bound":[1,9],"us":[1,3,4,5,6,8,9,10,11,12,13,15,16,17,18,19,20,21,22,23],"usag":6,"user":[0,10,18],"usual":6,"v99":23,"valid":[3,4,18],"valu":[0,1,2,3,4,5,6,10,11,12,13,15,16,17,18,19,20,22],"var":22,"var_opt_sketch":[21,22],"var_opt_union":22,"variabl":[6,18],"varianc":[14,21],"variant":[3,6,7],"varopt":[14,20,21],"vector":[10,16,17,18,19,23],"veri":[4,6,15,16,17,19],"version":[1,6,7,12,15,16,17,18,19],"vesel\u00fd":18,"via":18,"view":16,"visibl":18,"w":6,"warmup":1,"we":[6,11,16,18],"weight":[5,6,7,16,17,18,19,20,21,22],"well":[0,2,15,19,22],"were":[2,6,16,17],"what":[6,15],"when":[0,1,3,4,5,8,13,15,17,18,22],"where":[1,6,12,13,16,20],"whether":[1,3,4,18],"which":[2,3,4,5,6,7,10,12,15,16,17,18,19],"while":[2,3,15,19],"whose":7,"wiki":11,"wikipedia":11,"win":0,"within":[5,8],"without":15,"work":[2,15,17,18],"wors":16,"worst":6,"would":6,"written":[12,18],"x":[5,16],"y":[16,20],"year":6,"yield":16,"you":17,"zero":16,"zohar":[18,23]},"titles":["Compressed Probabilistic Counting (CPC)","HyperLogLog (HLL)","Distinct Counting","Theta Sketch","Tuple Sketch","CountMin Sketch","Frequent Items","Frequency Sketches","Helper Classes","Jaccard Similarity","Kernel Function","Kolmogorov-Smirnov Test","Serialize/Deserialize (SerDe)","Tuple Policy","Apache DataSketches","Quantiles Sketches","KLL Sketch","Quantiles Sketch (Deprecated)","Relative Error Quantiles (REQ) Sketch","t-digest","Exact and Bounded, Probabilitiy Proportional to Size (EBPPS) Sampling","Random Sampling Sketches","Variance Optimal Sampling (VarOpt)","Density Sketch","Vector Sketches"],"titleterms":{"apach":14,"bound":20,"class":[8,14],"compress":0,"count":[0,2,14],"countmin":5,"cpc":0,"datasketch":14,"densiti":23,"deprec":17,"deseri":12,"digest":19,"distinct":[2,14],"ebpp":20,"error":18,"estim":14,"exact":20,"frequenc":[7,14],"frequent":6,"function":10,"helper":[8,14],"hll":1,"hyperloglog":1,"indic":14,"item":6,"jaccard":9,"kernel":10,"kll":16,"kolmogorov":11,"optim":22,"polici":13,"probabilist":0,"probabilitii":20,"proport":20,"quantil":[14,15,17,18],"random":[14,21],"rel":18,"req":18,"sampl":[14,20,21,22],"serd":12,"serial":12,"similar":9,"size":20,"sketch":[3,4,5,7,14,15,16,17,18,21,23,24],"smirnov":11,"t":19,"tabl":14,"test":11,"theta":3,"tupl":[4,13],"varianc":22,"varopt":22,"vector":[14,24]}}) \ No newline at end of file diff --git a/docs/5.2.0/vector/density_sketch.html b/docs/5.2.0/vector/density_sketch.html new file mode 100644 index 00000000..33445703 --- /dev/null +++ b/docs/5.2.0/vector/density_sketch.html @@ -0,0 +1,246 @@ + + + + + + + + + Density Sketch — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Density Sketch

+

Builds a coreset from the given set of input points. +Provides density estimate at a given point.

+

Based on the following paper: Zohar Karnin, Edo Liberty +“Discrepancy, Coresets, and Sketches in Machine Learning” +https://proceedings.mlr.press/v99/karnin19a/karnin19a.pdf

+

Inspired by the following implementation: https://github.com/edoliberty/streaming-quantiles/blob/f688c8161a25582457b0a09deb4630a81406293b/gde.py

+

Requires the use of a KernelFunction to compute the distance between two vectors.

+
+
+class density_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, kernel: _datasketches.KernelFunction) _datasketches.density_sketch
+

Reads a bytes object and returns the corresponding density_sketch

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int, dim: int, kernel: _datasketches.KernelFunction) None
+

Creates a new density sketch

+
+
Parameters:
+
    +
  • k (int) – controls the size and error of the sketch

  • +
  • dim (int) – dimension of the input data

  • +
  • kernel (KernelFunction) – instance of a kernel

  • +
+
+
+
+ +
+
+property dim
+

The configured parameter dim

+
+ +
+
+get_estimate
+

Returns an approximate density at the given point

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Updates the sketch with the given vector

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/5.2.0/vector/index.html b/docs/5.2.0/vector/index.html new file mode 100644 index 00000000..56c6d446 --- /dev/null +++ b/docs/5.2.0/vector/index.html @@ -0,0 +1,133 @@ + + + + + + + + + Vector Sketches — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Vector Sketches

+

These sketches are designed to accept vector inputs. For now, the library provides only the +density_sketch for Kernel Density Estimation.

+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/Makefile b/docs/Makefile deleted file mode 100644 index d0c3cbf1..00000000 --- a/docs/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# Minimal makefile for Sphinx documentation -# - -# You can set these variables from the command line, and also -# from the environment for the first two. -SPHINXOPTS ?= -SPHINXBUILD ?= sphinx-build -SOURCEDIR = source -BUILDDIR = build - -# Put it first so that "make" without argument is like "make help". -help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -.PHONY: help Makefile - -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/README.md b/docs/README.md deleted file mode 100644 index 9109e28f..00000000 --- a/docs/README.md +++ /dev/null @@ -1,23 +0,0 @@ -Follow these steps to build the documentation. -1. Clone the directory in an appropriate location `git clone https://github.com/apache/datasketches-python.git` -2. Make a new branch and switch to that branch. -``` -cd datasketches-python -git branch new-branch -git checkout new-branch -``` -3. In project root, make a new virtual environment with the appropriate packages. Depending on how python is aliased in your environment, you may -need `python` or `python3`, as indicated by `python(3)`. -``` -python -m venv venv # create a new virtual env named venv using system python -source venv/bin/activate -python(3) -m pip install sphinx # now using venv python -python(3) -m pip install sphinx-rtd-theme -``` -4. In project root run `python(3) -m pip install .` to build the python bindings. -5. Build and open the documentation: -``` -cd python/docs -make html -open build/html/index.html -``` diff --git a/docs/main/.buildinfo b/docs/main/.buildinfo new file mode 100644 index 00000000..d6ebb969 --- /dev/null +++ b/docs/main/.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: 86d4b171ba47c51d1a3d7f924e02560f +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/docs/main/_sources/distinct_counting/cpc.rst.txt b/docs/main/_sources/distinct_counting/cpc.rst.txt new file mode 100644 index 00000000..6a28d387 --- /dev/null +++ b/docs/main/_sources/distinct_counting/cpc.rst.txt @@ -0,0 +1,32 @@ +Compressed Probabilistic Counting (CPC) +--------------------------------------- +High performance C++ implementation of Compressed Probabilistic Counting (CPC) Sketch. +This is a unique-counting sketch that implements the Compressed Probabilistic Counting (CPC, a.k.a FM85) algorithms developed by Kevin Lang in his paper +`Back to the Future: an Even More Nearly Optimal Cardinality Estimation Algorithm `_. +This sketch is extremely space-efficient when serialized. +In an apples-to-apples empirical comparison against compressed HyperLogLog sketches, this new algorithm simultaneously wins on the two dimensions of the space/accuracy tradeoff and produces sketches that are smaller than the entropy of HLL, so no possible implementation of compressed HLL can match its space efficiency for a given accuracy. As described in the paper this sketch implements a newly developed ICON estimator algorithm that survives unioning operations, another well-known estimator, the Historical Inverse Probability (HIP) estimator does not. +The update speed performance of this sketch is quite fast and is comparable to the speed of HLL. +The unioning (merging) capability of this sketch also allows for merging of sketches with different configurations of K. +For additional security this sketch can be configured with a user-specified hash seed. + + +.. autoclass:: _datasketches.cpc_sketch + :members: + :undoc-members: + :exclude-members: deserialize + + .. rubric:: Static Methods: + + .. automethod:: deserialize + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + + +.. autoclass:: _datasketches.cpc_union + :members: + :undoc-members: + :exclude-members: deserialize + + .. automethod:: __init__ diff --git a/docs/main/_sources/distinct_counting/hyper_log_log.rst.txt b/docs/main/_sources/distinct_counting/hyper_log_log.rst.txt new file mode 100644 index 00000000..287209b0 --- /dev/null +++ b/docs/main/_sources/distinct_counting/hyper_log_log.rst.txt @@ -0,0 +1,55 @@ +HyperLogLog (HLL) +----------------- +This is a high performance implementation of Phillipe Flajolet's HLL sketch but with significantly improved error behavior. + +If the ONLY use case for sketching is counting uniques and merging, the HLL sketch is a reasonable choice, although the highest performing in terms of accuracy for storage space consumed is CPC (Compressed Probabilistic Counting). For large enough counts, this HLL version (with HLL_4) can be 2 to 16 times smaller than the Theta sketch family for the same accuracy. + +This implementation offers three different types of HLL sketch, each with different trade-offs with accuracy, space and performance. +These types are specified with the target_hll_type parameter. + +In terms of accuracy, all three types, for the same lg_config_k, have the same error distribution as a function of ``n``, the number of unique values fed to the sketch. +The configuration parameter ``lg_config_k`` is the log-base-2 of ``k``, where ``k`` is the number of buckets or slots for the sketch. + +During warmup, when the sketch has only received a small number of unique items (up to about 10% of ``k``), this implementation leverages a new class of estimator algorithms with significantly better accuracy. + + +.. autoclass:: _datasketches.tgt_hll_type + + .. autoattribute:: HLL_4 + :annotation: : 4 bits per entry + + .. autoattribute:: HLL_6 + :annotation: : 6 bits per entry + + .. autoattribute:: HLL_8 + :annotation: : 8 bits per entry + + +.. autoclass:: _datasketches.hll_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_max_updatable_serialization_bytes, get_rel_err + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_max_updatable_serialization_bytes + .. automethod:: get_rel_err + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: _datasketches.hll_union + :members: + :undoc-members: + :exclude-members: get_rel_err + + .. rubric:: Static Methods: + + .. automethod:: get_rel_err + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + \ No newline at end of file diff --git a/docs/main/_sources/distinct_counting/index.rst.txt b/docs/main/_sources/distinct_counting/index.rst.txt new file mode 100644 index 00000000..f4038815 --- /dev/null +++ b/docs/main/_sources/distinct_counting/index.rst.txt @@ -0,0 +1,24 @@ +Distinct Counting +================= + +.. currentmodule:: datasketches + +Distinct counting is one of the earliest tasks to which sketches were applied. The concept is simple: +Provide an estimate of the number of unique elements in a set of data. One of the earliest solutions came +from Flajolet and Martin in 1985 with their seminal work +`Probabilistic counting Algorithms for Data Base Applications `_. + +The DataSketches library offers several types of distinct counting sketches, each with different properties. + + * :class:`hll_sketch`: Hyper Log Log, a well-known sketch for distinct counting but no longer state-of-the-art. + * :class:`cpc_sketch`: Provides a better accuracy-space trade-off than HLL, but with a somewhat larger footprint while in-memory. + * :class:`theta_sketch`: Theta sketch, a type of k-minimum value sketch, which provide good performance with intersection and set difference operations. + * :class:`tuple_sketch`: Tuple sketch, which is similar to a theta sketch but supports additional data stored with each key. + +.. toctree:: + :maxdepth: 1 + + hyper_log_log + cpc + theta + tuple \ No newline at end of file diff --git a/docs/main/_sources/distinct_counting/theta.rst.txt b/docs/main/_sources/distinct_counting/theta.rst.txt new file mode 100644 index 00000000..94951f96 --- /dev/null +++ b/docs/main/_sources/distinct_counting/theta.rst.txt @@ -0,0 +1,65 @@ +Theta Sketch +------------ + +.. currentmodule:: datasketches + +Theta sketches are used for distinct counting. + +The theta package contains the basic sketch classes that are members of the `Theta Sketch Framework `_. +There is a separate Tuple package for many of the sketches that are derived from the same algorithms defined in the Theta Sketch Framework paper. + +The *Theta Sketch* sketch is a space-efficient method for estimating cardinalities of sets. +It can also easily handle set operations (such as union, intersection, difference) while maintaining good accuracy. +Theta sketch is a practical variant of the K-Minimum Values sketch which avoids the need to sort the stored +hash values on every insertion to the sketch. +It has better error properties than the HyperLogLog sketch for set operations beyond the simple union. + +Set operations (union, intersection, A-not-B) are performed through the use of dedicated objects. + +Several `Jaccard similarity `_ +measures can be computed between theta sketches with the :class:`theta_jaccard_similarity` class. + +.. autoclass:: theta_sketch + :members: + :undoc-members: + +.. autoclass:: update_theta_sketch + :members: + :undoc-members: + + .. automethod:: __init__ + + +.. autoclass:: compact_theta_sketch + :members: + :undoc-members: + :exclude-members: deserialize + + .. rubric:: Static Methods: + + .. automethod:: deserialize + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + + +.. autoclass:: theta_union + :members: + :undoc-members: + + .. automethod:: __init__ + + +.. autoclass:: theta_intersection + :members: + :undoc-members: + + .. automethod:: __init__ + + +.. autoclass:: theta_a_not_b + :members: + :undoc-members: + + .. automethod:: __init__ diff --git a/docs/main/_sources/distinct_counting/tuple.rst.txt b/docs/main/_sources/distinct_counting/tuple.rst.txt new file mode 100644 index 00000000..e4a369f2 --- /dev/null +++ b/docs/main/_sources/distinct_counting/tuple.rst.txt @@ -0,0 +1,64 @@ +Tuple Sketch +------------ + +.. currentmodule:: datasketches + +Tuple sketches are an extension of Theta sketches, meaning they provide estimate of distinct counts, that +allow the keeping of arbitrary summaries associated with each retained key +(for example, a count for every key). The use of a :class:`tuple_sketch` requires a :class:`TuplePolicy` which +defines how summaries are created, updated, merged, or intersected. The library provides a few basic +examples of :class:`TuplePolicy` implementations, but the right custom summary and policy can allow very +complicated analysis to be performed quite easily. + +Set operations (union, intersection, A-not-B) are performed through the use of dedicated objects. + +Several `Jaccard similarity `_ +measures can be computed between theta sketches with the :class:`tuple_jaccard_similarity` class. + +.. note:: + Serializing and deserializing this sketch requires the use of a :class:`PyObjectSerDe`. + +.. autoclass:: tuple_sketch + :members: + :undoc-members: + +.. autoclass:: update_tuple_sketch + :members: + :undoc-members: + + .. automethod:: __init__ + + +.. autoclass:: compact_tuple_sketch + :members: + :undoc-members: + :exclude-members: deserialize + + .. rubric:: Static Methods: + + .. automethod:: deserialize + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + + +.. autoclass:: tuple_union + :members: + :undoc-members: + + .. automethod:: __init__ + + +.. autoclass:: tuple_intersection + :members: + :undoc-members: + + .. automethod:: __init__ + + +.. autoclass:: tuple_a_not_b + :members: + :undoc-members: + + .. automethod:: __init__ diff --git a/docs/main/_sources/frequency/count_min_sketch.rst.txt b/docs/main/_sources/frequency/count_min_sketch.rst.txt new file mode 100644 index 00000000..b53b02e4 --- /dev/null +++ b/docs/main/_sources/frequency/count_min_sketch.rst.txt @@ -0,0 +1,27 @@ +CountMin Sketch +--------------- + +The CountMin sketch, as described in Cormode and Muthukrishnan in +http://dimacs.rutgers.edu/~graham/pubs/papers/cm-full.pdf, +is used for approximate Frequency Estimation. +For an item :math:`x` with frequency :math:`f_x`, the sketch provides an estimate, :math:`\hat{f_x}`, +such that :math:`f_x \approx \hat{f_x}.` +The sketch guarantees that :math:`f_x \le \hat{f_x}` and provides a probabilistic upper bound which is dependent on the size parameters. +The sketch provides an estimate of the occurrence frequency for any queried item but, in contrast +to the Frequent Items Sketch, this sketch does not provide a list of +heavy hitters. + +.. currentmodule:: _datasketches + +.. autoclass:: count_min_sketch + :members: + :undoc-members: + :exclude-members: deserialize, suggest_num_buckets, suggest_num_hashes + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: suggest_num_buckets + .. automethod:: suggest_num_hashes + + .. rubric:: Non-static Methods: diff --git a/docs/main/_sources/frequency/frequent_items.rst.txt b/docs/main/_sources/frequency/frequent_items.rst.txt new file mode 100644 index 00000000..76d81f58 --- /dev/null +++ b/docs/main/_sources/frequency/frequent_items.rst.txt @@ -0,0 +1,120 @@ +Frequent Items +-------------- + +.. currentmodule:: datasketches + +This sketch is useful for tracking approximate frequencies of items (``object`` or ``string``) with optional associated +integer counts that are members of a multiset of such items. +The true frequency of an item is defined to be the sum of associated counts. + +This implementation provides the following capabilities: + +* Estimate the *frequency* of an item. +* Return *upper* and *lower bounds* of any item, such that the true frequency is always between the upper and lower bounds. +* Return a global *maximum error* that holds for all items in the stream. +* Return an array of frequent items that qualify either a *NO_FALSE_POSITIVES* or a *NO_FALSE_NEGATIVES* error type. +* *Merge* itself with another sketch object created from this class. +* *Serialize/Deserialize* to/from a byte array. + +**Space Usage** + +The sketch is initialized with a maximum map size, ``maxMapSize``, that specifies the maximum physical length of the internal hash map of the form ``(object item, int count)``. +The maximum map size is always a power of 2, defined through the variables ``lg_max_map_size``. + +The hash map starts at a very small size (8 entries) and grows as needed up to the specified maximum map size. + +Excluding external space required for the item objects, the internal memory space usage of this sketch is ``18 * mapSize`` bytes (assuming 8 bytes for each reference), +plus a small constant number of additional bytes. +The internal memory space usage of this sketch will never exceed ``18 * maxMapSize`` bytes, plus a small constant number of additional bytes. + +**Maximum Capacity of the Sketch** + +The ``LOAD_FACTOR`` for the hash map is internally set at :math:`75\%`, which means at any time the map capacity of ``(item, count)`` pairs is ``mapCap = 0.75 * mapSize``. +The maximum capacity of ``(item, count)`` pairs of the sketch is ``maxMapCap = 0.75 * maxMapSize``. + +**Updating the sketch with ``(item, count)`` pairs** + +If the item is found in the hash map, the mapped count field (the "counter") is incremented by the incoming count; otherwise, a new counter ``(item, count)`` pair is created. +If the number of tracked counters reaches the maximum capacity of the hash map, the sketch decrements all of the counters (by an approximately computed median) +and removes any non-positive counters. + +**Accuracy** + +If fewer than ``0.75 * maxMapSize`` different items are inserted into the sketch, the estimated frequencies returned by the sketch will be exact. + +The logic of the frequent items sketch is such that the stored counts and true counts are never too different. +More specifically, for any item, the sketch can return an estimate of the true frequency of item, along with upper and lower bounds on the frequency (that hold deterministically). + +For this implementation and for a specific active item, it is guaranteed that the true frequency will be between the Upper Bound (UB) and the Lower Bound (LB) computed for that item. +Specifically, ``(UB- LB) ≤ W * epsilon``, where :math:`W` denotes the sum of all item counts, and :math:`epsilon = 3.5/M`, where :math:`epsilon = M` is the maxMapSize. + +This is a worst-case guarantee that applies to arbitrary inputs. +For inputs typically seen in practice, ``(UB-LB)`` is usually much smaller. + +**Background** + +This code implements a variant of what is commonly known as the "Misra-Gries algorithm". +Variants of it were discovered and rediscovered and redesigned several times over the years: + +* *Finding repeated elements*, Misra, Gries, 1982 +* *Frequency estimation of Internet packet streams with limited space* Demaine, Lopez-Ortiz, Munro, 2002 +* *A simple algorithm for finding frequent elements in streams and bags* Karp, Shenker, Papadimitriou, 2003 +* *Efficient Computation of Frequent and Top-k Elements in Data Streams* Metwally, Agrawal, Abbadi, 2006 + + +For speed, we do employ some randomization that introduces a small probability that our proof of the worst-case bound might not apply to a given run. +However, we have ensured that this probability is extremely small. +For example, if the stream causes one table purge (rebuild), our proof of the worst-case bound applies with a probability of at least `1 - 1E-14`. +If the stream causes ``1E9`` purges, our proof applies with a probability of at least ``1 - 1E-5``. + +There are two flavors of Frequent Items Sketches, one with generic items (objects) and another specific to strings. +The string version is a legacy name from before the library supported generic objects and is retained +only for backwards compatibility. + +.. note:: + The :class:`frequent_items_sketch` uses an input object's ``__hash__`` and ``__eq__`` methods. + +.. note:: + Serializing and deserializing the :class:`frequent_items_sketch` requires the use of a :class:`PyObjectSerDe`. + +.. autoclass:: frequent_items_error_type + + .. autoattribute:: NO_FALSE_POSITIVES + :annotation: : Returns only true positives but may miss some heavy hitters. + + .. autoattribute:: NO_FALSE_NEGATIVES + :annotation: : Does not miss any heavy hitters but may return false positives. + + +.. autoclass:: frequent_items_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_epsilon_for_lg_size, get_apriori_error + :member-order: groupwise + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_epsilon_for_lg_size + .. automethod:: get_apriori_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + + +.. autoclass:: frequent_strings_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_epsilon_for_lg_size, get_apriori_error + :member-order: groupwise + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_epsilon_for_lg_size + .. automethod:: get_apriori_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ diff --git a/docs/main/_sources/frequency/index.rst.txt b/docs/main/_sources/frequency/index.rst.txt new file mode 100644 index 00000000..3cd3dfa5 --- /dev/null +++ b/docs/main/_sources/frequency/index.rst.txt @@ -0,0 +1,15 @@ +Frequency Sketches +================== + +Frequency estimation involves determining how often an item has been seen in a stream. The library currently +offers two types of sketches for frequency estimation, one of which has two closely-related variants. + + * :class:`frequent_items_sketch`: Identifies the *Top K* or *heavy hitters* in a stream, those items whose weight is above a certain percentage of the entire stream. Does not necessarily provide an estimate for most items outside the heavy hitters. + * :class:`frequent_strings_sketch`: Like the items version but containing snly strings (an implementation from before the library handled generic objects). + * :class:`count_min_sketch`: Provides an estimate for any item, regardless of relative weight, but does not maintain a list of the heaviest items. + +.. toctree:: + :maxdepth: 1 + + frequent_items + count_min_sketch \ No newline at end of file diff --git a/docs/main/_sources/helper/index.rst.txt b/docs/main/_sources/helper/index.rst.txt new file mode 100644 index 00000000..182b8e85 --- /dev/null +++ b/docs/main/_sources/helper/index.rst.txt @@ -0,0 +1,24 @@ +Helper Classes +============== + +.. currentmodule:: dataksetches + +These classes are required for certain sketches or specific +functionality within sketches. +Some of them are abstract base classes, but in those cases there is at +least one reference example of a concrete class. + + * :class:`serde` is used when serializing and deserializing sketches. + * :class:`jaccard` is used to compute the Jaccard similarity between pairs of theta or tuple sketches. + * :class:`tuple_policy` is required to use a :class:`tuple_sketch` by specifying how summaries are combined. + * :func:`ks_test` performs a Kolmogorov-Smirnov test on absolute-error quantiles family sketches. + * :class:`kernel_function` is required when using a :class:`kernel_sketch` for Kernel Density Estimation. + +.. toctree:: + :maxdepth: 1 + + serde + jaccard + tuple_policy + ks_test + kernel diff --git a/docs/main/_sources/helper/jaccard.rst.txt b/docs/main/_sources/helper/jaccard.rst.txt new file mode 100644 index 00000000..d3b9bfa3 --- /dev/null +++ b/docs/main/_sources/helper/jaccard.rst.txt @@ -0,0 +1,23 @@ +Jaccard Similarity +################## + +.. currentmodule:: datasketches + +These objects provide measures related to the `Jaccard similarity `_ +of :class:`theta_sketch` and :class:`tuple_sketch` objects. + +Note that there are separate classes to be used for theta and tuple sketches. + +.. autoclass:: theta_jaccard_similarity + + .. automethod:: jaccard + .. automethod:: exactly_equal + .. automethod:: similarity_test + .. automethod:: dissimilarity_test + +.. autoclass:: tuple_jaccard_similarity + + .. automethod:: jaccard + .. automethod:: exactly_equal + .. automethod:: similarity_test + .. automethod:: dissimilarity_test diff --git a/docs/main/_sources/helper/kernel.rst.txt b/docs/main/_sources/helper/kernel.rst.txt new file mode 100644 index 00000000..bdc2c729 --- /dev/null +++ b/docs/main/_sources/helper/kernel.rst.txt @@ -0,0 +1,21 @@ +Kernel Function +############### + +.. currentmodule:: datasketches + +A `kernel function `_ is a specific type of +mathematical funciton that is particularly useful in certain machine learning and pattern recognition +contexts. The :class:`density_sketch` performs approximate +`kernel density estimation `_ which, unsurprisingly, +relies on the use of such a kernel function. + +The library provides an abstract base class :class:`KernelFunction` and an example implementation of a +Gaussian (also known as a Radial Basis Function) kernel. Custom classes must override the base class +and provide a floating point value as a score indicating the similarity of two input vectors. + +.. autoclass:: KernelFunction + + .. automethod:: __call__ + +.. autoclass:: GaussianKernel + :show-inheritance: \ No newline at end of file diff --git a/docs/main/_sources/helper/ks_test.rst.txt b/docs/main/_sources/helper/ks_test.rst.txt new file mode 100644 index 00000000..c9bc19b0 --- /dev/null +++ b/docs/main/_sources/helper/ks_test.rst.txt @@ -0,0 +1,14 @@ +Kolmogorov-Smirnov Test +####################### + +.. currentmodule:: datasketches + +A `Kolmogorov-Smirnov Test `_` is +a test of equality of two distributions to determine if they are likely to have come from the same +underlying distribution. +The DataSketches library provides a modified form of the test that takes into account the error +in each underlying sketch in the analysis. + +Currently, the test assumes both input sketches are of the same family and data type. + +.. autofunction:: ks_test diff --git a/docs/main/_sources/helper/serde.rst.txt b/docs/main/_sources/helper/serde.rst.txt new file mode 100644 index 00000000..ccac1d84 --- /dev/null +++ b/docs/main/_sources/helper/serde.rst.txt @@ -0,0 +1,34 @@ +Serialize/Deserialize (SerDe) +############################# + +.. currentmodule:: datasketches + +A SerDe is a class used to serialize items sketches to a :class:`bytes` object in binary. +Several example SerDes are provided as references. + +The use of binary-compatible SerDes in different languages is critical for cross-language compatibility. + +Each implementation must extend the :class:`PyObjectSerDe` class and override all three of its methods. + +.. autoclass:: PyObjectSerDe + + .. automethod:: get_size + .. automethod:: to_bytes + .. automethod:: from_bytes + + +The provided SerDes are: + +.. autoclass:: PyStringsSerDe + :show-inheritance: + +.. autoclass:: PyIntsSerDe + :show-inheritance: + +.. autoclass:: PyLongsSerDe + :show-inheritance: + +.. autoclass:: PyFloatsSerDe + :show-inheritance: + +.. autoclass:: PyDoublesSerDe diff --git a/docs/main/_sources/helper/tuple_policy.rst.txt b/docs/main/_sources/helper/tuple_policy.rst.txt new file mode 100644 index 00000000..3f5781f2 --- /dev/null +++ b/docs/main/_sources/helper/tuple_policy.rst.txt @@ -0,0 +1,25 @@ +Tuple Policy +############ + +.. currentmodule:: datasketches + +A Tuple Policy is needed when using a :class:`tuple_sketch` in order to specify how the +summary values should be created, updated, combined, or intersected. A summary can consist of +any python object. + +Each implementation must extend the abstract base class :class:`TuplePolicy`. + +.. autoclass:: TuplePolicy + + .. automethod:: create_summary + .. automethod:: update_summary + .. automethod:: __call__ + +.. autoclass:: AccumulatorPolicy + :show-inheritance: + +.. autoclass:: MinIntPolicy + :show-inheritance: + +.. autoclass:: MaxIntPolicy + :show-inheritance: diff --git a/docs/main/_sources/index.rst.txt b/docs/main/_sources/index.rst.txt new file mode 100644 index 00000000..b683e1fd --- /dev/null +++ b/docs/main/_sources/index.rst.txt @@ -0,0 +1,73 @@ +.. datasketches documentation master file, created by + sphinx-quickstart on Tue Jul 25 11:04:59 2023. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Apache DataSketches +================================================= + +**DataSketches** are highly-efficient algorithms to analyze big data quickly. + + +Counting Distincts +################## +.. + maxdepth: 1 means only the heading is printed in the contents +.. toctree:: + :maxdepth: 2 + + distinct_counting/index + +Quantile Estimation +################### + +.. toctree:: + :maxdepth: 2 + + quantiles/index + +Frequency Sketches +################## +This problem may also be known as **heavy hitters** or **TopK** + +.. toctree:: + :maxdepth: 2 + + frequency/index + +Vector Sketches +############### + +.. toctree:: + :maxdepth: 2 + + vector/index + + +Random Sampling +############### + +.. toctree:: + :maxdepth: 2 + + sampling/index + +Helper Classes +############## + +.. toctree:: + :maxdepth: 2 + + helper/index + + +.. note:: + + This project is under active development. + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/docs/main/_sources/quantiles/index.rst.txt b/docs/main/_sources/quantiles/index.rst.txt new file mode 100644 index 00000000..bf53ea36 --- /dev/null +++ b/docs/main/_sources/quantiles/index.rst.txt @@ -0,0 +1,30 @@ +Quantiles Sketches +================== + +Quantile estimation is useful for understanding the distribution of data values in a stream. The sketches currently +in the library are designed to answer queries about the `rank` of an item in the stream of items. That is, when +applying a global ordering on all the items, what is the portion of items seen so far that are less than (alternatively, +less-than-or-equal-to) the given item. Using straightforward logic, they can also estimate the item at a given rank +in the stream. + +These sketches may be used to compute approximate histograms, Probability Mass Functions (PMFs), or +Cumulative Distribution Functions (CDFs). + +The library provides four types of quantiles sketches, three of which have generic items as well as versions +specific to a given numeric type (e.g. integer or floating point values). Those three types provide error +bounds on rank estimation with proven probabilistic error distributions. t-digest is a heuristic-based sketch +that works only on numeric data, and while the error properties are not guaranteed, the sketch typically +does a good job with small storage. + + * KLL: Provides uniform rank estimation error over the entire range. + * REQ: Provides relative rank error estimates, which decreases approaching either the high or low end values. + * t-digest: Relative rank error estimates, heuristic-based without guarantees but quite compact with generally very good error properties. + * Classic quantiles: Largely deprecated in favor of KLL, also provides uniform rank estimation error. Included largely for backwards compatibility with historic data. + +.. toctree:: + :maxdepth: 1 + + kll + req + tdigest + quantiles_depr \ No newline at end of file diff --git a/docs/main/_sources/quantiles/kll.rst.txt b/docs/main/_sources/quantiles/kll.rst.txt new file mode 100644 index 00000000..ab7f0c46 --- /dev/null +++ b/docs/main/_sources/quantiles/kll.rst.txt @@ -0,0 +1,166 @@ +KLL Sketch +---------- + +.. currentmodule:: datasketches + +Implementation of a very compact quantiles sketch with lazy compaction scheme +and nearly optimal accuracy per retained item. +See `Optimal Quantile Approximation in Streams`. + +This is a stochastic streaming sketch that enables near real-time analysis of the +approximate distribution of items from a very large stream in a single pass, requiring only +that the items are comparable. +The analysis is obtained using `get_quantile()` function or the +inverse functions `get_rank()`, `get_pmf()` (Probability Mass Function), and `get_cdf()` +(Cumulative Distribution Function). + +Given an input stream of `N` items, the `natural rank` of any specific +item is defined as its index `(1 to N)` in inclusive mode +or `(0 to N-1)` in exclusive mode +in the hypothetical sorted stream of all `N` input items. + +The `normalized rank` (`rank`) of any specific item is defined as its +`natural rank` divided by `N`. +Thus, the `normalized rank` is between zero and one. +In the documentation for this sketch `natural rank` is never used so any +reference to just `rank` should be interpreted to mean `normalized rank`. + +This sketch is configured with a parameter `k`, which affects the size of the sketch +and its estimation error. + +The estimation error is commonly called `epsilon` (or `eps`) and is a fraction +between zero and one. Larger values of `k` result in smaller values of `epsilon`. +Epsilon is always with respect to the rank and cannot be applied to the +corresponding items. + +The relationship between the `normalized rank` and the corresponding items can be viewed +as a two-dimensional monotonic plot with the `normalized rank` on one axis and the +corresponding items on the other axis. If the y-axis is specified as the item-axis and +the x-axis as the `normalized rank`, then `y = get_quantile(x)` is a monotonically +increasing function. + +The function `get_quantile(rank)` translates ranks into +corresponding quantiles. The functions `get_rank(item)`, +`get_cdf(...)` (Cumulative Distribution Function), and `get_pmf(...)` +(Probability Mass Function) perform the opposite operation and translate items into ranks. + +The `get_pmf(...)` function has about 13 to 47% worse rank error (depending +on `k`) than the other queries because the mass of each "bin" of the PMF has +"double-sided" error from the upper and lower edges of the bin as a result of a subtraction, +as the errors from the two edges can sometimes add. + +The default `k` of 200 yields a "single-sided" `epsilon` of about 1.33% and a +"double-sided" (PMF) `epsilon` of about 1.65%. + +A `get_quantile(rank)` query has the following guarantees: +- Let `q = get_quantile(r)` where `r` is the rank between zero and one. +- The quantile `q` will be an item from the input stream. +- Let `true_rank` be the true rank of `q` derived from the hypothetical sorted +stream of all `N` items. +- Let `eps = get_normalized_rank_error(false)`. +- Then `r - eps ≤ true_rank ≤ r + eps` with a confidence of 99%. Note that the +error is on the rank, not the quantile. + +A `get_rank(item)` query has the following guarantees: +- Let `r = get_rank(i)` where `i` is an item between the min and max items of +the input stream. +- Let `true_rank` be the true rank of `i` derived from the hypothetical sorted +stream of all `N` items. +- Let `eps = get_normalized_rank_error(false)`. +- Then `r - eps ≤ true_rank ≤ r + eps` with a confidence of 99%. + +A `get_pmf()` query has the following guarantees: +- Let `{r1, r2, ..., r(m+1)} = get_pmf(s1, s2, ..., sm)` where `s1, s2` are +split points (items from the input domain) between the min and max items of +the input stream. +- Let `mass_i = estimated mass between s_i and s_i+1`. +- Let `true_mass` be the true mass between the items of `s_i`, +`s_i+1` derived from the hypothetical sorted stream of all `N` items. +- Let `eps = get_normalized_rank_error(true)`. +- then `mass - eps ≤ true_mass ≤ mass + eps` with a confidence of 99%. +- `r(m+1)` includes the mass of all points larger than `s_m`. + +A `get_cdf(...)` query has the following guarantees; +- Let `{r1, r2, ..., r(m+1)} = get_cdf(s1, s2, ..., sm)` where `s1, s2, ...` are +split points (items from the input domain) between the min and max items of +the input stream. +- Let `mass_i = r_(i+1) - r_i`. +- Let `true_mass` be the true mass between the true ranks of `s_i`, +`s_i+1` derived from the hypothetical sorted stream of all `N` items. +- Let `eps = get_normalized_rank_error(true)`. +- then `mass - eps ≤ true_mass ≤ mass + eps` with a confidence of 99%. +- `1 - r(m+1)` includes the mass of all points larger than `s_m`. + +From the above, it might seem like we could make some estimates to bound the +`item` returned from a call to `get_quantile()`. The sketch, however, does not +let us derive error bounds or confidences around items. Because errors are independent, we +can approximately bracket a value as shown below, but there are no error estimates available. +Additionally, the interval may be quite large for certain distributions. +- Let `q = get_quantile(r)`, the estimated quantile of rank `r`. +- Let `eps = get_normalized_rank_error(false)`. +- Let `q_lo = estimated quantile of rank (r - eps)`. +- Let `q_hi = estimated quantile of rank (r + eps)`. +- Then `q_lo ≤ q ≤ q_hi`, with 99% confidence. + +.. note:: + For the :class:`kll_items_sketch`, objects must be comparable with ``__lt__``. + +.. note:: + Serializing and deserializing a :class:`kll_items_sketch` requires the use of a :class:`PyObjectSerDe`. + + +.. autoclass:: kll_ints_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_normalized_rank_error + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_normalized_rank_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: kll_floats_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_normalized_rank_error + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_normalized_rank_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: kll_doubles_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_normalized_rank_error + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_normalized_rank_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: kll_items_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_normalized_rank_error + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_normalized_rank_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ diff --git a/docs/main/_sources/quantiles/quantiles_depr.rst.txt b/docs/main/_sources/quantiles/quantiles_depr.rst.txt new file mode 100644 index 00000000..18dd5df6 --- /dev/null +++ b/docs/main/_sources/quantiles/quantiles_depr.rst.txt @@ -0,0 +1,106 @@ +Quantiles Sketch (Deprecated) +----------------------------- + +.. currentmodule:: datasketches + +This is a deprecated quantiles sketch that is included for cross-language compatibility. +Most new projects will favor the KLL sketch over this one, or the REQ sketch for higher accuracy +at the very edge of a distribution. + +This is a stochastic streaming sketch that enables near-real time analysis of the +approximate distribution from a very large stream in a single pass. +The analysis is obtained using `get_rank()` and `get_quantile()` functions, +the Probability Mass Function from `get_pmf()`` and the Cumulative Distribution Function from `get_cdf`. + +Consider a large stream of one million values such as packet sizes coming into a network node. +The natural rank of any specific size value is its index in the hypothetical sorted +array of values. +The normalized rank is the natural rank divided by the stream size, +in this case one million. +The value corresponding to the normalized rank of `0.5` represents the 50th percentile or median +value of the distribution, or `get_quantile(0.5)`. +Similarly, the 95th percentile is obtained from `get_quantile(0.95)`. + +From the min and max values, for example, 1 and 1000 bytes, +you can obtain the PMF from `get_pmf(100, 500, 900)` that will result in an array of +4 fractional values such as {.4, .3, .2, .1}, which means that +40% of the values were < 100, +30% of the values were ≥ 100 and < 500, +20% of the values were ≥ 500 and < 900, and +10% of the values were ≥ 900. +A frequency histogram can be obtained by multiplying these fractions by `get_n()`, +which is the total count of values received. +The `get_cdf()`` works similarly, but produces the cumulative distribution instead. + +As of November 2021, this implementation produces serialized sketches which are binary-compatible +with the equivalent Java implementation only when template parameter T = double +(64-bit double precision values). + +The accuracy of this sketch is a function of the configured value `k`, which also affects +the overall size of the sketch. Accuracy of this quantile sketch is always with respect to +the normalized rank. A `k` of 128 produces a normalized, rank error of about 1.7%. +For example, the median item returned from `get_quantile(0.5)` will be between the actual items +from the hypothetically sorted array of input items at normalized ranks of 0.483 and 0.517, with +a confidence of about 99%. + +.. note:: + For the :class:`quantiles_items_sketch`, objects must be comparable with ``__lt__``. + +.. note:: + Serializing and deserializing a :class:`quantiles_items_sketch` requires the use of a :class:`PyObjectSerDe`. + +.. autoclass:: quantiles_ints_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_normalized_rank_error + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_normalized_rank_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: quantiles_floats_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_normalized_rank_error + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_normalized_rank_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: quantiles_doubles_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_normalized_rank_error + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_normalized_rank_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: quantiles_items_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_normalized_rank_error + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_normalized_rank_error + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ diff --git a/docs/main/_sources/quantiles/req.rst.txt b/docs/main/_sources/quantiles/req.rst.txt new file mode 100644 index 00000000..3f63e01e --- /dev/null +++ b/docs/main/_sources/quantiles/req.rst.txt @@ -0,0 +1,79 @@ +Relative Error Quantiles (REQ) Sketch +------------------------------------- + +.. currentmodule:: datasketches + +This is an implementation based on the `paper `_ "Relative Error Streaming Quantiles" by Graham Cormode, Zohar Karnin, Edo Liberty, Justin Thaler, Pavel Veselý, and loosely derived from a Python prototype written by Pavel Veselý. + +This implementation differs from the algorithm described in the paper in the following: + +The algorithm requires no upper bound on the stream length. +Instead, each relative-compactor counts the number of compaction operations performed so far (via variable state). +Initially, the relative-compactor starts with `INIT_NUMBER_OF_SECTIONS`. +Each time the number of compactions `(variable state) exceeds 2^{numSections - 1}`, we double `numSections`. +Note that after merging the sketch with another one variable state may not correspond to the number of compactions performed at a particular level, however, +since the state variable never exceeds the number of compactions, the guarantees of the sketch remain valid. + +The size of each section (variable `k` and `section_size` in the code and parameter `k` in the paper) is +initialized with a number set by the user via variable `k`. +When the number of sections doubles, we decrease section_size by a factor of `sqrt(2)`. +This is applied at each level separately. +Thus, when we double the number of sections, the nominal compactor size increases by a factor of approx. `sqrt(2) (+/- rounding)`. + +The merge operation here does not perform "special compactions", which are used in the paper to allow for a tight mathematical analysis of the sketch. +This implementation provides a number of capabilities not discussed in the paper or provided in the Python prototype. + +The Python prototype only implemented high accuracy for low ranks. This implementation provides the user with the ability to +choose either high rank accuracy or low rank accuracy at the time of sketch construction. +The Python prototype only implemented a comparison criterion of `INCLUSIVE`. +This implementation allows the user to use both the `INCLUSIVE` criterion and the `EXCLUSIVE` criterion. +This implementation provides extensive debug visibility into the operation of the sketch with two levels of detail output. +This is not only useful for debugging, but is a powerful tool to help users understand how the sketch works. + +.. note:: + For the :class:`req_items_sketch`, objects must be comparable with ``__lt__``. + +.. note:: + Serializing and deserializing a :class:`req_items_sketch` requires the use of a :class:`PyObjectSerDe`. + +.. autoclass:: req_ints_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_RSE + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_RSE + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: req_floats_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_RSE + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_RSE + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: req_items_sketch + :members: + :undoc-members: + :exclude-members: deserialize, get_RSE + + .. rubric:: Static Methods: + + .. automethod:: deserialize + .. automethod:: get_RSE + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ diff --git a/docs/main/_sources/quantiles/tdigest.rst.txt b/docs/main/_sources/quantiles/tdigest.rst.txt new file mode 100644 index 00000000..f697cbe9 --- /dev/null +++ b/docs/main/_sources/quantiles/tdigest.rst.txt @@ -0,0 +1,52 @@ +t-digest +-------- + +.. currentmodule:: datasketches + +The implementation in this library is based on the MergingDigest described in +`Computing Extremely Accurate Quantiles Using t-Digests `_ by Ted Dunning and Otmar Ertl. + +The implementation in this library has a few differences from the reference implementation associated with that paper: + +* Merge does not modify the input +* Derialization similar to other sketches in this library, although reading the reference implementation format is supported + +Unlike all other algorithms in the library, t-digest is empirical and has no mathematical basis for estimating its error +and its results are dependent on the input data. However, for many common data distributions, it can produce excellent results. +t-digest also operates only on numeric data and, unlike the quantiles family algorithms in the library which return quantile +approximations from the input domain, t-digest interpolates values and will hold and return data points not seen in the input. + +The closest alternative to t-digest in this library is REQ sketch. It prioritizes one chosen side of the rank domain: +either low rank accuracy or high rank accuracy. t-digest (in this implementation) prioritizes both ends of the rank domain +and has lower accuracy towards the middle of the rank domain (median). + +Measurements show that t-digest is slightly biased (tends to underestimate low ranks and overestimate high ranks), while still +doing very well close to the extremes. The effect seems to be more pronounced with more input values. + +For more information on the performance characteristics, see `the Datasketches page on t-digest `_. + +.. autoclass:: tdigest_float + :members: + :undoc-members: + :exclude-members: deserialize + + .. rubric:: Static Methods: + + .. automethod:: deserialize + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: tdigest_double + :members: + :undoc-members: + :exclude-members: deserialize + + .. rubric:: Static Methods: + + .. automethod:: deserialize + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ diff --git a/docs/main/_sources/sampling/ebpps.rst.txt b/docs/main/_sources/sampling/ebpps.rst.txt new file mode 100644 index 00000000..b2253209 --- /dev/null +++ b/docs/main/_sources/sampling/ebpps.rst.txt @@ -0,0 +1,33 @@ +Exact and Bounded, Probabilitiy Proportional to Size (EBPPS) Sampling +--------------------------------------------------------------------- + +.. currentmodule:: datasketches + +An EBPPS sketch produces a randome sample of data from a stream of items, ensuring that the probability +of including an item is always exactly equal to the item's size. The size of an item is defined as its +weight relative to the total weight of all items seen so far by the sketch. In contrast to VarOpt sampling, +this sketch may return fewer than `k` items in order to keep the probability of including an item strictly +proportional to its size. + +This sketch is based on: B. Hentschel, P. J. Haas, Y. Tian +"Exact PPS Sampling with Bounded Sample Size", +Information Processing Letters, 2023. + +EBPPS sampling is related to reservoir sampling, but handles unequal item weights. +Feeding the sketch items with a uniform weight value will produce a sample equivalent to reservoir sampling. + +.. note:: + Serializing and deserializing this sketch requires the use of a :class:`PyObjectSerDe`. + +.. autoclass:: ebpps_sketch + :members: + :undoc-members: + :exclude-members: deserialize + + .. rubric:: Static Methods: + + .. automethod:: deserialize + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ diff --git a/docs/main/_sources/sampling/index.rst.txt b/docs/main/_sources/sampling/index.rst.txt new file mode 100644 index 00000000..fca6c3ce --- /dev/null +++ b/docs/main/_sources/sampling/index.rst.txt @@ -0,0 +1,21 @@ +Random Sampling Sketches +======================== + +.. currentmodule:: datasketches + +These sketches are used to randomly sample items. The length of the input +stream does not need to be known in advance. + +Both VarOpt (Variance Optimal) and EBPPS (Exact and Bounded, +Probability Proportional to Size) sketches will include sample items based on +each item's weight relative to the weight of the entire stream but +they differ in details: + + * :class:`ebpps_sketch` ensures that the probability of including an item is always exactly proportional to the item's weight. + * :class:`var_opt_sketch` optimizes for applying a predicate to the resulting sample such that the variance of the subset sum after applying the predicate is minimized, even if the inclusion probability differs somewhat from being proportional to the item's weight. + +.. toctree:: + :maxdepth: 1 + + varopt + ebpps diff --git a/docs/main/_sources/sampling/varopt.rst.txt b/docs/main/_sources/sampling/varopt.rst.txt new file mode 100644 index 00000000..d837835e --- /dev/null +++ b/docs/main/_sources/sampling/varopt.rst.txt @@ -0,0 +1,42 @@ +Variance Optimal Sampling (VarOpt) +---------------------------------- + +.. currentmodule:: datasketches + +A VarOpt sketch samples data from a stream of items. The sketch is desinged for optimal (minimum) +variance when querying the sketch to estimate subset sums of items matching a provided predicate. +The sketch will produce a sample of size `k` (or smaller if fewer items have been presented), with +the probability of including an item roughly corresponding it the item's weight relative to the total +weight of all items presented to the sketch. + +VarOpt sampling is related to reservoir sampling, with improved error bounds for subset sum estimation. +Feeding the sketch items with a uniform weight value will produce a sample equivalent to reservoir sampling. + +.. note:: + Serializing and deserializing this sketch requires the use of a :class:`PyObjectSerDe`. + +.. autoclass:: var_opt_sketch + :members: + :undoc-members: + :exclude-members: deserialize + + .. rubric:: Static Methods: + + .. automethod:: deserialize + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ + +.. autoclass:: var_opt_union + :members: + :undoc-members: + :exclude-members: deserialize + + .. rubric:: Static Methods: + + .. automethod:: deserialize + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ diff --git a/docs/main/_sources/vector/density_sketch.rst.txt b/docs/main/_sources/vector/density_sketch.rst.txt new file mode 100644 index 00000000..07d83181 --- /dev/null +++ b/docs/main/_sources/vector/density_sketch.rst.txt @@ -0,0 +1,28 @@ +Density Sketch +-------------- + +.. currentmodule:: datasketches + +Builds a coreset from the given set of input points. +Provides density estimate at a given point. + +Based on the following paper: Zohar Karnin, Edo Liberty +"Discrepancy, Coresets, and Sketches in Machine Learning" +https://proceedings.mlr.press/v99/karnin19a/karnin19a.pdf + +Inspired by the following implementation: https://github.com/edoliberty/streaming-quantiles/blob/f688c8161a25582457b0a09deb4630a81406293b/gde.py + +Requires the use of a :class:`KernelFunction` to compute the distance between two vectors. + +.. autoclass:: density_sketch + :members: + :undoc-members: + :exclude-members: deserialize + + .. rubric:: Static Methods: + + .. automethod:: deserialize + + .. rubric:: Non-static Methods: + + .. automethod:: __init__ diff --git a/docs/main/_sources/vector/index.rst.txt b/docs/main/_sources/vector/index.rst.txt new file mode 100644 index 00000000..1b83a43c --- /dev/null +++ b/docs/main/_sources/vector/index.rst.txt @@ -0,0 +1,12 @@ +Vector Sketches +================== + +.. currentmodule:: dataksetches + +These sketches are designed to accept vector inputs. For now, the library provides only the +:class:`density_sketch` for Kernel Density Estimation. + +.. toctree:: + :maxdepth: 1 + + density_sketch \ No newline at end of file diff --git a/docs/main/_static/_sphinx_javascript_frameworks_compat.js b/docs/main/_static/_sphinx_javascript_frameworks_compat.js new file mode 100644 index 00000000..81415803 --- /dev/null +++ b/docs/main/_static/_sphinx_javascript_frameworks_compat.js @@ -0,0 +1,123 @@ +/* Compatability shim for jQuery and underscores.js. + * + * Copyright Sphinx contributors + * Released under the two clause BSD licence + */ + +/** + * small helper function to urldecode strings + * + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL + */ +jQuery.urldecode = function(x) { + if (!x) { + return x + } + return decodeURIComponent(x.replace(/\+/g, ' ')); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s === 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node, addItems) { + if (node.nodeType === 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && + !jQuery(node.parentNode).hasClass(className) && + !jQuery(node.parentNode).hasClass("nohighlight")) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.className = className; + } + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + if (isInSVG) { + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + var bbox = node.parentElement.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": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} diff --git a/docs/main/_static/basic.css b/docs/main/_static/basic.css new file mode 100644 index 00000000..7ebbd6d0 --- /dev/null +++ b/docs/main/_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/docs/main/_static/css/badge_only.css b/docs/main/_static/css/badge_only.css new file mode 100644 index 00000000..88ba55b9 --- /dev/null +++ b/docs/main/_static/css/badge_only.css @@ -0,0 +1 @@ +.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions .rst-other-versions .rtd-current-item{font-weight:700}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}#flyout-search-form{padding:6px} \ No newline at end of file diff --git a/docs/main/_static/css/fonts/Roboto-Slab-Bold.woff b/docs/main/_static/css/fonts/Roboto-Slab-Bold.woff new file mode 100644 index 00000000..6cb60000 Binary files /dev/null and b/docs/main/_static/css/fonts/Roboto-Slab-Bold.woff differ diff --git a/docs/main/_static/css/fonts/Roboto-Slab-Bold.woff2 b/docs/main/_static/css/fonts/Roboto-Slab-Bold.woff2 new file mode 100644 index 00000000..7059e231 Binary files /dev/null and b/docs/main/_static/css/fonts/Roboto-Slab-Bold.woff2 differ diff --git a/docs/main/_static/css/fonts/Roboto-Slab-Regular.woff b/docs/main/_static/css/fonts/Roboto-Slab-Regular.woff new file mode 100644 index 00000000..f815f63f Binary files /dev/null and b/docs/main/_static/css/fonts/Roboto-Slab-Regular.woff differ diff --git a/docs/main/_static/css/fonts/Roboto-Slab-Regular.woff2 b/docs/main/_static/css/fonts/Roboto-Slab-Regular.woff2 new file mode 100644 index 00000000..f2c76e5b Binary files /dev/null and b/docs/main/_static/css/fonts/Roboto-Slab-Regular.woff2 differ diff --git a/docs/main/_static/css/fonts/fontawesome-webfont.eot b/docs/main/_static/css/fonts/fontawesome-webfont.eot new file mode 100644 index 00000000..e9f60ca9 Binary files /dev/null and b/docs/main/_static/css/fonts/fontawesome-webfont.eot differ diff --git a/docs/main/_static/css/fonts/fontawesome-webfont.svg b/docs/main/_static/css/fonts/fontawesome-webfont.svg new file mode 100644 index 00000000..855c845e --- /dev/null +++ b/docs/main/_static/css/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/main/_static/css/fonts/fontawesome-webfont.ttf b/docs/main/_static/css/fonts/fontawesome-webfont.ttf new file mode 100644 index 00000000..35acda2f Binary files /dev/null and b/docs/main/_static/css/fonts/fontawesome-webfont.ttf differ diff --git a/docs/main/_static/css/fonts/fontawesome-webfont.woff b/docs/main/_static/css/fonts/fontawesome-webfont.woff new file mode 100644 index 00000000..400014a4 Binary files /dev/null and b/docs/main/_static/css/fonts/fontawesome-webfont.woff differ diff --git a/docs/main/_static/css/fonts/fontawesome-webfont.woff2 b/docs/main/_static/css/fonts/fontawesome-webfont.woff2 new file mode 100644 index 00000000..4d13fc60 Binary files /dev/null and b/docs/main/_static/css/fonts/fontawesome-webfont.woff2 differ diff --git a/docs/main/_static/css/fonts/lato-bold-italic.woff b/docs/main/_static/css/fonts/lato-bold-italic.woff new file mode 100644 index 00000000..88ad05b9 Binary files /dev/null and b/docs/main/_static/css/fonts/lato-bold-italic.woff differ diff --git a/docs/main/_static/css/fonts/lato-bold-italic.woff2 b/docs/main/_static/css/fonts/lato-bold-italic.woff2 new file mode 100644 index 00000000..c4e3d804 Binary files /dev/null and b/docs/main/_static/css/fonts/lato-bold-italic.woff2 differ diff --git a/docs/main/_static/css/fonts/lato-bold.woff b/docs/main/_static/css/fonts/lato-bold.woff new file mode 100644 index 00000000..c6dff51f Binary files /dev/null and b/docs/main/_static/css/fonts/lato-bold.woff differ diff --git a/docs/main/_static/css/fonts/lato-bold.woff2 b/docs/main/_static/css/fonts/lato-bold.woff2 new file mode 100644 index 00000000..bb195043 Binary files /dev/null and b/docs/main/_static/css/fonts/lato-bold.woff2 differ diff --git a/docs/main/_static/css/fonts/lato-normal-italic.woff b/docs/main/_static/css/fonts/lato-normal-italic.woff new file mode 100644 index 00000000..76114bc0 Binary files /dev/null and b/docs/main/_static/css/fonts/lato-normal-italic.woff differ diff --git a/docs/main/_static/css/fonts/lato-normal-italic.woff2 b/docs/main/_static/css/fonts/lato-normal-italic.woff2 new file mode 100644 index 00000000..3404f37e Binary files /dev/null and b/docs/main/_static/css/fonts/lato-normal-italic.woff2 differ diff --git a/docs/main/_static/css/fonts/lato-normal.woff b/docs/main/_static/css/fonts/lato-normal.woff new file mode 100644 index 00000000..ae1307ff Binary files /dev/null and b/docs/main/_static/css/fonts/lato-normal.woff differ diff --git a/docs/main/_static/css/fonts/lato-normal.woff2 b/docs/main/_static/css/fonts/lato-normal.woff2 new file mode 100644 index 00000000..3bf98433 Binary files /dev/null and b/docs/main/_static/css/fonts/lato-normal.woff2 differ diff --git a/docs/main/_static/css/theme.css b/docs/main/_static/css/theme.css new file mode 100644 index 00000000..0f14f106 --- /dev/null +++ b/docs/main/_static/css/theme.css @@ -0,0 +1,4 @@ +html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden],audio:not([controls]){display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;text-decoration:none}ins,mark{color:#000}mark{background:#ff0;font-style:italic;font-weight:700}.rst-content code,.rst-content tt,code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:after,q:before{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,ol,ul{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure,form{margin:0}label{cursor:pointer}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{body,html,section{background:none!important}*{box-shadow:none!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}.rst-content .toctree-wrapper>p.caption,h2,h3,p{orphans:3;widows:3}.rst-content .toctree-wrapper>p.caption,h2,h3{page-break-after:avoid}}.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .eqno .headerlink:before,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .eqno .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a button.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-left.toctree-expand,.wy-menu-vertical li button.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .eqno .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a button.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-right.toctree-expand,.wy-menu-vertical li button.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .eqno .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a button.pull-left.toctree-expand,.wy-menu-vertical li.on a button.pull-left.toctree-expand,.wy-menu-vertical li button.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .eqno .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a button.pull-right.toctree-expand,.wy-menu-vertical li.on a button.pull-right.toctree-expand,.wy-menu-vertical li button.pull-right.toctree-expand{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li button.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content .eqno a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content p a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li a button.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content .eqno .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content p .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li button.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content .eqno .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a button.toctree-expand,.btn .wy-menu-vertical li.on a button.toctree-expand,.btn .wy-menu-vertical li button.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content .eqno .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a button.toctree-expand,.nav .wy-menu-vertical li.on a button.toctree-expand,.nav .wy-menu-vertical li button.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .eqno .btn .headerlink,.rst-content .eqno .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p .btn .headerlink,.rst-content p .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn button.toctree-expand,.wy-menu-vertical li.current>a .btn button.toctree-expand,.wy-menu-vertical li.current>a .nav button.toctree-expand,.wy-menu-vertical li .nav button.toctree-expand,.wy-menu-vertical li.on a .btn button.toctree-expand,.wy-menu-vertical li.on a .nav button.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .eqno .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li button.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .eqno .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li button.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .eqno .btn .fa-large.headerlink,.rst-content .eqno .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p .btn .fa-large.headerlink,.rst-content p .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn button.fa-large.toctree-expand,.wy-menu-vertical li .nav button.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .eqno .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li button.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .eqno .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li button.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .eqno .btn .fa-spin.headerlink,.rst-content .eqno .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p .btn .fa-spin.headerlink,.rst-content p .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn button.fa-spin.toctree-expand,.wy-menu-vertical li .nav button.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content .eqno .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li button.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content .eqno .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li button.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content .eqno .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li button.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content .eqno .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini button.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.rst-content section ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.rst-content section ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.rst-content section ul li p:last-child,.rst-content section ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.rst-content section ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.rst-content section ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.rst-content section ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content .section ol.arabic,.rst-content .toctree-wrapper ol,.rst-content .toctree-wrapper ol.arabic,.rst-content section ol,.rst-content section ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol.arabic li,.rst-content .section ol li,.rst-content .toctree-wrapper ol.arabic li,.rst-content .toctree-wrapper ol li,.rst-content section ol.arabic li,.rst-content section ol li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol.arabic li ul,.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content .toctree-wrapper ol.arabic li ul,.rst-content .toctree-wrapper ol li p:last-child,.rst-content .toctree-wrapper ol li ul,.rst-content section ol.arabic li ul,.rst-content section ol li p:last-child,.rst-content section ol li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol.arabic li ul li,.rst-content .section ol li ul li,.rst-content .toctree-wrapper ol.arabic li ul li,.rst-content .toctree-wrapper ol li ul li,.rst-content section ol.arabic li ul li,.rst-content section ol li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs>li{display:inline-block;padding-top:5px}.wy-breadcrumbs>li.wy-breadcrumbs-aside{float:right}.rst-content .wy-breadcrumbs>li code,.rst-content .wy-breadcrumbs>li tt,.wy-breadcrumbs>li .rst-content tt,.wy-breadcrumbs>li code{all:inherit;color:inherit}.breadcrumb-item:before{content:"/";color:#bbb;font-size:13px;padding:0 6px 0 3px}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li button.toctree-expand{display:block;float:left;margin-left:-1.2em;line-height:18px;color:#4d4d4d;border:none;background:none;padding:0}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover button.toctree-expand,.wy-menu-vertical li.on a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand{display:block;line-height:18px;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{padding:.4045em 1.618em .4045em 4.045em}.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{padding:.4045em 1.618em .4045em 5.663em}.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a{padding:.4045em 1.618em .4045em 7.281em}.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a{padding:.4045em 1.618em .4045em 8.899em}.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a{padding:.4045em 1.618em .4045em 10.517em}.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a{padding:.4045em 1.618em .4045em 12.135em}.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a{padding:.4045em 1.618em .4045em 13.753em}.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a{padding:.4045em 1.618em .4045em 15.371em}.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 1.618em .4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 button.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 button.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover button.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active button.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em;max-width:100%}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search .wy-dropdown>aactive,.wy-side-nav-search .wy-dropdown>afocus,.wy-side-nav-search>a:hover,.wy-side-nav-search>aactive,.wy-side-nav-search>afocus{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon,.wy-side-nav-search>a.icon{display:block}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.switch-menus{position:relative;display:block;margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-side-nav-search>div.switch-menus>div.language-switch,.wy-side-nav-search>div.switch-menus>div.version-switch{display:inline-block;padding:.2em}.wy-side-nav-search>div.switch-menus>div.language-switch select,.wy-side-nav-search>div.switch-menus>div.version-switch select{display:inline-block;margin-right:-2rem;padding-right:2rem;max-width:240px;text-align-last:center;background:none;border:none;border-radius:0;box-shadow:none;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-size:1em;font-weight:400;color:hsla(0,0%,100%,.3);cursor:pointer;appearance:none;-webkit-appearance:none;-moz-appearance:none}.wy-side-nav-search>div.switch-menus>div.language-switch select:active,.wy-side-nav-search>div.switch-menus>div.language-switch select:focus,.wy-side-nav-search>div.switch-menus>div.language-switch select:hover,.wy-side-nav-search>div.switch-menus>div.version-switch select:active,.wy-side-nav-search>div.switch-menus>div.version-switch select:focus,.wy-side-nav-search>div.switch-menus>div.version-switch select:hover{background:hsla(0,0%,100%,.1);color:hsla(0,0%,100%,.5)}.wy-side-nav-search>div.switch-menus>div.language-switch select option,.wy-side-nav-search>div.switch-menus>div.version-switch select option{color:#000}.wy-side-nav-search>div.switch-menus>div.language-switch:has(>select):after,.wy-side-nav-search>div.switch-menus>div.version-switch:has(>select):after{display:inline-block;width:1.5em;height:100%;padding:.1em;content:"\f0d7";font-size:1em;line-height:1.2em;font-family:FontAwesome;text-align:center;pointer-events:none;box-sizing:border-box}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .eqno .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content .eqno .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions .rst-other-versions .rtd-current-item{font-weight:700}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}#flyout-search-form{padding:6px}.rst-content .toctree-wrapper>p.caption,.rst-content h1,.rst-content h2,.rst-content h3,.rst-content h4,.rst-content h5,.rst-content h6{margin-bottom:24px}.rst-content img{max-width:100%;height:auto}.rst-content div.figure,.rst-content figure{margin-bottom:24px}.rst-content div.figure .caption-text,.rst-content figure .caption-text{font-style:italic}.rst-content div.figure p:last-child.caption,.rst-content figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center,.rst-content figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img,.rst-content section>a>img,.rst-content section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp,.rst-content div.highlight span.linenos{user-select:none;pointer-events:none}.rst-content div.highlight span.linenos{display:inline-block;padding-left:0;padding-right:12px;margin-right:12px;border-right:1px solid #e6e9ea}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li,.rst-content .toctree-wrapper ol.loweralpha,.rst-content .toctree-wrapper ol.loweralpha>li,.rst-content section ol.loweralpha,.rst-content section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li,.rst-content .toctree-wrapper ol.upperalpha,.rst-content .toctree-wrapper ol.upperalpha>li,.rst-content section ol.upperalpha,.rst-content section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*,.rst-content .toctree-wrapper ol li>*,.rst-content .toctree-wrapper ul li>*,.rst-content section ol li>*,.rst-content section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child,.rst-content .toctree-wrapper ol li>:first-child,.rst-content .toctree-wrapper ul li>:first-child,.rst-content section ol li>:first-child,.rst-content section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child,.rst-content .toctree-wrapper ol li>p,.rst-content .toctree-wrapper ol li>p:last-child,.rst-content .toctree-wrapper ul li>p,.rst-content .toctree-wrapper ul li>p:last-child,.rst-content section ol li>p,.rst-content section ol li>p:last-child,.rst-content section ul li>p,.rst-content section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child,.rst-content .toctree-wrapper ol li>p:only-child,.rst-content .toctree-wrapper ol li>p:only-child:last-child,.rst-content .toctree-wrapper ul li>p:only-child,.rst-content .toctree-wrapper ul li>p:only-child:last-child,.rst-content section ol li>p:only-child,.rst-content section ol li>p:only-child:last-child,.rst-content section ul li>p:only-child,.rst-content section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul,.rst-content .toctree-wrapper ol li>ol,.rst-content .toctree-wrapper ol li>ul,.rst-content .toctree-wrapper ul li>ol,.rst-content .toctree-wrapper ul li>ul,.rst-content section ol li>ol,.rst-content section ol li>ul,.rst-content section ul li>ol,.rst-content section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul,.rst-content .toctree-wrapper ol.simple li>*,.rst-content .toctree-wrapper ol.simple li ol,.rst-content .toctree-wrapper ol.simple li ul,.rst-content .toctree-wrapper ul.simple li>*,.rst-content .toctree-wrapper ul.simple li ol,.rst-content .toctree-wrapper ul.simple li ul,.rst-content section ol.simple li>*,.rst-content section ol.simple li ol,.rst-content section ol.simple li ul,.rst-content section ul.simple li>*,.rst-content section ul.simple li ol,.rst-content section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink{opacity:0;font-size:14px;font-family:FontAwesome;margin-left:.5em}.rst-content .code-block-caption .headerlink:focus,.rst-content .code-block-caption:hover .headerlink,.rst-content .eqno .headerlink:focus,.rst-content .eqno:hover .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink:focus,.rst-content .toctree-wrapper>p.caption:hover .headerlink,.rst-content dl dt .headerlink:focus,.rst-content dl dt:hover .headerlink,.rst-content h1 .headerlink:focus,.rst-content h1:hover .headerlink,.rst-content h2 .headerlink:focus,.rst-content h2:hover .headerlink,.rst-content h3 .headerlink:focus,.rst-content h3:hover .headerlink,.rst-content h4 .headerlink:focus,.rst-content h4:hover .headerlink,.rst-content h5 .headerlink:focus,.rst-content h5:hover .headerlink,.rst-content h6 .headerlink:focus,.rst-content h6:hover .headerlink,.rst-content p.caption .headerlink:focus,.rst-content p.caption:hover .headerlink,.rst-content p .headerlink:focus,.rst-content p:hover .headerlink,.rst-content table>caption .headerlink:focus,.rst-content table>caption:hover .headerlink{opacity:1}.rst-content p a{overflow-wrap:anywhere}.rst-content .wy-table td p,.rst-content .wy-table td ul,.rst-content .wy-table th p,.rst-content .wy-table th ul,.rst-content table.docutils td p,.rst-content table.docutils td ul,.rst-content table.docutils th p,.rst-content table.docutils th ul,.rst-content table.field-list td p,.rst-content table.field-list td ul,.rst-content table.field-list th p,.rst-content table.field-list th ul{font-size:inherit}.rst-content .btn:focus{outline:2px solid}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .citation-reference>span.fn-bracket,.rst-content .footnote-reference>span.fn-bracket{display:none}.rst-content .hlist{width:100%}.rst-content dl dt span.classifier:before{content:" : "}.rst-content dl dt span.classifier-delimiter{display:none!important}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:auto minmax(80%,95%)}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{display:inline-grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{display:grid;grid-template-columns:auto auto minmax(.65rem,auto) minmax(40%,95%)}html.writer-html5 .rst-content aside.citation>span.label,html.writer-html5 .rst-content aside.footnote>span.label,html.writer-html5 .rst-content div.citation>span.label{grid-column-start:1;grid-column-end:2}html.writer-html5 .rst-content aside.citation>span.backrefs,html.writer-html5 .rst-content aside.footnote>span.backrefs,html.writer-html5 .rst-content div.citation>span.backrefs{grid-column-start:2;grid-column-end:3;grid-row-start:1;grid-row-end:3}html.writer-html5 .rst-content aside.citation>p,html.writer-html5 .rst-content aside.footnote>p,html.writer-html5 .rst-content div.citation>p{grid-column-start:4;grid-column-end:5}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{margin-bottom:24px}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.citation>dt>span.brackets:before,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.citation>dt>span.brackets:after,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a{word-break:keep-all}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a:not(:first-child):before,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.citation>dd p,html.writer-html5 .rst-content dl.footnote>dd p{font-size:.9rem}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{padding-left:1rem;padding-right:1rem;font-size:.9rem;line-height:1.2rem}html.writer-html5 .rst-content aside.citation p,html.writer-html5 .rst-content aside.footnote p,html.writer-html5 .rst-content div.citation p{font-size:.9rem;line-height:1.2rem;margin-bottom:12px}html.writer-html5 .rst-content aside.citation span.backrefs,html.writer-html5 .rst-content aside.footnote span.backrefs,html.writer-html5 .rst-content div.citation span.backrefs{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content aside.citation span.backrefs>a,html.writer-html5 .rst-content aside.footnote span.backrefs>a,html.writer-html5 .rst-content div.citation span.backrefs>a{word-break:keep-all}html.writer-html5 .rst-content aside.citation span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content aside.footnote span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content div.citation span.backrefs>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content aside.citation span.label,html.writer-html5 .rst-content aside.footnote span.label,html.writer-html5 .rst-content div.citation span.label{line-height:1.2rem}html.writer-html5 .rst-content aside.citation-list,html.writer-html5 .rst-content aside.footnote-list,html.writer-html5 .rst-content div.citation-list{margin-bottom:24px}html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content aside.footnote-list aside.footnote,html.writer-html5 .rst-content div.citation-list>div.citation,html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content aside.footnote-list aside.footnote code,html.writer-html5 .rst-content aside.footnote-list aside.footnote tt,html.writer-html5 .rst-content aside.footnote code,html.writer-html5 .rst-content aside.footnote tt,html.writer-html5 .rst-content div.citation-list>div.citation code,html.writer-html5 .rst-content div.citation-list>div.citation tt,html.writer-html5 .rst-content dl.citation code,html.writer-html5 .rst-content dl.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c;white-space:normal}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040;overflow-wrap:normal}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}.rst-content dl dd>ol:last-child,.rst-content dl dd>p:last-child,.rst-content dl dd>table:last-child,.rst-content dl dd>ul:last-child{margin-bottom:0}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px;max-width:100%}html.writer-html4 .rst-content dl:not(.docutils) .k,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .k{font-style:italic}html.writer-html4 .rst-content dl:not(.docutils) .descclassname,html.writer-html4 .rst-content dl:not(.docutils) .descname,html.writer-html4 .rst-content dl:not(.docutils) .sig-name,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .sig-name{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#000}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel,.rst-content .menuselection{font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .guilabel,.rst-content .menuselection{border:1px solid #7fbbe3;background:#e7f2fa}.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>.kbd,.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>kbd{color:inherit;font-size:80%;background-color:#fff;border:1px solid #a6a6a6;border-radius:4px;box-shadow:0 2px grey;padding:2.4px 6px;margin:auto 0}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block} \ No newline at end of file diff --git a/docs/main/_static/doctools.js b/docs/main/_static/doctools.js new file mode 100644 index 00000000..0398ebb9 --- /dev/null +++ b/docs/main/_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/docs/main/_static/documentation_options.js b/docs/main/_static/documentation_options.js new file mode 100644 index 00000000..e21c068c --- /dev/null +++ b/docs/main/_static/documentation_options.js @@ -0,0 +1,13 @@ +const DOCUMENTATION_OPTIONS = { + VERSION: '0.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/docs/main/_static/file.png b/docs/main/_static/file.png new file mode 100644 index 00000000..a858a410 Binary files /dev/null and b/docs/main/_static/file.png differ diff --git a/docs/main/_static/fonts/Lato/lato-bold.eot b/docs/main/_static/fonts/Lato/lato-bold.eot new file mode 100644 index 00000000..3361183a Binary files /dev/null and b/docs/main/_static/fonts/Lato/lato-bold.eot differ diff --git a/docs/main/_static/fonts/Lato/lato-bold.ttf b/docs/main/_static/fonts/Lato/lato-bold.ttf new file mode 100644 index 00000000..29f691d5 Binary files /dev/null and b/docs/main/_static/fonts/Lato/lato-bold.ttf differ diff --git a/docs/main/_static/fonts/Lato/lato-bold.woff b/docs/main/_static/fonts/Lato/lato-bold.woff new file mode 100644 index 00000000..c6dff51f Binary files /dev/null and b/docs/main/_static/fonts/Lato/lato-bold.woff differ diff --git a/docs/main/_static/fonts/Lato/lato-bold.woff2 b/docs/main/_static/fonts/Lato/lato-bold.woff2 new file mode 100644 index 00000000..bb195043 Binary files /dev/null and b/docs/main/_static/fonts/Lato/lato-bold.woff2 differ diff --git a/docs/main/_static/fonts/Lato/lato-bolditalic.eot b/docs/main/_static/fonts/Lato/lato-bolditalic.eot new file mode 100644 index 00000000..3d415493 Binary files /dev/null and b/docs/main/_static/fonts/Lato/lato-bolditalic.eot differ diff --git a/docs/main/_static/fonts/Lato/lato-bolditalic.ttf b/docs/main/_static/fonts/Lato/lato-bolditalic.ttf new file mode 100644 index 00000000..f402040b Binary files /dev/null and b/docs/main/_static/fonts/Lato/lato-bolditalic.ttf differ diff --git a/docs/main/_static/fonts/Lato/lato-bolditalic.woff b/docs/main/_static/fonts/Lato/lato-bolditalic.woff new file mode 100644 index 00000000..88ad05b9 Binary files /dev/null and b/docs/main/_static/fonts/Lato/lato-bolditalic.woff differ diff --git a/docs/main/_static/fonts/Lato/lato-bolditalic.woff2 b/docs/main/_static/fonts/Lato/lato-bolditalic.woff2 new file mode 100644 index 00000000..c4e3d804 Binary files /dev/null and b/docs/main/_static/fonts/Lato/lato-bolditalic.woff2 differ diff --git a/docs/main/_static/fonts/Lato/lato-italic.eot b/docs/main/_static/fonts/Lato/lato-italic.eot new file mode 100644 index 00000000..3f826421 Binary files /dev/null and b/docs/main/_static/fonts/Lato/lato-italic.eot differ diff --git a/docs/main/_static/fonts/Lato/lato-italic.ttf b/docs/main/_static/fonts/Lato/lato-italic.ttf new file mode 100644 index 00000000..b4bfc9b2 Binary files /dev/null and b/docs/main/_static/fonts/Lato/lato-italic.ttf differ diff --git a/docs/main/_static/fonts/Lato/lato-italic.woff b/docs/main/_static/fonts/Lato/lato-italic.woff new file mode 100644 index 00000000..76114bc0 Binary files /dev/null and b/docs/main/_static/fonts/Lato/lato-italic.woff differ diff --git a/docs/main/_static/fonts/Lato/lato-italic.woff2 b/docs/main/_static/fonts/Lato/lato-italic.woff2 new file mode 100644 index 00000000..3404f37e Binary files /dev/null and b/docs/main/_static/fonts/Lato/lato-italic.woff2 differ diff --git a/docs/main/_static/fonts/Lato/lato-regular.eot b/docs/main/_static/fonts/Lato/lato-regular.eot new file mode 100644 index 00000000..11e3f2a5 Binary files /dev/null and b/docs/main/_static/fonts/Lato/lato-regular.eot differ diff --git a/docs/main/_static/fonts/Lato/lato-regular.ttf b/docs/main/_static/fonts/Lato/lato-regular.ttf new file mode 100644 index 00000000..74decd9e Binary files /dev/null and b/docs/main/_static/fonts/Lato/lato-regular.ttf differ diff --git a/docs/main/_static/fonts/Lato/lato-regular.woff b/docs/main/_static/fonts/Lato/lato-regular.woff new file mode 100644 index 00000000..ae1307ff Binary files /dev/null and b/docs/main/_static/fonts/Lato/lato-regular.woff differ diff --git a/docs/main/_static/fonts/Lato/lato-regular.woff2 b/docs/main/_static/fonts/Lato/lato-regular.woff2 new file mode 100644 index 00000000..3bf98433 Binary files /dev/null and b/docs/main/_static/fonts/Lato/lato-regular.woff2 differ diff --git a/docs/main/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot b/docs/main/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot new file mode 100644 index 00000000..79dc8efe Binary files /dev/null and b/docs/main/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot differ diff --git a/docs/main/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf b/docs/main/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf new file mode 100644 index 00000000..df5d1df2 Binary files /dev/null and b/docs/main/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf differ diff --git a/docs/main/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff b/docs/main/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff new file mode 100644 index 00000000..6cb60000 Binary files /dev/null and b/docs/main/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff differ diff --git a/docs/main/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2 b/docs/main/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2 new file mode 100644 index 00000000..7059e231 Binary files /dev/null and b/docs/main/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2 differ diff --git a/docs/main/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot b/docs/main/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot new file mode 100644 index 00000000..2f7ca78a Binary files /dev/null and b/docs/main/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot differ diff --git a/docs/main/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf b/docs/main/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf new file mode 100644 index 00000000..eb52a790 Binary files /dev/null and b/docs/main/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf differ diff --git a/docs/main/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff b/docs/main/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff new file mode 100644 index 00000000..f815f63f Binary files /dev/null and b/docs/main/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff differ diff --git a/docs/main/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2 b/docs/main/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2 new file mode 100644 index 00000000..f2c76e5b Binary files /dev/null and b/docs/main/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2 differ diff --git a/docs/main/_static/jquery.js b/docs/main/_static/jquery.js new file mode 100644 index 00000000..c4c6022f --- /dev/null +++ b/docs/main/_static/jquery.js @@ -0,0 +1,2 @@ +/*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0
"),n("table.docutils.footnote").wrap("
"),n("table.docutils.citation").wrap("
"),n(".wy-menu-vertical ul").not(".simple").siblings("a").each((function(){var t=n(this);expand=n(''),expand.on("click",(function(n){return e.toggleCurrent(t),n.stopPropagation(),!1})),t.prepend(expand)}))},reset:function(){var n=encodeURI(window.location.hash)||"#";try{var e=$(".wy-menu-vertical"),t=e.find('[href="'+n+'"]');if(0===t.length){var i=$('.document [id="'+n.substring(1)+'"]').closest("div.section");0===(t=e.find('[href="#'+i.attr("id")+'"]')).length&&(t=e.find('[href="#"]'))}if(t.length>0){$(".wy-menu-vertical .current").removeClass("current").attr("aria-expanded","false"),t.addClass("current").attr("aria-expanded","true"),t.closest("li.toctree-l1").parent().addClass("current").attr("aria-expanded","true");for(let n=1;n<=10;n++)t.closest("li.toctree-l"+n).addClass("current").attr("aria-expanded","true");t[0].scrollIntoView()}}catch(n){console.log("Error expanding nav for anchor",n)}},onScroll:function(){this.winScroll=!1;var n=this.win.scrollTop(),e=n+this.winHeight,t=this.navBar.scrollTop()+(n-this.winPosition);n<0||e>this.docHeight||(this.navBar.scrollTop(t),this.winPosition=n)},onResize:function(){this.winResize=!1,this.winHeight=this.win.height(),this.docHeight=$(document).height()},hashChange:function(){this.linkScroll=!0,this.win.one("hashchange",(function(){this.linkScroll=!1}))},toggleCurrent:function(n){var e=n.closest("li");e.siblings("li.current").removeClass("current").attr("aria-expanded","false"),e.siblings().find("li.current").removeClass("current").attr("aria-expanded","false");var t=e.find("> ul li");t.length&&(t.removeClass("current").attr("aria-expanded","false"),e.toggleClass("current").attr("aria-expanded",(function(n,e){return"true"==e?"false":"true"})))}},"undefined"!=typeof window&&(window.SphinxRtdTheme={Navigation:n.exports.ThemeNav,StickyNav:n.exports.ThemeNav}),function(){for(var n=0,e=["ms","moz","webkit","o"],t=0;t a.language.name.localeCompare(b.language.name)); + + const languagesHTML = ` +
+
Languages
+ ${languages + .map( + (translation) => ` +
+ ${translation.language.code} +
+ `, + ) + .join("\n")} +
+ `; + return languagesHTML; + } + + function renderVersions(config) { + if (!config.versions.active.length) { + return ""; + } + const versionsHTML = ` +
+
Versions
+ ${config.versions.active + .map( + (version) => ` +
+ ${version.slug} +
+ `, + ) + .join("\n")} +
+ `; + return versionsHTML; + } + + function renderDownloads(config) { + if (!Object.keys(config.versions.current.downloads).length) { + return ""; + } + const downloadsNameDisplay = { + pdf: "PDF", + epub: "Epub", + htmlzip: "HTML", + }; + + const downloadsHTML = ` +
+
Downloads
+ ${Object.entries(config.versions.current.downloads) + .map( + ([name, url]) => ` +
+ ${downloadsNameDisplay[name]} +
+ `, + ) + .join("\n")} +
+ `; + return downloadsHTML; + } + + document.addEventListener("readthedocs-addons-data-ready", function (event) { + const config = event.detail.data(); + + const flyout = ` +
+ + Read the Docs + v: ${config.versions.current.slug} + + +
+
+ ${renderLanguages(config)} + ${renderVersions(config)} + ${renderDownloads(config)} +
+
On Read the Docs
+
+ Project Home +
+
+ Builds +
+
+ Downloads +
+
+
+
Search
+
+
+ +
+
+
+
+ + Hosted by Read the Docs + +
+
+ `; + + // Inject the generated flyout into the body HTML element. + document.body.insertAdjacentHTML("beforeend", flyout); + + // Trigger the Read the Docs Addons Search modal when clicking on the "Search docs" input from inside the flyout. + document + .querySelector("#flyout-search-form") + .addEventListener("focusin", () => { + const event = new CustomEvent("readthedocs-search-show"); + document.dispatchEvent(event); + }); + }) +} + +if (themeLanguageSelector || themeVersionSelector) { + function onSelectorSwitch(event) { + const option = event.target.selectedIndex; + const item = event.target.options[option]; + window.location.href = item.dataset.url; + } + + document.addEventListener("readthedocs-addons-data-ready", function (event) { + const config = event.detail.data(); + + const versionSwitch = document.querySelector( + "div.switch-menus > div.version-switch", + ); + if (themeVersionSelector) { + let versions = config.versions.active; + if (config.versions.current.hidden || config.versions.current.type === "external") { + versions.unshift(config.versions.current); + } + const versionSelect = ` + + `; + + versionSwitch.innerHTML = versionSelect; + versionSwitch.firstElementChild.addEventListener("change", onSelectorSwitch); + } + + const languageSwitch = document.querySelector( + "div.switch-menus > div.language-switch", + ); + + if (themeLanguageSelector) { + if (config.projects.translations.length) { + // Add the current language to the options on the selector + let languages = config.projects.translations.concat( + config.projects.current, + ); + languages = languages.sort((a, b) => + a.language.name.localeCompare(b.language.name), + ); + + const languageSelect = ` + + `; + + languageSwitch.innerHTML = languageSelect; + languageSwitch.firstElementChild.addEventListener("change", onSelectorSwitch); + } + else { + languageSwitch.remove(); + } + } + }); +} + +document.addEventListener("readthedocs-addons-data-ready", function (event) { + // Trigger the Read the Docs Addons Search modal when clicking on "Search docs" input from the topnav. + document + .querySelector("[role='search'] input") + .addEventListener("focusin", () => { + const event = new CustomEvent("readthedocs-search-show"); + document.dispatchEvent(event); + }); +}); \ No newline at end of file diff --git a/docs/main/_static/language_data.js b/docs/main/_static/language_data.js new file mode 100644 index 00000000..c7fe6c6f --- /dev/null +++ b/docs/main/_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/docs/main/_static/minus.png b/docs/main/_static/minus.png new file mode 100644 index 00000000..d96755fd Binary files /dev/null and b/docs/main/_static/minus.png differ diff --git a/docs/main/_static/plus.png b/docs/main/_static/plus.png new file mode 100644 index 00000000..7107cec9 Binary files /dev/null and b/docs/main/_static/plus.png differ diff --git a/docs/main/_static/pygments.css b/docs/main/_static/pygments.css new file mode 100644 index 00000000..6f8b210a --- /dev/null +++ b/docs/main/_static/pygments.css @@ -0,0 +1,75 @@ +pre { line-height: 125%; } +td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +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: #3D7B7B; font-style: italic } /* Comment */ +.highlight .err { border: 1px solid #F00 } /* Error */ +.highlight .k { color: #008000; font-weight: bold } /* Keyword */ +.highlight .o { color: #666 } /* Operator */ +.highlight .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */ +.highlight .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #9C6500 } /* Comment.Preproc */ +.highlight .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */ +.highlight .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */ +.highlight .gr { color: #E40000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #008400 } /* Generic.Inserted */ +.highlight .go { color: #717171 } /* Generic.Output */ +.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #04D } /* Generic.Traceback */ +.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #008000 } /* Keyword.Pseudo */ +.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #B00040 } /* Keyword.Type */ +.highlight .m { color: #666 } /* Literal.Number */ +.highlight .s { color: #BA2121 } /* Literal.String */ +.highlight .na { color: #687822 } /* Name.Attribute */ +.highlight .nb { color: #008000 } /* Name.Builtin */ +.highlight .nc { color: #00F; font-weight: bold } /* Name.Class */ +.highlight .no { color: #800 } /* Name.Constant */ +.highlight .nd { color: #A2F } /* Name.Decorator */ +.highlight .ni { color: #717171; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #00F } /* Name.Function */ +.highlight .nl { color: #767600 } /* Name.Label */ +.highlight .nn { color: #00F; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #19177C } /* Name.Variable */ +.highlight .ow { color: #A2F; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #BBB } /* Text.Whitespace */ +.highlight .mb { color: #666 } /* Literal.Number.Bin */ +.highlight .mf { color: #666 } /* Literal.Number.Float */ +.highlight .mh { color: #666 } /* Literal.Number.Hex */ +.highlight .mi { color: #666 } /* Literal.Number.Integer */ +.highlight .mo { color: #666 } /* Literal.Number.Oct */ +.highlight .sa { color: #BA2121 } /* Literal.String.Affix */ +.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */ +.highlight .sc { color: #BA2121 } /* Literal.String.Char */ +.highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */ +.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #BA2121 } /* Literal.String.Double */ +.highlight .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */ +.highlight .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */ +.highlight .sx { color: #008000 } /* Literal.String.Other */ +.highlight .sr { color: #A45A77 } /* Literal.String.Regex */ +.highlight .s1 { color: #BA2121 } /* Literal.String.Single */ +.highlight .ss { color: #19177C } /* Literal.String.Symbol */ +.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */ +.highlight .fm { color: #00F } /* Name.Function.Magic */ +.highlight .vc { color: #19177C } /* Name.Variable.Class */ +.highlight .vg { color: #19177C } /* Name.Variable.Global */ +.highlight .vi { color: #19177C } /* Name.Variable.Instance */ +.highlight .vm { color: #19177C } /* Name.Variable.Magic */ +.highlight .il { color: #666 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/docs/main/_static/searchtools.js b/docs/main/_static/searchtools.js new file mode 100644 index 00000000..91f4be57 --- /dev/null +++ b/docs/main/_static/searchtools.js @@ -0,0 +1,635 @@ +/* + * 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 = []; + // find documents, if any, containing the query word in their text/title term indices + // use Object.hasOwnProperty to avoid mismatching against prototype properties + const arr = [ + { files: terms.hasOwnProperty(word) ? terms[word] : undefined, score: Scorer.term }, + { files: titleTerms.hasOwnProperty(word) ? titleTerms[word] : undefined, 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, new Map()); + const fileScores = scoreMap.get(file); + fileScores.set(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).get(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/docs/main/_static/sphinx_highlight.js b/docs/main/_static/sphinx_highlight.js new file mode 100644 index 00000000..8a96c69a --- /dev/null +++ b/docs/main/_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/docs/main/distinct_counting/cpc.html b/docs/main/distinct_counting/cpc.html new file mode 100644 index 00000000..2d87ef58 --- /dev/null +++ b/docs/main/distinct_counting/cpc.html @@ -0,0 +1,268 @@ + + + + + + + + + Compressed Probabilistic Counting (CPC) — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Compressed Probabilistic Counting (CPC)

+

High performance C++ implementation of Compressed Probabilistic Counting (CPC) Sketch. +This is a unique-counting sketch that implements the Compressed Probabilistic Counting (CPC, a.k.a FM85) algorithms developed by Kevin Lang in his paper +Back to the Future: an Even More Nearly Optimal Cardinality Estimation Algorithm. +This sketch is extremely space-efficient when serialized. +In an apples-to-apples empirical comparison against compressed HyperLogLog sketches, this new algorithm simultaneously wins on the two dimensions of the space/accuracy tradeoff and produces sketches that are smaller than the entropy of HLL, so no possible implementation of compressed HLL can match its space efficiency for a given accuracy. As described in the paper this sketch implements a newly developed ICON estimator algorithm that survives unioning operations, another well-known estimator, the Historical Inverse Probability (HIP) estimator does not. +The update speed performance of this sketch is quite fast and is comparable to the speed of HLL. +The unioning (merging) capability of this sketch also allows for merging of sketches with different configurations of K. +For additional security this sketch can be configured with a user-specified hash seed.

+
+
+class cpc_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.cpc_sketch
+

Reads a bytes object and returns the corresponding cpc_sketch

+
+ +

Non-static Methods:

+
+
+__init__(self, lg_k: int = 11, seed: int = 9001) None
+

Creates a new CPC sketch

+
+
Parameters:
+
    +
  • lg_k (int, optional) – base 2 logarithm of the number of bins in the sketch

  • +
  • seed (int, optional) – seed value for the hash function

  • +
+
+
+
+ +
+
+get_estimate
+

Estimate of the distinct count of the input stream

+
+ +
+
+get_lower_bound
+

Returns an approximate lower bound on the estimate for kappa values in {1, 2, 3}, roughly corresponding to standard deviations

+
+ +
+
+get_upper_bound
+

Returns an approximate upper bound on the estimate for kappa values in {1, 2, 3}, roughly corresponding to standard deviations

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+property lg_k
+

Configured lg_k of this sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, datum: int) -> None

  2. +
+

Updates the sketch with the given 64-bit integer value

+
    +
  1. update(self, datum: float) -> None

  2. +
+

Updates the sketch with the given 64-bit floating point

+
    +
  1. update(self, datum: str) -> None

  2. +
+

Updates the sketch with the given string

+
+ +
+ +
+
+class cpc_union(*args, **kwargs)
+
+
+__init__(self, lg_k: int, seed: int = 9001) None
+
+ +
+
+get_result
+

Returns a CPC sketch with the result of the union

+
+ +
+
+update
+

Updates the union with the provided CPC sketch

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/main/distinct_counting/hyper_log_log.html b/docs/main/distinct_counting/hyper_log_log.html new file mode 100644 index 00000000..a60930eb --- /dev/null +++ b/docs/main/distinct_counting/hyper_log_log.html @@ -0,0 +1,424 @@ + + + + + + + + + HyperLogLog (HLL) — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

HyperLogLog (HLL)

+

This is a high performance implementation of Phillipe Flajolet’s HLL sketch but with significantly improved error behavior.

+

If the ONLY use case for sketching is counting uniques and merging, the HLL sketch is a reasonable choice, although the highest performing in terms of accuracy for storage space consumed is CPC (Compressed Probabilistic Counting). For large enough counts, this HLL version (with HLL_4) can be 2 to 16 times smaller than the Theta sketch family for the same accuracy.

+

This implementation offers three different types of HLL sketch, each with different trade-offs with accuracy, space and performance. +These types are specified with the target_hll_type parameter.

+

In terms of accuracy, all three types, for the same lg_config_k, have the same error distribution as a function of n, the number of unique values fed to the sketch. +The configuration parameter lg_config_k is the log-base-2 of k, where k is the number of buckets or slots for the sketch.

+

During warmup, when the sketch has only received a small number of unique items (up to about 10% of k), this implementation leverages a new class of estimator algorithms with significantly better accuracy.

+
+
+class tgt_hll_type(*values)
+

Target HLL flavor

+
+
+HLL_4 : 4 bits per entry
+
+ +
+
+HLL_6 : 6 bits per entry
+
+ +
+
+HLL_8 : 8 bits per entry
+
+ +
+ +
+
+class hll_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.hll_sketch
+

Reads a bytes object and returns the corresponding hll_sketch

+
+ +
+
+get_max_updatable_serialization_bytes(lg_k: int, tgt_type: _datasketches.tgt_hll_type) int
+

Provides a likely upper bound on serialization size for the given parameters

+
+ +
+
+get_rel_err(upper_bound: bool, unioned: bool, lg_k: int, num_std_devs: int) float
+

Returns the a priori relative error bound for the given parameters

+
+ +

Non-static Methods:

+
+
+__init__(self, lg_k: int, tgt_type: _datasketches.tgt_hll_type = tgt_hll_type.HLL_8, start_max_size: bool = False) None
+

Constructs a new HLL sketch

+
+
Parameters:
+
    +
  • lg_config_k (int) – A full sketch can hold 2^lg_config_k rows. Must be between 7 and 21, inclusive,

  • +
  • tgt_type (tgt_hll_type) – The HLL mode to use, if/when the sketch reaches estimation mode

  • +
  • start_full_size (bool) – Indicates whether to start in HLL mode, keeping memory use constant (if HLL_6 or HLL_8) at the cost of much higher initial memory use. Default (and recommended) is False.

  • +
+
+
+
+ +
+
+get_compact_serialization_bytes
+

Returns the size of the serialized sketch when compressing the exception table if HLL_4

+
+ +
+
+get_estimate
+

Estimate of the distinct count of the input stream

+
+ +
+
+get_lower_bound
+

Returns the approximate lower error bound given the specified number of standard deviations in {1, 2, 3}

+
+ +
+
+get_updatable_serialization_bytes
+

Returns the size of the serialized sketch

+
+ +
+
+get_upper_bound
+

Returns the approximate upper error bound given the specified number of standard deviations in {1, 2, 3}

+
+ +
+
+is_compact
+

True if the sketch is compact, otherwise False

+
+ +
+
+is_empty
+

True if the sketch is empty, otherwise False

+
+ +
+
+property lg_config_k
+

Configured lg_k value for the sketch

+
+ +
+
+reset
+

Resets the sketch to the empty state in coupon collection mode

+
+ +
+
+serialize_compact
+

Serializes the sketch into a bytes object, compressing the exception table if HLL_4

+
+ +
+
+serialize_updatable
+

Serializes the sketch into a bytes object

+
+ +
+
+property tgt_type
+

The HLL type (4, 6, or 8) when in estimation mode

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, datum: int) -> None

  2. +
+

Updates the sketch with the given integral value

+
    +
  1. update(self, datum: float) -> None

  2. +
+

Updates the sketch with the given floating point value

+
    +
  1. update(self, datum: str) -> None

  2. +
+

Updates the sketch with the given string value

+
+ +
+ +
+
+class hll_union(*args, **kwargs)
+

Static Methods:

+
+
+get_rel_err(upper_bound: bool, unioned: bool, lg_k: int, num_std_devs: int) float
+

Returns the a priori relative error bound for the given parameters

+
+ +

Non-static Methods:

+
+
+__init__(self, lg_max_k: int) None
+

Construct an hll_union object if the given size.

+
+
Parameters:
+

lg_max_k (int) – The maximum size, in log2, of k. Must be between 7 and 21, inclusive.

+
+
+
+ +
+
+get_estimate
+

Estimate of the distinct count of the input stream

+
+ +
+
+get_lower_bound
+

Returns the approximate lower error bound given the specified number of standard deviations in {1, 2, 3}

+
+ +
+
+get_result
+

Returns a sketch of the target type representing the current union state

+
+ +
+
+get_upper_bound
+

Returns the approximate upper error bound given the specified number of standard deviations in {1, 2, 3}

+
+ +
+
+is_empty
+

True if the union is empty, otherwise False

+
+ +
+
+property lg_config_k
+

Configured lg_k value for the union

+
+ +
+
+reset
+

Resets the union to the empty state

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, sketch: _datasketches.hll_sketch) -> None

  2. +
+

Updates the union with the given HLL sketch

+
    +
  1. update(self, datum: int) -> None

  2. +
+

Updates the union with the given integral value

+
    +
  1. update(self, datum: float) -> None

  2. +
+

Updates the union with the given floating point value

+
    +
  1. update(self, datum: str) -> None

  2. +
+

Updates the union with the given string value

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/main/distinct_counting/index.html b/docs/main/distinct_counting/index.html new file mode 100644 index 00000000..ce4493db --- /dev/null +++ b/docs/main/distinct_counting/index.html @@ -0,0 +1,150 @@ + + + + + + + + + Distinct Counting — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Distinct Counting

+

Distinct counting is one of the earliest tasks to which sketches were applied. The concept is simple: +Provide an estimate of the number of unique elements in a set of data. One of the earliest solutions came +from Flajolet and Martin in 1985 with their seminal work +Probabilistic counting Algorithms for Data Base Applications.

+

The DataSketches library offers several types of distinct counting sketches, each with different properties.

+
+
    +
  • hll_sketch: Hyper Log Log, a well-known sketch for distinct counting but no longer state-of-the-art.

  • +
  • cpc_sketch: Provides a better accuracy-space trade-off than HLL, but with a somewhat larger footprint while in-memory.

  • +
  • theta_sketch: Theta sketch, a type of k-minimum value sketch, which provide good performance with intersection and set difference operations.

  • +
  • tuple_sketch: Tuple sketch, which is similar to a theta sketch but supports additional data stored with each key.

  • +
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/main/distinct_counting/theta.html b/docs/main/distinct_counting/theta.html new file mode 100644 index 00000000..a66a2a9f --- /dev/null +++ b/docs/main/distinct_counting/theta.html @@ -0,0 +1,438 @@ + + + + + + + + + Theta Sketch — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Theta Sketch

+

Theta sketches are used for distinct counting.

+

The theta package contains the basic sketch classes that are members of the Theta Sketch Framework. +There is a separate Tuple package for many of the sketches that are derived from the same algorithms defined in the Theta Sketch Framework paper.

+

The Theta Sketch sketch is a space-efficient method for estimating cardinalities of sets. +It can also easily handle set operations (such as union, intersection, difference) while maintaining good accuracy. +Theta sketch is a practical variant of the K-Minimum Values sketch which avoids the need to sort the stored +hash values on every insertion to the sketch. +It has better error properties than the HyperLogLog sketch for set operations beyond the simple union.

+

Set operations (union, intersection, A-not-B) are performed through the use of dedicated objects.

+

Several Jaccard similarity +measures can be computed between theta sketches with the theta_jaccard_similarity class.

+
+
+class theta_sketch
+

An abstract base class for theta sketches

+
+
+get_estimate
+

Estimate of the distinct count of the input stream

+
+ +
+
+get_lower_bound
+

Returns an approximate lower bound on the estimate at standard deviations in {1, 2, 3}

+
+ +
+
+get_seed_hash
+

Returns a hash of the seed used in the sketch

+
+ +
+
+get_upper_bound
+

Returns an approximate upper bound on the estimate at standard deviations in {1, 2, 3}

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if sketch is in estimation mode, otherwise False

+
+ +
+
+is_ordered
+

Returns True if the sketch entries are sorted, otherwise False

+
+ +
+
+property num_retained
+

The number of items currently in the sketch

+
+ +
+
+property theta
+

Theta (effective sampling rate) as a fraction from 0 to 1

+
+ +
+
+property theta64
+

Theta as 64-bit value

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+ +
+
+class update_theta_sketch(*args, **kwargs)
+
+
+__init__(self, lg_k: int = 12, p: float = 1.0, seed: int = 9001) None
+

Creates an update_theta_sketch using the provided parameters

+
+
Parameters:
+
    +
  • lg_k (int, optional) – base 2 logarithm of the maximum size of the sketch. Default 12.

  • +
  • p (float, optional) – an initial sampling rate to use. Default 1.0

  • +
  • seed (int, optional) – the seed to use when hashing values

  • +
+
+
+
+ +
+
+compact
+

Returns a compacted form of the sketch, optionally sorting it

+
+ +
+
+reset
+

Resets the sketch to the initial empty state

+
+ +
+
+trim
+

Removes retained entries in excess of the nominal size k (if any)

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, datum: int) -> None

  2. +
+

Updates the sketch with the given integral value

+
    +
  1. update(self, datum: float) -> None

  2. +
+

Updates the sketch with the given floating point value

+
    +
  1. update(self, datum: str) -> None

  2. +
+

Updates the sketch with the given string

+
+ +
+ +
+
+class compact_theta_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, seed: int = 9001) _datasketches.compact_theta_sketch
+

Reads a bytes object and returns the corresponding compact_theta_sketch

+
+ +

Non-static Methods:

+
+
+__init__(self, arg0: _datasketches.theta_sketch, arg1: bool, /) None
+

Creates a compact_theta_sketch from an existing theta_sketch.

+
+
Parameters:
+
    +
  • other (theta_sketch) – a source theta_sketch

  • +
  • ordered (bool) – whether the incoming sketch entries are sorted. Default True

  • +
+
+
+
+ +
+
+serialize
+

Serializes the sketch into a bytes object, optionally compressing the data

+
+ +
+ +
+
+class theta_union(*args, **kwargs)
+
+
+__init__(self, lg_k: int = 12, p: float = 1.0, seed: int = 9001) None
+

Creates a theta_union using the provided parameters

+
+
Parameters:
+
    +
  • lg_k (int, optional) – base 2 logarithm of the maximum size of the union. Default 12.

  • +
  • p (float, optional) – an initial sampling rate to use. Default 1.0

  • +
  • seed (int, optional) – the seed to use when hashing values. Must match all sketch seeds.

  • +
+
+
+
+ +
+
+get_result
+

Returns the sketch corresponding to the union result

+
+ +
+
+update
+

Updates the union with the given sketch

+
+ +
+ +
+
+class theta_intersection(*args, **kwargs)
+
+
+__init__(self, seed: int = 9001) None
+

Creates a theta_intersection using the provided parameters

+
+
Parameters:
+

seed (int, optional) – the seed to use when hashing values. Must match all sketch seeds

+
+
+
+ +
+
+get_result
+

Returns the sketch corresponding to the intersection result

+
+ +
+
+has_result
+

Returns True if the intersection has a valid result, otherwise False

+
+ +
+
+update
+

Intersections the provided sketch with the current intersection state

+
+ +
+ +
+
+class theta_a_not_b(*args, **kwargs)
+
+
+__init__(self, seed: int = 9001) None
+

Creates a tuple_a_not_b object

+
+
Parameters:
+

seed (int, optional) – the seed to use when hashing values. Must match all sketch seeds.

+
+
+
+ +
+
+compute
+

Returns a sketch with the result of applying the A-not-B operation on the given inputs

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/main/distinct_counting/tuple.html b/docs/main/distinct_counting/tuple.html new file mode 100644 index 00000000..aa619a73 --- /dev/null +++ b/docs/main/distinct_counting/tuple.html @@ -0,0 +1,512 @@ + + + + + + + + + Tuple Sketch — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Tuple Sketch

+

Tuple sketches are an extension of Theta sketches, meaning they provide estimate of distinct counts, that +allow the keeping of arbitrary summaries associated with each retained key +(for example, a count for every key). The use of a tuple_sketch requires a TuplePolicy which +defines how summaries are created, updated, merged, or intersected. The library provides a few basic +examples of TuplePolicy implementations, but the right custom summary and policy can allow very +complicated analysis to be performed quite easily.

+

Set operations (union, intersection, A-not-B) are performed through the use of dedicated objects.

+

Several Jaccard similarity +measures can be computed between theta sketches with the tuple_jaccard_similarity class.

+
+

Note

+

Serializing and deserializing this sketch requires the use of a PyObjectSerDe.

+
+
+
+class tuple_sketch
+

An abstract base class for tuple sketches.

+
+
+DEFAULT_SEED = 9001
+
+ +
+
+get_estimate
+

Estimate of the distinct count of the input stream

+
+ +
+
+get_lower_bound
+

Returns an approximate lower bound on the estimate at standard deviations in {1, 2, 3}

+
+ +
+
+get_seed_hash
+

Returns a hash of the seed used in the sketch

+
+ +
+
+get_upper_bound
+

Returns an approximate upper bound on the estimate at standard deviations in {1, 2, 3}

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if sketch is in estimation mode, otherwise False

+
+ +
+
+is_ordered
+

Returns True if the sketch entries are sorted, otherwise False

+
+ +
+
+property num_retained
+

The number of items currently in the sketch

+
+ +
+
+property theta
+

Theta (effective sampling rate) as a fraction from 0 to 1

+
+ +
+
+property theta64
+

Theta as 64-bit value

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+ +
+
+class update_tuple_sketch(*args, **kwargs)
+
+
+__init__(self, policy: _datasketches.TuplePolicy, lg_k: int = 12, p: float = 1.0, seed: int = 9001) None
+

Creates an update_tuple_sketch using the provided parameters

+
+
Parameters:
+
    +
  • policy (TuplePolicy) – a policy to use when updating

  • +
  • lg_k (int, optional) – base 2 logarithm of the maximum size of the sketch. Default 12.

  • +
  • p (float, optional) – an initial sampling rate to use. Default 1.0

  • +
  • seed (int, optional) – the seed to use when hashing values

  • +
+
+
+
+ +
+
+compact
+

Returns a compacted form of the sketch, optionally sorting it

+
+ +
+
+filter
+

Produces a compact_tuple_sketch from the given sketch by applying a predicate to the summary in each entry.

+
+
Parameters:
+

predicate – A function returning true or value evaluated on each tuple summary

+
+
Returns:
+

A compact_tuple_sketch with the selected entries

+
+
Return type:
+

compact_tuple_sketch

+
+
+
+ +
+
+reset
+

Resets the sketch to the initial empty state

+
+ +
+
+trim
+

Removes retained entries in excess of the nominal size k (if any)

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, datum: int, value: object) -> None

  2. +
+

Updates the sketch with the given integral item and summary value

+
    +
  1. update(self, datum: float, value: object) -> None

  2. +
+

Updates the sketch with the given floating point item and summary value

+
    +
  1. update(self, datum: str, value: object) -> None

  2. +
+

Updates the sketch with the given string item and summary value

+
+ +
+ +
+
+class compact_tuple_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe, seed: int = 9001) _datasketches.compact_tuple_sketch
+

Reads a bytes object and returns the corresponding compact_tuple_sketch

+
+ +

Non-static Methods:

+
+
+__init__(self, other: _datasketches.tuple_sketch, ordered: bool = True) None
+
+__init__(self, other: _datasketches.theta_sketch, summary: object) None
+

Overloaded function.

+
    +
  1. __init__(self, other: _datasketches.tuple_sketch, ordered: bool = True) -> None

  2. +
+

Creates a compact_tuple_sketch from an existing tuple_sketch.

+
+
Parameters:
+
    +
  • other (tuple_sketch) – a sourch tuple_sketch

  • +
  • ordered (bool, optional) – whether the incoming sketch entries are sorted. Default True

  • +
+
+
+
    +
  1. __init__(self, other: _datasketches.theta_sketch, summary: object) -> None

  2. +
+

Creates a compact_tuple_sketch from a theta_sketch using a fixed summary value.

+
+
Parameters:
+
    +
  • other (theta_sketch) – a source theta sketch

  • +
  • summary (object) – a summary to use for every sketch entry

  • +
+
+
+
+ +
+
+filter
+

Produces a compact_tuple_sketch from the given sketch by applying a predicate to the summary in each entry.

+
+
Parameters:
+

predicate – A function returning true or value evaluated on each tuple summary

+
+
Returns:
+

A compact_tuple_sketch with the selected entries

+
+
Return type:
+

compact_tuple_sketch

+
+
+
+ +
+
+serialize
+

Serializes the sketch into a bytes object

+
+ +
+ +
+
+class tuple_union(*args, **kwargs)
+
+
+__init__(self, policy: _datasketches.TuplePolicy, lg_k: int = 12, p: float = 1.0, seed: int = 9001) None
+

Creates a tuple_union using the provided parameters

+
+
Parameters:
+
    +
  • policy (TuplePolicy) – a policy to use when unioning entries

  • +
  • lg_k (int, optional) – base 2 logarithm of the maximum size of the union. Default 12.

  • +
  • p (float, optional) – an initial sampling rate to use. Default 1.0

  • +
  • seed (int, optional) – the seed to use when hashing values. Must match any sketch seeds.

  • +
+
+
+
+ +
+
+get_result
+

Returns the sketch corresponding to the union result

+
+ +
+
+reset
+

Resets the sketch to the initial empty

+
+ +
+
+update
+

Updates the union with the given sketch

+
+ +
+ +
+
+class tuple_intersection(*args, **kwargs)
+
+
+__init__(self, policy: _datasketches.TuplePolicy, seed: int = 9001) None
+

Creates a tuple_intersection using the provided parameters

+
+
Parameters:
+
    +
  • policy (TuplePolicy) – a policy to use when intersecting entries

  • +
  • seed (int, optional) – the seed to use when hashing values. Must match any sketch seeds

  • +
+
+
+
+ +
+
+get_result
+

Returns the sketch corresponding to the intersection result

+
+ +
+
+has_result
+

Returns True if the intersection has a valid result, otherwise False

+
+ +
+
+update
+

Intersects the provided sketch with the current intersection state

+
+ +
+ +
+
+class tuple_a_not_b(*args, **kwargs)
+
+
+__init__(self, seed: int = 9001) None
+

Creates a tuple_a_not_b object

+
+
Parameters:
+

seed (int, optional) – the seed to use when hashing values. Must match any sketch seeds.

+
+
+
+ +
+
+compute
+

Returns a sketch with the result of applying the A-not-B operation on the given inputs

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/main/frequency/count_min_sketch.html b/docs/main/frequency/count_min_sketch.html new file mode 100644 index 00000000..934d24d1 --- /dev/null +++ b/docs/main/frequency/count_min_sketch.html @@ -0,0 +1,301 @@ + + + + + + + + + CountMin Sketch — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

CountMin Sketch

+

The CountMin sketch, as described in Cormode and Muthukrishnan in +http://dimacs.rutgers.edu/~graham/pubs/papers/cm-full.pdf, +is used for approximate Frequency Estimation. +For an item \(x\) with frequency \(f_x\), the sketch provides an estimate, \(\hat{f_x}\), +such that \(f_x \approx \hat{f_x}.\) +The sketch guarantees that \(f_x \le \hat{f_x}\) and provides a probabilistic upper bound which is dependent on the size parameters. +The sketch provides an estimate of the occurrence frequency for any queried item but, in contrast +to the Frequent Items Sketch, this sketch does not provide a list of +heavy hitters.

+
+
+class count_min_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.count_min_sketch
+

Reads a bytes object and returns the corresponding count_min_sketch

+
+ +
+
+suggest_num_buckets(relative_error: float) int
+

Suggests the number of buckets needed to achieve an accuracy within the provided relative_error. For example, when relative_error = 0.05, the returned frequency estimates satisfy the ‘relative_error’ guarantee that never overestimates the weights but may underestimate the weights by 5% of the total weight in the sketch. Returns the number of hash buckets at every level of the sketch required in order to obtain the specified relative error.

+
+ +
+
+suggest_num_hashes(confidence: float) int
+

Suggests the number of hashes needed to achieve the provided confidence. For example, with 95% confidence, frequency estimates satisfy the ‘relative_error’ guarantee. Returns the number of hash functions that are required in order to achieve the specified confidence of the sketch. confidence = 1 - delta, with delta denoting the sketch failure probability.

+
+ +

Non-static Methods:

+
+
+get_estimate
+

Overloaded function.

+
    +
  1. get_estimate(self, item: int) -> float

  2. +
+

Returns an estimate of the frequency of the provided 64-bit integer value

+
    +
  1. get_estimate(self, item: str) -> float

  2. +
+

Returns an estimate of the frequency of the provided string

+
+ +
+
+get_lower_bound
+

Overloaded function.

+
    +
  1. get_lower_bound(self, item: int) -> float

  2. +
+

Returns a lower bound on the estimate for the given 64-bit integer value

+
    +
  1. get_lower_bound(self, item: str) -> float

  2. +
+

Returns a lower bound on the estimate for the provided string

+
+ +
+
+get_relative_error
+

Returns the maximum permissible error for any frequency estimate query

+
+ +
+
+get_serialized_size_bytes
+

Returns the size in bytes of the serialized image of the sketch

+
+ +
+
+get_upper_bound
+

Overloaded function.

+
    +
  1. get_upper_bound(self, item: int) -> float

  2. +
+

Returns an upper bound on the estimate for the given 64-bit integer value

+
    +
  1. get_upper_bound(self, item: str) -> float

  2. +
+

Returns an upper bound on the estimate for the provided string

+
+ +
+
+is_empty
+

Returns True if the sketch has seen no items, otherwise False

+
+ +
+
+merge
+

Merges the provided other sketch into this one

+
+ +
+
+property num_buckets
+

The configured number of buckets for the sketch

+
+ +
+
+property num_hashes
+

The configured number of hashes for the sketch

+
+ +
+
+property seed
+

The base hash seed for the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+property total_weight
+

The total weight currently inserted into the stream

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: int, weight: float = 1.0) -> None

  2. +
+

Updates the sketch with the given 64-bit integer value

+
    +
  1. update(self, item: str, weight: float = 1.0) -> None

  2. +
+

Updates the sketch with the given string

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/main/frequency/frequent_items.html b/docs/main/frequency/frequent_items.html new file mode 100644 index 00000000..77da8961 --- /dev/null +++ b/docs/main/frequency/frequent_items.html @@ -0,0 +1,477 @@ + + + + + + + + + Frequent Items — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Frequent Items

+

This sketch is useful for tracking approximate frequencies of items (object or string) with optional associated +integer counts that are members of a multiset of such items. +The true frequency of an item is defined to be the sum of associated counts.

+

This implementation provides the following capabilities:

+
    +
  • Estimate the frequency of an item.

  • +
  • Return upper and lower bounds of any item, such that the true frequency is always between the upper and lower bounds.

  • +
  • Return a global maximum error that holds for all items in the stream.

  • +
  • Return an array of frequent items that qualify either a NO_FALSE_POSITIVES or a NO_FALSE_NEGATIVES error type.

  • +
  • Merge itself with another sketch object created from this class.

  • +
  • Serialize/Deserialize to/from a byte array.

  • +
+

Space Usage

+

The sketch is initialized with a maximum map size, maxMapSize, that specifies the maximum physical length of the internal hash map of the form (object item, int count). +The maximum map size is always a power of 2, defined through the variables lg_max_map_size.

+

The hash map starts at a very small size (8 entries) and grows as needed up to the specified maximum map size.

+

Excluding external space required for the item objects, the internal memory space usage of this sketch is 18 * mapSize bytes (assuming 8 bytes for each reference), +plus a small constant number of additional bytes. +The internal memory space usage of this sketch will never exceed 18 * maxMapSize bytes, plus a small constant number of additional bytes.

+

Maximum Capacity of the Sketch

+

The LOAD_FACTOR for the hash map is internally set at \(75\%\), which means at any time the map capacity of (item, count) pairs is mapCap = 0.75 * mapSize. +The maximum capacity of (item, count) pairs of the sketch is maxMapCap = 0.75 * maxMapSize.

+

Updating the sketch with ``(item, count)`` pairs

+

If the item is found in the hash map, the mapped count field (the “counter”) is incremented by the incoming count; otherwise, a new counter (item, count) pair is created. +If the number of tracked counters reaches the maximum capacity of the hash map, the sketch decrements all of the counters (by an approximately computed median) +and removes any non-positive counters.

+

Accuracy

+

If fewer than 0.75 * maxMapSize different items are inserted into the sketch, the estimated frequencies returned by the sketch will be exact.

+

The logic of the frequent items sketch is such that the stored counts and true counts are never too different. +More specifically, for any item, the sketch can return an estimate of the true frequency of item, along with upper and lower bounds on the frequency (that hold deterministically).

+

For this implementation and for a specific active item, it is guaranteed that the true frequency will be between the Upper Bound (UB) and the Lower Bound (LB) computed for that item. +Specifically, (UB- LB) W * epsilon, where \(W\) denotes the sum of all item counts, and \(epsilon = 3.5/M\), where \(epsilon = M\) is the maxMapSize.

+

This is a worst-case guarantee that applies to arbitrary inputs. +For inputs typically seen in practice, (UB-LB) is usually much smaller.

+

Background

+

This code implements a variant of what is commonly known as the “Misra-Gries algorithm”. +Variants of it were discovered and rediscovered and redesigned several times over the years:

+
    +
  • Finding repeated elements, Misra, Gries, 1982

  • +
  • Frequency estimation of Internet packet streams with limited space Demaine, Lopez-Ortiz, Munro, 2002

  • +
  • A simple algorithm for finding frequent elements in streams and bags Karp, Shenker, Papadimitriou, 2003

  • +
  • Efficient Computation of Frequent and Top-k Elements in Data Streams Metwally, Agrawal, Abbadi, 2006

  • +
+

For speed, we do employ some randomization that introduces a small probability that our proof of the worst-case bound might not apply to a given run. +However, we have ensured that this probability is extremely small. +For example, if the stream causes one table purge (rebuild), our proof of the worst-case bound applies with a probability of at least 1 - 1E-14. +If the stream causes 1E9 purges, our proof applies with a probability of at least 1 - 1E-5.

+

There are two flavors of Frequent Items Sketches, one with generic items (objects) and another specific to strings. +The string version is a legacy name from before the library supported generic objects and is retained +only for backwards compatibility.

+
+

Note

+

The frequent_items_sketch uses an input object’s __hash__ and __eq__ methods.

+
+
+

Note

+

Serializing and deserializing the frequent_items_sketch requires the use of a PyObjectSerDe.

+
+
+
+class frequent_items_error_type(*values)
+
+
+NO_FALSE_POSITIVES : Returns only true positives but may miss some heavy hitters.
+
+ +
+
+NO_FALSE_NEGATIVES : Does not miss any heavy hitters but may return false positives.
+
+ +
+ +
+
+class frequent_items_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe) _datasketches.frequent_items_sketch
+

Reads a bytes object using the provided serde and returns the corresponding frequent_strings_sketch.

+
+ +
+
+get_epsilon_for_lg_size(lg_max_map_size: int) float
+

Returns the epsilon value used to compute a priori error for a given log2(max_map_size)

+
+ +
+
+get_apriori_error(lg_max_map_size: int, estimated_total_weight: int) float
+

Returns the estimated a priori error given the max_map_size for the sketch and the estimated_total_stream_weight.

+
+ +

Non-static Methods:

+
+
+__init__(self, lg_max_k: int) None
+

Creates an instance of the sketch

+
+
Parameters:
+

lg_max_k (int) – base 2 logarithm of the maximum size of the internal hash map of the sketch. Maximum capacity is 0.75 of this value, which is the maximum number of distinct items the sketch can contain.

+
+
+
+ +
+
+property epsilon
+

The epsilon value used by the sketch to compute error

+
+ +
+
+get_estimate
+

Returns the estimate of the weight (frequency) of the given item. +Note: The true frequency of a item would be the sum of the counts as a result of the two update functions.

+
+ +
+
+get_frequent_items
+
+ +
+
+get_lower_bound
+

Returns the guaranteed lower bound weight (frequency) of the given item.

+
+ +
+
+get_serialized_size_bytes
+

Computes the size needed to serialize the current state of the sketch using the provided serde. This can be expensive since every item needs to be looked at.

+
+ +
+
+get_upper_bound
+

Returns the guaranteed upper bound weight (frequency) of the given item.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+merge
+

Merges the given sketch into this one

+
+ +
+
+property num_active_items
+

The number of active items in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object using the provided serde.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+property total_weight
+

The sum of the weights (frequencies) in the stream seen so far by the sketch

+
+ +
+
+update
+

Updates the sketch with the given string and, optionally, a weight

+
+ +
+ +
+
+class frequent_strings_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.frequent_strings_sketch
+

Reads a bytes object and returns the corresponding frequent_strings_sketch.

+
+ +
+
+get_epsilon_for_lg_size(lg_max_map_size: int) float
+

Returns the epsilon value used to compute a priori error for a given log2(max_map_size)

+
+ +
+
+get_apriori_error(lg_max_map_size: int, estimated_total_weight: int) float
+

Returns the estimated a priori error given the max_map_size for the sketch and the estimated_total_stream_weight.

+
+ +

Non-static Methods:

+
+
+__init__(self, lg_max_k: int) None
+

Creates an instance of the sketch

+
+
Parameters:
+

lg_max_k (int) – base 2 logarithm of the maximum size of the internal hash map of the sketch. Maximum capacity is 0.75 of this value, which is the maximum number of distinct items the sketch can contain.

+
+
+
+ +
+
+property epsilon
+

The epsilon value used by the sketch to compute error

+
+ +
+
+get_estimate
+

Returns the estimate of the weight (frequency) of the given item. +Note: The true frequency of a item would be the sum of the counts as a result of the two update functions.

+
+ +
+
+get_frequent_items
+
+ +
+
+get_lower_bound
+

Returns the guaranteed lower bound weight (frequency) of the given item.

+
+ +
+
+get_serialized_size_bytes
+

Computes the size needed to serialize the current state of the sketch. This can be expensive since every item needs to be looked at.

+
+ +
+
+get_upper_bound
+

Returns the guaranteed upper bound weight (frequency) of the given item.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+merge
+

Merges the given sketch into this one

+
+ +
+
+property num_active_items
+

The number of active items in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+property total_weight
+

The sum of the weights (frequencies) in the stream seen so far by the sketch

+
+ +
+
+update
+

Updates the sketch with the given string and, optionally, a weight

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/main/frequency/index.html b/docs/main/frequency/index.html new file mode 100644 index 00000000..1f38065c --- /dev/null +++ b/docs/main/frequency/index.html @@ -0,0 +1,142 @@ + + + + + + + + + Frequency Sketches — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Frequency Sketches

+

Frequency estimation involves determining how often an item has been seen in a stream. The library currently +offers two types of sketches for frequency estimation, one of which has two closely-related variants.

+
+
    +
  • frequent_items_sketch: Identifies the Top K or heavy hitters in a stream, those items whose weight is above a certain percentage of the entire stream. Does not necessarily provide an estimate for most items outside the heavy hitters.

  • +
  • frequent_strings_sketch: Like the items version but containing snly strings (an implementation from before the library handled generic objects).

  • +
  • count_min_sketch: Provides an estimate for any item, regardless of relative weight, but does not maintain a list of the heaviest items.

  • +
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/main/genindex.html b/docs/main/genindex.html new file mode 100644 index 00000000..8c4b4532 --- /dev/null +++ b/docs/main/genindex.html @@ -0,0 +1,1464 @@ + + + + + + + + Index — datasketches 0.1 documentation + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ + +

Index

+ +
+ _ + | A + | C + | D + | E + | F + | G + | H + | I + | J + | K + | L + | M + | N + | P + | Q + | R + | S + | T + | U + | V + +
+

_

+ + +
+ +

A

+ + +
+ +

C

+ + + +
+ +

D

+ + + +
+ +

E

+ + + +
+ +

F

+ + + +
+ +

G

+ + + +
+ +

H

+ + + +
+ +

I

+ + + +
+ +

J

+ + +
+ +

K

+ + + +
+ +

L

+ + + +
+ +

M

+ + + +
+ +

N

+ + + +
+ +

P

+ + + +
+ +

Q

+ + + +
+ +

R

+ + +
+ +

S

+ + + +
+ +

T

+ + + +
+ +

U

+ + + +
+ +

V

+ + + +
+ + + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/main/helper/index.html b/docs/main/helper/index.html new file mode 100644 index 00000000..dc74ac3f --- /dev/null +++ b/docs/main/helper/index.html @@ -0,0 +1,152 @@ + + + + + + + + + Helper Classes — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Helper Classes

+

These classes are required for certain sketches or specific +functionality within sketches. +Some of them are abstract base classes, but in those cases there is at +least one reference example of a concrete class.

+
+
    +
  • serde is used when serializing and deserializing sketches.

  • +
  • jaccard is used to compute the Jaccard similarity between pairs of theta or tuple sketches.

  • +
  • tuple_policy is required to use a tuple_sketch by specifying how summaries are combined.

  • +
  • ks_test() performs a Kolmogorov-Smirnov test on absolute-error quantiles family sketches.

  • +
  • kernel_function is required when using a kernel_sketch for Kernel Density Estimation.

  • +
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/main/helper/jaccard.html b/docs/main/helper/jaccard.html new file mode 100644 index 00000000..d36838a3 --- /dev/null +++ b/docs/main/helper/jaccard.html @@ -0,0 +1,210 @@ + + + + + + + + + Jaccard Similarity — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Jaccard Similarity

+

These objects provide measures related to the Jaccard similarity +of theta_sketch and tuple_sketch objects.

+

Note that there are separate classes to be used for theta and tuple sketches.

+
+
+class theta_jaccard_similarity
+

An object to help compute Jaccard similarity between theta sketches.

+
+
+jaccard(sketch_a: _datasketches.theta_sketch, sketch_b: _datasketches.theta_sketch, seed: int = 9001) list[float]
+

Returns a list with {lower_bound, estimate, upper_bound} of the Jaccard similarity between sketches

+
+ +
+
+exactly_equal(sketch_a: _datasketches.theta_sketch, sketch_b: _datasketches.theta_sketch, seed: int = 9001) bool
+

Returns True if sketch_a and sketch_b are equivalent, otherwise False

+
+ +
+
+similarity_test(actual: _datasketches.theta_sketch, expected: _datasketches.theta_sketch, threshold: float, seed: int = 9001) bool
+

Tests similarity of an actual sketch against an expected sketch. Computers the lower bound of the Jaccard index J_{LB} of the actual and expected sketches. If J_{LB} >= threshold, then the sketches are considered to be similar with a confidence of 97.7% and returns True, otherwise False.

+
+ +
+
+dissimilarity_test(actual: _datasketches.theta_sketch, expected: _datasketches.theta_sketch, threshold: float, seed: int = 9001) bool
+

Tests dissimilarity of an actual sketch against an expected sketch. Computers the lower bound of the Jaccard index J_{UB} of the actual and expected sketches. If J_{UB} <= threshold, then the sketches are considered to be dissimilar with a confidence of 97.7% and returns True, otherwise False.

+
+ +
+ +
+
+class tuple_jaccard_similarity
+

An object to help compute Jaccard similarity between tuple sketches.

+
+
+jaccard(sketch_a: _datasketches.tuple_sketch, sketch_b: _datasketches.tuple_sketch, seed: int = 9001) list[float]
+

Returns a list with {lower_bound, estimate, upper_bound} of the Jaccard similarity between sketches

+
+ +
+
+exactly_equal(sketch_a: _datasketches.tuple_sketch, sketch_b: _datasketches.tuple_sketch, seed: int = 9001) bool
+

Returns True if sketch_a and sketch_b are equivalent, otherwise False

+
+ +
+
+similarity_test(actual: _datasketches.tuple_sketch, expected: _datasketches.tuple_sketch, threshold: float, seed: int = 9001) bool
+

Tests similarity of an actual sketch against an expected sketch. Computes the lower bound of the Jaccard index J_{LB} of the actual and expected sketches. If J_{LB} >= threshold, then the sketches are considered to be similar with a confidence of 97.7% and returns True, otherwise False.

+
+ +
+
+dissimilarity_test(actual: _datasketches.tuple_sketch, expected: _datasketches.tuple_sketch, threshold: float, seed: int = 9001) bool
+

Tests dissimilarity of an actual sketch against an expected sketch. Computes the upper bound of the Jaccard index J_{UB} of the actual and expected sketches. If J_{UB} <= threshold, then the sketches are considered to be dissimilar with a confidence of 97.7% and returns True, otherwise False.

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/main/helper/kernel.html b/docs/main/helper/kernel.html new file mode 100644 index 00000000..f3a8af8c --- /dev/null +++ b/docs/main/helper/kernel.html @@ -0,0 +1,182 @@ + + + + + + + + + Kernel Function — datasketches 0.1 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Kernel Function

+

A kernel function is a specific type of +mathematical funciton that is particularly useful in certain machine learning and pattern recognition +contexts. The density_sketch performs approximate +kernel density estimation which, unsurprisingly, +relies on the use of such a kernel function.

+

The library provides an abstract base class KernelFunction and an example implementation of a +Gaussian (also known as a Radial Basis Function) kernel. Custom classes must override the base class +and provide a floating point value as a score indicating the similarity of two input vectors.

+
+
+class KernelFunction(*args, **kwargs)
+

A generic base class from which user-defined kernels must inherit.

+
+
+__call__(self, a: object, b: object) float
+

A method to evaluate a kernel with given inputs a and b.

+
+
Parameters:
+
    +
  • a (numpy array) – An input vector

  • +
  • b (numpy array) – An input vector

  • +
+
+
Returns:
+

A vector similarity score

+
+
Return type:
+

float

+
+
+
+ +
+ +
+
+class GaussianKernel(bandwidth: float = 1.0)
+

Bases: KernelFunction

+

Implements a basic Gaussian kernel

+
+
Parameters:
+

bandwidth (float) – The kernel bandwidth, default 1.0

+
+
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/main/helper/ks_test.html b/docs/main/helper/ks_test.html new file mode 100644 index 00000000..598de348 --- /dev/null +++ b/docs/main/helper/ks_test.html @@ -0,0 +1,208 @@ + + + + + + + + + Kolmogorov-Smirnov Test — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Kolmogorov-Smirnov Test

+

A Kolmogorov-Smirnov Test <https://en.wikipedia.org/wiki/Kolmogorov%E2%80%93Smirnov_test>`_ is +a test of equality of two distributions to determine if they are likely to have come from the same +underlying distribution. +The DataSketches library provides a modified form of the test that takes into account the error +in each underlying sketch in the analysis.

+

Currently, the test assumes both input sketches are of the same family and data type.

+
+
+ks_test(sk_1: _datasketches.kll_ints_sketch, sk_2: _datasketches.kll_ints_sketch, p: float) bool
+
+ks_test(sk_1: _datasketches.kll_floats_sketch, sk_2: _datasketches.kll_floats_sketch, p: float) bool
+
+ks_test(sk_1: _datasketches.kll_doubles_sketch, sk_2: _datasketches.kll_doubles_sketch, p: float) bool
+
+ks_test(sk_1: _datasketches.kll_items_sketch, sk_2: _datasketches.kll_items_sketch, p: float) bool
+
+ks_test(sk_1: _datasketches.quantiles_ints_sketch, sk_2: _datasketches.quantiles_ints_sketch, p: float) bool
+
+ks_test(sk_1: _datasketches.quantiles_floats_sketch, sk_2: _datasketches.quantiles_floats_sketch, p: float) bool
+
+ks_test(sk_1: _datasketches.quantiles_doubles_sketch, sk_2: _datasketches.quantiles_doubles_sketch, p: float) bool
+
+ks_test(sk_1: _datasketches.quantiles_items_sketch, sk_2: _datasketches.quantiles_items_sketch, p: float) bool
+

Overloaded function.

+
    +
  1. ks_test(sk_1: _datasketches.kll_ints_sketch, sk_2: _datasketches.kll_ints_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for kll_ints_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
    +
  1. ks_test(sk_1: _datasketches.kll_floats_sketch, sk_2: _datasketches.kll_floats_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for kll_floats_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
    +
  1. ks_test(sk_1: _datasketches.kll_doubles_sketch, sk_2: _datasketches.kll_doubles_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for kll_doubles_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
    +
  1. ks_test(sk_1: _datasketches.kll_items_sketch, sk_2: _datasketches.kll_items_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for kll_items_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
    +
  1. ks_test(sk_1: _datasketches.quantiles_ints_sketch, sk_2: _datasketches.quantiles_ints_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for quantiles_ints_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
    +
  1. ks_test(sk_1: _datasketches.quantiles_floats_sketch, sk_2: _datasketches.quantiles_floats_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for quantiles_floats_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +:Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
    +
  1. ks_test(sk_1: _datasketches.quantiles_doubles_sketch, sk_2: _datasketches.quantiles_doubles_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for quantiles_doubles_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
    +
  1. ks_test(sk_1: _datasketches.quantiles_items_sketch, sk_2: _datasketches.quantiles_items_sketch, p: float) -> bool

  2. +
+

Performs the Kolmogorov-Smirnov Test for quantiles_items_sketch pairs. +Note: if the given sketches have insufficient data or if the sketch sizes are too small, this will return false. +Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying distribution) using the provided p-value, otherwise False.

+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/main/helper/serde.html b/docs/main/helper/serde.html new file mode 100644 index 00000000..95cfd2e5 --- /dev/null +++ b/docs/main/helper/serde.html @@ -0,0 +1,251 @@ + + + + + + + + + Serialize/Deserialize (SerDe) — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Serialize/Deserialize (SerDe)

+

A SerDe is a class used to serialize items sketches to a bytes object in binary. +Several example SerDes are provided as references.

+

The use of binary-compatible SerDes in different languages is critical for cross-language compatibility.

+

Each implementation must extend the PyObjectSerDe class and override all three of its methods.

+
+
+class PyObjectSerDe(*args, **kwargs)
+

An abstract base class for serde objects. All custom serdes must extend this class.

+
+
+get_size(self, item: object) int
+

Returns the size in bytes of an item

+
+
Parameters:
+

item (object) – The specified object

+
+
Returns:
+

The size of the item in bytes

+
+
Return type:
+

int

+
+
+
+ +
+
+to_bytes(self, item: object) bytes
+

Retuns a bytes object with a serialized version of an item

+
+
Parameters:
+

item (object) – The specified object

+
+
Returns:
+

A bytes object with the serialized object

+
+
Return type:
+

bytes

+
+
+
+ +
+
+from_bytes(self, data: bytes, offset: int) tuple
+

Reads a bytes object starting from the given offest and returns a tuple of the reconstructed object and the number of additional bytes read

+
+
Parameters:
+
    +
  • data (bytes) – A bytes object from which to deserialize

  • +
  • offset (int) – The offset, in bytes, at which to start reading

  • +
+
+
Returns:
+

A tuple with the reconstructed object and the number of bytes read

+
+
Return type:
+

tuple(object, int)

+
+
+
+ +
+ +

The provided SerDes are:

+
+
+class PyStringsSerDe(*args, **kwargs)
+

Bases: PyObjectSerDe

+

Implements a simple string-encoding scheme where a string is +written as <num_bytes> <string_contents>, with no null termination. +This format allows pre-allocating each string, at the cost of +additional storage. Using this format, the serialized string consumes +4 + len(item) bytes.

+
+ +
+
+class PyIntsSerDe(*args, **kwargs)
+

Bases: PyObjectSerDe

+

Implements an integer encoding scheme where each integer is written +as a 32-bit (4 byte) little-endian value.

+
+ +
+
+class PyLongsSerDe(*args, **kwargs)
+

Bases: PyObjectSerDe

+

Implements an integer encoding scheme where each integer is written +as a 64-bit (8 byte) little-endian value.

+
+ +
+
+class PyFloatsSerDe(*args, **kwargs)
+

Bases: PyObjectSerDe

+

Implements a floating point encoding scheme where each value is written +as a 32-bit floating point value.

+
+ +
+
+class PyDoublesSerDe(*args, **kwargs)
+

Implements a floating point encoding scheme where each value is written +as a 64-bit floating point value.

+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/main/helper/tuple_policy.html b/docs/main/helper/tuple_policy.html new file mode 100644 index 00000000..f1e065bc --- /dev/null +++ b/docs/main/helper/tuple_policy.html @@ -0,0 +1,228 @@ + + + + + + + + + Tuple Policy — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Tuple Policy

+

A Tuple Policy is needed when using a tuple_sketch in order to specify how the +summary values should be created, updated, combined, or intersected. A summary can consist of +any python object.

+

Each implementation must extend the abstract base class TuplePolicy.

+
+
+class TuplePolicy(*args, **kwargs)
+

An abstract base class for Tuple Policy objects. All custom policies must extend this class.

+
+
+create_summary(self) object
+

Creates a new Summary object

+
+
Returns:
+

a Summary object

+
+
Return type:
+

object

+
+
+
+ +
+
+update_summary(self, summary: object, update: object) object
+

Applies the relevant policy to update the provided summary with the data in update.

+
+
Parameters:
+
    +
  • summary (object) – An existing Summary

  • +
  • update (object) – An update to apply to the Summary

  • +
+
+
Returns:
+

The updated Summary

+
+
Return type:
+

object

+
+
+
+ +
+
+__call__(self, summary: object, update: object) object
+

Similar to update_summary but allows a different implementation for set operations (union and intersection)

+
+
Parameters:
+
    +
  • summary (object) – An existing Summary

  • +
  • update (object) – An update to apply to the Summary

  • +
+
+
Returns:
+

The updated Summary

+
+
Return type:
+

object

+
+
+
+ +
+ +
+
+class AccumulatorPolicy
+

Bases: TuplePolicy

+

Implements an accumulatory summary policy, where new values +are added to the existing value.

+
+ +
+
+class MinIntPolicy
+

Bases: TuplePolicy

+

Implements a MIN rule, where the smallest integer value is always kept.

+
+ +
+
+class MaxIntPolicy
+

Bases: TuplePolicy

+

Implements a MAX rule, where the largest integer value is always kept.

+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/main/index.html b/docs/main/index.html new file mode 100644 index 00000000..df3fafab --- /dev/null +++ b/docs/main/index.html @@ -0,0 +1,213 @@ + + + + + + + + + Apache DataSketches — datasketches 0.1 documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Apache DataSketches

+

DataSketches are highly-efficient algorithms to analyze big data quickly.

+
+

Counting Distincts

+ +
+
+

Quantile Estimation

+ +
+
+

Frequency Sketches

+

This problem may also be known as heavy hitters or TopK

+ +
+
+

Vector Sketches

+ +
+
+

Random Sampling

+ +
+
+

Helper Classes

+ +
+

Note

+

This project is under active development.

+
+
+
+
+

Indices and tables

+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/main/objects.inv b/docs/main/objects.inv new file mode 100644 index 00000000..4e57db77 Binary files /dev/null and b/docs/main/objects.inv differ diff --git a/docs/main/quantiles/index.html b/docs/main/quantiles/index.html new file mode 100644 index 00000000..c94ed2e3 --- /dev/null +++ b/docs/main/quantiles/index.html @@ -0,0 +1,157 @@ + + + + + + + + + Quantiles Sketches — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Quantiles Sketches

+

Quantile estimation is useful for understanding the distribution of data values in a stream. The sketches currently +in the library are designed to answer queries about the rank of an item in the stream of items. That is, when +applying a global ordering on all the items, what is the portion of items seen so far that are less than (alternatively, +less-than-or-equal-to) the given item. Using straightforward logic, they can also estimate the item at a given rank +in the stream.

+

These sketches may be used to compute approximate histograms, Probability Mass Functions (PMFs), or +Cumulative Distribution Functions (CDFs).

+

The library provides four types of quantiles sketches, three of which have generic items as well as versions +specific to a given numeric type (e.g. integer or floating point values). Those three types provide error +bounds on rank estimation with proven probabilistic error distributions. t-digest is a heuristic-based sketch +that works only on numeric data, and while the error properties are not guaranteed, the sketch typically +does a good job with small storage.

+
+
    +
  • KLL: Provides uniform rank estimation error over the entire range.

  • +
  • REQ: Provides relative rank error estimates, which decreases approaching either the high or low end values.

  • +
  • t-digest: Relative rank error estimates, heuristic-based without guarantees but quite compact with generally very good error properties.

  • +
  • Classic quantiles: Largely deprecated in favor of KLL, also provides uniform rank estimation error. Included largely for backwards compatibility with historic data.

  • +
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/main/quantiles/kll.html b/docs/main/quantiles/kll.html new file mode 100644 index 00000000..d8867ed7 --- /dev/null +++ b/docs/main/quantiles/kll.html @@ -0,0 +1,960 @@ + + + + + + + + + KLL Sketch — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

KLL Sketch

+

Implementation of a very compact quantiles sketch with lazy compaction scheme +and nearly optimal accuracy per retained item. +See Optimal Quantile Approximation in Streams.

+

This is a stochastic streaming sketch that enables near real-time analysis of the +approximate distribution of items from a very large stream in a single pass, requiring only +that the items are comparable. +The analysis is obtained using get_quantile() function or the +inverse functions get_rank(), get_pmf() (Probability Mass Function), and get_cdf() +(Cumulative Distribution Function).

+

Given an input stream of N items, the natural rank of any specific +item is defined as its index (1 to N) in inclusive mode +or (0 to N-1) in exclusive mode +in the hypothetical sorted stream of all N input items.

+

The normalized rank (rank) of any specific item is defined as its +natural rank divided by N. +Thus, the normalized rank is between zero and one. +In the documentation for this sketch natural rank is never used so any +reference to just rank should be interpreted to mean normalized rank.

+

This sketch is configured with a parameter k, which affects the size of the sketch +and its estimation error.

+

The estimation error is commonly called epsilon (or eps) and is a fraction +between zero and one. Larger values of k result in smaller values of epsilon. +Epsilon is always with respect to the rank and cannot be applied to the +corresponding items.

+

The relationship between the normalized rank and the corresponding items can be viewed +as a two-dimensional monotonic plot with the normalized rank on one axis and the +corresponding items on the other axis. If the y-axis is specified as the item-axis and +the x-axis as the normalized rank, then y = get_quantile(x) is a monotonically +increasing function.

+

The function get_quantile(rank) translates ranks into +corresponding quantiles. The functions get_rank(item), +get_cdf(…) (Cumulative Distribution Function), and get_pmf(…) +(Probability Mass Function) perform the opposite operation and translate items into ranks.

+

The get_pmf(…) function has about 13 to 47% worse rank error (depending +on k) than the other queries because the mass of each “bin” of the PMF has +“double-sided” error from the upper and lower edges of the bin as a result of a subtraction, +as the errors from the two edges can sometimes add.

+

The default k of 200 yields a “single-sided” epsilon of about 1.33% and a +“double-sided” (PMF) epsilon of about 1.65%.

+

A get_quantile(rank) query has the following guarantees: +- Let q = get_quantile(r) where r is the rank between zero and one. +- The quantile q will be an item from the input stream. +- Let true_rank be the true rank of q derived from the hypothetical sorted +stream of all N items. +- Let eps = get_normalized_rank_error(false). +- Then r - eps ≤ true_rank ≤ r + eps with a confidence of 99%. Note that the +error is on the rank, not the quantile.

+

A get_rank(item) query has the following guarantees: +- Let r = get_rank(i) where i is an item between the min and max items of +the input stream. +- Let true_rank be the true rank of i derived from the hypothetical sorted +stream of all N items. +- Let eps = get_normalized_rank_error(false). +- Then r - eps ≤ true_rank ≤ r + eps with a confidence of 99%.

+

A get_pmf() query has the following guarantees: +- Let {r1, r2, …, r(m+1)} = get_pmf(s1, s2, …, sm) where s1, s2 are +split points (items from the input domain) between the min and max items of +the input stream. +- Let mass_i = estimated mass between s_i and s_i+1. +- Let true_mass be the true mass between the items of s_i, +s_i+1 derived from the hypothetical sorted stream of all N items. +- Let eps = get_normalized_rank_error(true). +- then mass - eps ≤ true_mass ≤ mass + eps with a confidence of 99%. +- r(m+1) includes the mass of all points larger than s_m.

+

A get_cdf(…) query has the following guarantees; +- Let {r1, r2, …, r(m+1)} = get_cdf(s1, s2, …, sm) where s1, s2, … are +split points (items from the input domain) between the min and max items of +the input stream. +- Let mass_i = r_(i+1) - r_i. +- Let true_mass be the true mass between the true ranks of s_i, +s_i+1 derived from the hypothetical sorted stream of all N items. +- Let eps = get_normalized_rank_error(true). +- then mass - eps ≤ true_mass ≤ mass + eps with a confidence of 99%. +- 1 - r(m+1) includes the mass of all points larger than s_m.

+

From the above, it might seem like we could make some estimates to bound the +item returned from a call to get_quantile(). The sketch, however, does not +let us derive error bounds or confidences around items. Because errors are independent, we +can approximately bracket a value as shown below, but there are no error estimates available. +Additionally, the interval may be quite large for certain distributions. +- Let q = get_quantile(r), the estimated quantile of rank r. +- Let eps = get_normalized_rank_error(false). +- Let q_lo = estimated quantile of rank (r - eps). +- Let q_hi = estimated quantile of rank (r + eps). +- Then q_lo ≤ q ≤ q_hi, with 99% confidence.

+
+

Note

+

For the kll_items_sketch, objects must be comparable with __lt__.

+
+
+

Note

+

Serializing and deserializing a kll_items_sketch requires the use of a PyObjectSerDe.

+
+
+
+class kll_ints_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.kll_ints_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 200) None
+

Creates a KLL sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 200.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given normalized rank in a hypothetical sorted version of the input stream so far. +For kll_floats_sketch: if the sketch is empty this returns nan. For kll_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: int) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=int32]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class kll_floats_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.kll_floats_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 200) None
+

Creates a KLL sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 200.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given normalized rank in a hypothetical sorted version of the input stream so far. +For kll_floats_sketch: if the sketch is empty this returns nan. For kll_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: float) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=float32]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class kll_doubles_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.kll_doubles_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 200) None
+

Creates a KLL sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 200.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given normalized rank in a hypothetical sorted version of the input stream so far. +For kll_floats_sketch: if the sketch is empty this returns nan. For kll_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: float) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=float64]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class kll_items_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe) _datasketches.kll_items_sketch
+

Deserializes the sketch from a bytes object using the provided serde.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 200) None
+

Creates a KLL sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 200.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given normalized rank in a hypothetical sorted version of the input stream so far. +For kll_floats_sketch: if the sketch is empty this returns nan. For kll_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object using the provided serde.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Updates the sketch with the given value

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/main/quantiles/quantiles_depr.html b/docs/main/quantiles/quantiles_depr.html new file mode 100644 index 00000000..9b5605ee --- /dev/null +++ b/docs/main/quantiles/quantiles_depr.html @@ -0,0 +1,902 @@ + + + + + + + + + Quantiles Sketch (Deprecated) — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Quantiles Sketch (Deprecated)

+

This is a deprecated quantiles sketch that is included for cross-language compatibility. +Most new projects will favor the KLL sketch over this one, or the REQ sketch for higher accuracy +at the very edge of a distribution.

+

This is a stochastic streaming sketch that enables near-real time analysis of the +approximate distribution from a very large stream in a single pass. +The analysis is obtained using get_rank() and get_quantile() functions, +the Probability Mass Function from get_pmf()` and the Cumulative Distribution Function from get_cdf.

+

Consider a large stream of one million values such as packet sizes coming into a network node. +The natural rank of any specific size value is its index in the hypothetical sorted +array of values. +The normalized rank is the natural rank divided by the stream size, +in this case one million. +The value corresponding to the normalized rank of 0.5 represents the 50th percentile or median +value of the distribution, or get_quantile(0.5). +Similarly, the 95th percentile is obtained from get_quantile(0.95).

+

From the min and max values, for example, 1 and 1000 bytes, +you can obtain the PMF from get_pmf(100, 500, 900) that will result in an array of +4 fractional values such as {.4, .3, .2, .1}, which means that +40% of the values were < 100, +30% of the values were ≥ 100 and < 500, +20% of the values were ≥ 500 and < 900, and +10% of the values were ≥ 900. +A frequency histogram can be obtained by multiplying these fractions by get_n(), +which is the total count of values received. +The get_cdf()` works similarly, but produces the cumulative distribution instead.

+

As of November 2021, this implementation produces serialized sketches which are binary-compatible +with the equivalent Java implementation only when template parameter T = double +(64-bit double precision values).

+

The accuracy of this sketch is a function of the configured value k, which also affects +the overall size of the sketch. Accuracy of this quantile sketch is always with respect to +the normalized rank. A k of 128 produces a normalized, rank error of about 1.7%. +For example, the median item returned from get_quantile(0.5) will be between the actual items +from the hypothetically sorted array of input items at normalized ranks of 0.483 and 0.517, with +a confidence of about 99%.

+
+

Note

+

For the quantiles_items_sketch, objects must be comparable with __lt__.

+
+
+

Note

+

Serializing and deserializing a quantiles_items_sketch requires the use of a PyObjectSerDe.

+
+
+
+class quantiles_ints_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.quantiles_ints_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 128) None
+

Creates a classic quantiles sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 128.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given rank in a hypothetical sorted version of the input stream so far. +For quantiles_floats_sketch: if the sketch is empty this returns nan. For quantiles_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: int) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=int32]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class quantiles_floats_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.quantiles_floats_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 128) None
+

Creates a classic quantiles sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 128.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given rank in a hypothetical sorted version of the input stream so far. +For quantiles_floats_sketch: if the sketch is empty this returns nan. For quantiles_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: float) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=float32]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class quantiles_doubles_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.quantiles_doubles_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 128) None
+

Creates a classic quantiles sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 128.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given rank in a hypothetical sorted version of the input stream so far. +For quantiles_floats_sketch: if the sketch is empty this returns nan. For quantiles_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: float) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=float64]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class quantiles_items_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe) _datasketches.quantiles_items_sketch
+

Deserializes the sketch from a bytes object using the provided serde.

+
+ +
+
+get_normalized_rank_error(k: int, as_pmf: bool) float
+

Gets the normalized rank error given parameters k and the pmf flag. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 128) None
+

Creates a classic quantiles sketch instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 128.

+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +The definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given rank in a hypothetical sorted version of the input stream so far. +For quantiles_floats_sketch: if the sketch is empty this returns nan. For quantiles_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+normalized_rank_error
+

Gets the normalized rank error for this sketch. +If pmf is True, returns the ‘double-sided’ normalized rank error for the get_PMF() function. +Otherwise, it is the ‘single-sided’ normalized rank error for all the other queries. +Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object using the provided serde.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Updates the sketch with the given value

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/main/quantiles/req.html b/docs/main/quantiles/req.html new file mode 100644 index 00000000..c81e563a --- /dev/null +++ b/docs/main/quantiles/req.html @@ -0,0 +1,753 @@ + + + + + + + + + Relative Error Quantiles (REQ) Sketch — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Relative Error Quantiles (REQ) Sketch

+

This is an implementation based on the paper “Relative Error Streaming Quantiles” by Graham Cormode, Zohar Karnin, Edo Liberty, Justin Thaler, Pavel Veselý, and loosely derived from a Python prototype written by Pavel Veselý.

+

This implementation differs from the algorithm described in the paper in the following:

+

The algorithm requires no upper bound on the stream length. +Instead, each relative-compactor counts the number of compaction operations performed so far (via variable state). +Initially, the relative-compactor starts with INIT_NUMBER_OF_SECTIONS. +Each time the number of compactions (variable state) exceeds 2^{numSections - 1}, we double numSections. +Note that after merging the sketch with another one variable state may not correspond to the number of compactions performed at a particular level, however, +since the state variable never exceeds the number of compactions, the guarantees of the sketch remain valid.

+

The size of each section (variable k and section_size in the code and parameter k in the paper) is +initialized with a number set by the user via variable k. +When the number of sections doubles, we decrease section_size by a factor of sqrt(2). +This is applied at each level separately. +Thus, when we double the number of sections, the nominal compactor size increases by a factor of approx. sqrt(2) (+/- rounding).

+

The merge operation here does not perform “special compactions”, which are used in the paper to allow for a tight mathematical analysis of the sketch. +This implementation provides a number of capabilities not discussed in the paper or provided in the Python prototype.

+

The Python prototype only implemented high accuracy for low ranks. This implementation provides the user with the ability to +choose either high rank accuracy or low rank accuracy at the time of sketch construction. +The Python prototype only implemented a comparison criterion of INCLUSIVE. +This implementation allows the user to use both the INCLUSIVE criterion and the EXCLUSIVE criterion. +This implementation provides extensive debug visibility into the operation of the sketch with two levels of detail output. +This is not only useful for debugging, but is a powerful tool to help users understand how the sketch works.

+
+

Note

+

For the req_items_sketch, objects must be comparable with __lt__.

+
+
+

Note

+

Serializing and deserializing a req_items_sketch requires the use of a PyObjectSerDe.

+
+
+
+class req_ints_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.req_ints_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_RSE(k: int, rank: float, is_hra: bool, n: int) float
+

Returns an a priori estimate of relative standard error (RSE, expressed as a number in [0,1]). Derived from Lemma 12 in http://arxiv.org/abs/2004.01668v2, but the constant factors have been modified based on empirical measurements, for a given value of parameter k. +Normalized rank must be a value between 0.0 and 1.0 (inclusive). If is_hra is True, uses high rank accuracy mode, else low rank accuracy. N is an estimate of the total number of points provided to the sketch.

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 12, is_hra: bool = True) None
+

Creates an REQ sketch instance with the given value of k.

+
+
Parameters:
+
    +
  • k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 12.

  • +
  • is_hra (bool, optional) – Specifies whether the skech has High Rank Accuracy (True) or Low Rank Accuracy. Default True.

  • +
+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, req_floats_sketch returns nan; req_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, req_floats_sketch returns nan; req_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given normalized rank in a hypothetical sorted version of the input stream so far. +For req_floats_sketch: if the sketch is empty this returns nan. For req_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+get_rank_lower_bound
+

Returns an approximate lower bound on the given normalized rank. +Normalized rank must be a value between 0.0 and 1.0 (inclusive); the number of standard deviations must be 1, 2, or 3.

+
+ +
+
+get_rank_upper_bound
+

Returns an approximate upper bound on the given normalized rank. +Normalized rank must be a value between 0.0 and 1.0 (inclusive); the number of standard deviations must be 1, 2, or 3.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+is_hra
+

Returns True if the sketch is in High Rank Accuracy mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: int) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=int32]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class req_floats_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.req_floats_sketch
+

Deserializes the sketch from a bytes object.

+
+ +
+
+get_RSE(k: int, rank: float, is_hra: bool, n: int) float
+

Returns an a priori estimate of relative standard error (RSE, expressed as a number in [0,1]). Derived from Lemma 12 in http://arxiv.org/abs/2004.01668v2, but the constant factors have been modified based on empirical measurements, for a given value of parameter k. +Normalized rank must be a value between 0.0 and 1.0 (inclusive). If is_hra is True, uses high rank accuracy mode, else low rank accuracy. N is an estimate of the total number of points provided to the sketch.

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 12, is_hra: bool = True) None
+

Creates an REQ sketch instance with the given value of k.

+
+
Parameters:
+
    +
  • k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 12.

  • +
  • is_hra (bool, optional) – Specifies whether the skech has High Rank Accuracy (True) or Low Rank Accuracy. Default True.

  • +
+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, req_floats_sketch returns nan; req_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, req_floats_sketch returns nan; req_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given normalized rank in a hypothetical sorted version of the input stream so far. +For req_floats_sketch: if the sketch is empty this returns nan. For req_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+get_rank_lower_bound
+

Returns an approximate lower bound on the given normalized rank. +Normalized rank must be a value between 0.0 and 1.0 (inclusive); the number of standard deviations must be 1, 2, or 3.

+
+ +
+
+get_rank_upper_bound
+

Returns an approximate upper bound on the given normalized rank. +Normalized rank must be a value between 0.0 and 1.0 (inclusive); the number of standard deviations must be 1, 2, or 3.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+is_hra
+

Returns True if the sketch is in High Rank Accuracy mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: float) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=float32]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class req_items_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe) _datasketches.req_items_sketch
+

Deserializes the sketch from a bytes object using the provided serde.

+
+ +
+
+get_RSE(k: int, rank: float, is_hra: bool, n: int) float
+

Returns an a priori estimate of relative standard error (RSE, expressed as a number in [0,1]). Derived from Lemma 12 in http://arxiv.org/abs/2004.01668v2, but the constant factors have been modified based on empirical measurements, for a given value of parameter k. +Normalized rank must be a value between 0.0 and 1.0 (inclusive). If is_hra is True, uses high rank accuracy mode, else low rank accuracy. N is an estimate of the total number of points provided to the sketch.

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 12, is_hra: bool = True) None
+

Creates an REQ sketch instance with the given value of k.

+
+
Parameters:
+
    +
  • k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 12.

  • +
  • is_hra (bool, optional) – Specifies whether the skech has High Rank Accuracy (True) or Low Rank Accuracy. Default True.

  • +
+
+
+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, req_floats_sketch returns nan; req_ints_sketch throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, req_floats_sketch returns nan; req_ints_sketch throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +The resulting approximations have a probabilistic guarantee that can be obtained from the get_normalized_rank_error(True) function. +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +If the parameter inclusive=false, the definition of an ‘interval’ is inclusive of the left split point (or minimum value) and exclusive of the right split point, with the exception that the last interval will include the maximum value. +If the parameter inclusive=true, the definition of an ‘interval’ is exclusive of the left split point (or minimum value) and inclusive of the right split point. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given normalized rank in a hypothetical sorted version of the input stream so far. +For req_floats_sketch: if the sketch is empty this returns nan. For req_ints_sketch: if the sketch is empty this throws a RuntimeError.

+
+ +
+
+get_quantiles
+

This returns an array that could have been generated by using get_quantile() for each normalized rank separately. +If the sketch is empty this returns an empty vector.

+
+ +
+
+get_rank
+

Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive. +The resulting approximation has a probabilistic guarantee that can be obtained from the get_normalized_rank_error(False) function. +With the parameter inclusive=true the weight of the given value is included into the rank.Otherwise the rank equals the sum of the weights of values less than the given value. +If the sketch is empty this returns nan.

+
+ +
+
+get_rank_lower_bound
+

Returns an approximate lower bound on the given normalized rank. +Normalized rank must be a value between 0.0 and 1.0 (inclusive); the number of standard deviations must be 1, 2, or 3.

+
+ +
+
+get_rank_upper_bound
+

Returns an approximate upper bound on the given normalized rank. +Normalized rank must be a value between 0.0 and 1.0 (inclusive); the number of standard deviations must be 1, 2, or 3.

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+is_hra
+

Returns True if the sketch is in High Rank Accuracy mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object using the provided serde.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Updates the sketch with the given value

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/main/quantiles/tdigest.html b/docs/main/quantiles/tdigest.html new file mode 100644 index 00000000..dde4f4b8 --- /dev/null +++ b/docs/main/quantiles/tdigest.html @@ -0,0 +1,445 @@ + + + + + + + + + t-digest — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

t-digest

+

The implementation in this library is based on the MergingDigest described in +Computing Extremely Accurate Quantiles Using t-Digests by Ted Dunning and Otmar Ertl.

+

The implementation in this library has a few differences from the reference implementation associated with that paper:

+
    +
  • Merge does not modify the input

  • +
  • Derialization similar to other sketches in this library, although reading the reference implementation format is supported

  • +
+

Unlike all other algorithms in the library, t-digest is empirical and has no mathematical basis for estimating its error +and its results are dependent on the input data. However, for many common data distributions, it can produce excellent results. +t-digest also operates only on numeric data and, unlike the quantiles family algorithms in the library which return quantile +approximations from the input domain, t-digest interpolates values and will hold and return data points not seen in the input.

+

The closest alternative to t-digest in this library is REQ sketch. It prioritizes one chosen side of the rank domain: +either low rank accuracy or high rank accuracy. t-digest (in this implementation) prioritizes both ends of the rank domain +and has lower accuracy towards the middle of the rank domain (median).

+

Measurements show that t-digest is slightly biased (tends to underestimate low ranks and overestimate high ranks), while still +doing very well close to the extremes. The effect seems to be more pronounced with more input values.

+

For more information on the performance characteristics, see the Datasketches page on t-digest.

+
+
+class tdigest_float(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.tdigest_float
+

Deserializes the sketch from a bytes object.

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 200) None
+

Creates a tdigest instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 200.

+
+
+
+ +
+
+compress
+

Process buffered values and merge centroids, if necesssary

+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given rank in a hypothetical sorted version of the input stream so far.

+
+ +
+
+get_rank
+

Computes the approximate normalized rank of the given value

+
+ +
+
+get_serialized_size_bytes
+

Returns the size of the serialized sketch, in bytes

+
+ +
+
+get_total_weight
+

The total weight processed by the sketch

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: float) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=float32]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+
+class tdigest_double(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes) _datasketches.tdigest_double
+

Deserializes the sketch from a bytes object.

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int = 200) None
+

Creates a tdigest instance with the given value of k.

+
+
Parameters:
+

k (int, optional) – Controls the size/accuracy trade-off of the sketch. Default is 200.

+
+
+
+ +
+
+compress
+

Process buffered values and merge centroids, if necesssary

+
+ +
+
+get_cdf
+

Returns an approximation to the Cumulative Distribution Function (CDF), which is the cumulative analog of the PMF, of the input stream given a set of split points (values). +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_max_value
+

Returns the maximum value from the stream. If empty, throws a RuntimeError

+
+ +
+
+get_min_value
+

Returns the minimum value from the stream. If empty, throws a RuntimeError

+
+ +
+
+get_pmf
+

Returns an approximation to the Probability Mass Function (PMF) of the input stream given a set of split points (values). +If the sketch is empty this returns an empty vector. +split_points is an array of m unique, monotonically increasing float values that divide the real number line into m+1 consecutive disjoint intervals. +It is not necessary to include either the min or max values in these split points.

+
+ +
+
+get_quantile
+

Returns an approximation to the data value associated with the given rank in a hypothetical sorted version of the input stream so far.

+
+ +
+
+get_rank
+

Computes the approximate normalized rank of the given value

+
+ +
+
+get_serialized_size_bytes
+

Returns the size of the serialized sketch, in bytes

+
+ +
+
+get_total_weight
+

The total weight processed by the sketch

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object.

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Overloaded function.

+
    +
  1. update(self, item: float) -> None

  2. +
+

Updates the sketch with the given value

+
    +
  1. update(self, array: ndarray[dtype=float64]) -> None

  2. +
+

Updates the sketch with the values in the given array

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/main/sampling/ebpps.html b/docs/main/sampling/ebpps.html new file mode 100644 index 00000000..8702d120 --- /dev/null +++ b/docs/main/sampling/ebpps.html @@ -0,0 +1,236 @@ + + + + + + + + + Exact and Bounded, Probabilitiy Proportional to Size (EBPPS) Sampling — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Exact and Bounded, Probabilitiy Proportional to Size (EBPPS) Sampling

+

An EBPPS sketch produces a randome sample of data from a stream of items, ensuring that the probability +of including an item is always exactly equal to the item’s size. The size of an item is defined as its +weight relative to the total weight of all items seen so far by the sketch. In contrast to VarOpt sampling, +this sketch may return fewer than k items in order to keep the probability of including an item strictly +proportional to its size.

+

This sketch is based on: B. Hentschel, P. J. Haas, Y. Tian +“Exact PPS Sampling with Bounded Sample Size”, +Information Processing Letters, 2023.

+

EBPPS sampling is related to reservoir sampling, but handles unequal item weights. +Feeding the sketch items with a uniform weight value will produce a sample equivalent to reservoir sampling.

+
+

Note

+

Serializing and deserializing this sketch requires the use of a PyObjectSerDe.

+
+
+
+class ebpps_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe) _datasketches.ebpps_sketch
+

Reads a bytes object and returns the corresponding ebpps_sketch

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int) None
+

Creates a new EBPPS sketch instance

+
+
Parameters:
+

k (int) – Maximum number of samples in the sketch

+
+
+
+ +
+
+property c
+

The expected number of samples returned upon a call to get_result() or the creation of an iterator. The number is a floating point value, where the fractional portion represents the probability of including a “partial item” from the sample. The value C should be no larger than the sketch’s configured value of k, although numerical precision limitations mean it may exceed k by double precision floating point error margins in certain cases.

+
+ +
+
+get_serialized_size_bytes
+

Computes the size in bytes needed to serialize the current sketch

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+property k
+

The sketch’s maximum configured sample size

+
+ +
+
+merge
+

Merges the sketch with the given sketch

+
+ +
+
+property n
+

The total stream length

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object

+
+ +
+
+to_string
+

Produces a string summary of the sketch and optionally prints the items

+
+ +
+
+update
+

Updates the sketch with the given value and weight

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/main/sampling/index.html b/docs/main/sampling/index.html new file mode 100644 index 00000000..8bb64355 --- /dev/null +++ b/docs/main/sampling/index.html @@ -0,0 +1,145 @@ + + + + + + + + + Random Sampling Sketches — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Random Sampling Sketches

+

These sketches are used to randomly sample items. The length of the input +stream does not need to be known in advance.

+

Both VarOpt (Variance Optimal) and EBPPS (Exact and Bounded, +Probability Proportional to Size) sketches will include sample items based on +each item’s weight relative to the weight of the entire stream but +they differ in details:

+
+
    +
  • ebpps_sketch ensures that the probability of including an item is always exactly proportional to the item’s weight.

  • +
  • var_opt_sketch optimizes for applying a predicate to the resulting sample such that the variance of the subset sum after applying the predicate is minimized, even if the inclusion probability differs somewhat from being proportional to the item’s weight.

  • +
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/main/sampling/varopt.html b/docs/main/sampling/varopt.html new file mode 100644 index 00000000..6a988363 --- /dev/null +++ b/docs/main/sampling/varopt.html @@ -0,0 +1,298 @@ + + + + + + + + + Variance Optimal Sampling (VarOpt) — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Variance Optimal Sampling (VarOpt)

+

A VarOpt sketch samples data from a stream of items. The sketch is desinged for optimal (minimum) +variance when querying the sketch to estimate subset sums of items matching a provided predicate. +The sketch will produce a sample of size k (or smaller if fewer items have been presented), with +the probability of including an item roughly corresponding it the item’s weight relative to the total +weight of all items presented to the sketch.

+

VarOpt sampling is related to reservoir sampling, with improved error bounds for subset sum estimation. +Feeding the sketch items with a uniform weight value will produce a sample equivalent to reservoir sampling.

+
+

Note

+

Serializing and deserializing this sketch requires the use of a PyObjectSerDe.

+
+
+
+class var_opt_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe) _datasketches.var_opt_sketch
+

Reads a bytes object and returns the corresponding var opt sketch

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int) None
+

Creates a new Var Opt sketch instance

+
+
Parameters:
+

k (int) – Maximum number of samples in the sketch

+
+
+
+ +
+
+estimate_subset_sum
+

Applies a provided predicate to the sketch and returns the estimated total weight matching the predicate, as well as upper and lower bounds on the estimate and the total weight processed by the sketch

+
+ +
+
+get_serialized_size_bytes
+

Computes the size in bytes needed to serialize the current sketch

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+property k
+

Returns the sketch’s maximum configured sample size

+
+ +
+
+property n
+

Returns the total stream length

+
+ +
+
+property num_samples
+

Returns the number of samples currently in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object

+
+ +
+
+to_string
+

Produces a string summary of the sketch and optionally prints the items

+
+ +
+
+update
+

Updates the sketch with the given value and weight

+
+ +
+ +
+
+class var_opt_union(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, serde: _datasketches.PyObjectSerDe) _datasketches.var_opt_union
+

Constructs a var opt union from the given bytes using the provided serde

+
+ +

Non-static Methods:

+
+
+__init__(self, max_k: int) None
+
+ +
+
+get_result
+

Returns a sketch corresponding to the union result

+
+ +
+
+get_serialized_size_bytes
+

Computes the size in bytes needed to serialize the current union

+
+ +
+
+reset
+

Resets the union to the empty state

+
+ +
+
+serialize
+

Serializes the union into a bytes object with the provided serde

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Updates the union with the given sketch

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/main/search.html b/docs/main/search.html new file mode 100644 index 00000000..d26add38 --- /dev/null +++ b/docs/main/search.html @@ -0,0 +1,134 @@ + + + + + + + + Search — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ + + + +
+ +
+ +
+
+ +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/docs/main/searchindex.js b/docs/main/searchindex.js new file mode 100644 index 00000000..e0046614 --- /dev/null +++ b/docs/main/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"alltitles":{"Apache DataSketches":[[14,null]],"Compressed Probabilistic Counting (CPC)":[[0,null]],"CountMin Sketch":[[5,null]],"Counting Distincts":[[14,"counting-distincts"]],"Density Sketch":[[23,null]],"Distinct Counting":[[2,null]],"Exact and Bounded, Probabilitiy Proportional to Size (EBPPS) Sampling":[[20,null]],"Frequency Sketches":[[7,null],[14,"frequency-sketches"]],"Frequent Items":[[6,null]],"Helper Classes":[[8,null],[14,"helper-classes"]],"HyperLogLog (HLL)":[[1,null]],"Indices and tables":[[14,"indices-and-tables"]],"Jaccard Similarity":[[9,null]],"KLL Sketch":[[16,null]],"Kernel Function":[[10,null]],"Kolmogorov-Smirnov Test":[[11,null]],"Quantile Estimation":[[14,"quantile-estimation"]],"Quantiles Sketch (Deprecated)":[[17,null]],"Quantiles Sketches":[[15,null]],"Random Sampling":[[14,"random-sampling"]],"Random Sampling Sketches":[[21,null]],"Relative Error Quantiles (REQ) Sketch":[[18,null]],"Serialize/Deserialize (SerDe)":[[12,null]],"Theta Sketch":[[3,null]],"Tuple Policy":[[13,null]],"Tuple Sketch":[[4,null]],"Variance Optimal Sampling (VarOpt)":[[22,null]],"Vector Sketches":[[14,"vector-sketches"],[24,null]],"t-digest":[[19,null]]},"docnames":["distinct_counting/cpc","distinct_counting/hyper_log_log","distinct_counting/index","distinct_counting/theta","distinct_counting/tuple","frequency/count_min_sketch","frequency/frequent_items","frequency/index","helper/index","helper/jaccard","helper/kernel","helper/ks_test","helper/serde","helper/tuple_policy","index","quantiles/index","quantiles/kll","quantiles/quantiles_depr","quantiles/req","quantiles/tdigest","sampling/ebpps","sampling/index","sampling/varopt","vector/density_sketch","vector/index"],"envversion":{"sphinx":65,"sphinx.domains.c":3,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":9,"sphinx.domains.index":1,"sphinx.domains.javascript":3,"sphinx.domains.math":2,"sphinx.domains.python":4,"sphinx.domains.rst":2,"sphinx.domains.std":2},"filenames":["distinct_counting/cpc.rst","distinct_counting/hyper_log_log.rst","distinct_counting/index.rst","distinct_counting/theta.rst","distinct_counting/tuple.rst","frequency/count_min_sketch.rst","frequency/frequent_items.rst","frequency/index.rst","helper/index.rst","helper/jaccard.rst","helper/kernel.rst","helper/ks_test.rst","helper/serde.rst","helper/tuple_policy.rst","index.rst","quantiles/index.rst","quantiles/kll.rst","quantiles/quantiles_depr.rst","quantiles/req.rst","quantiles/tdigest.rst","sampling/ebpps.rst","sampling/index.rst","sampling/varopt.rst","vector/density_sketch.rst","vector/index.rst"],"indexentries":{"__call__() (kernelfunction method)":[[10,"datasketches.KernelFunction.__call__",false]],"__call__() (tuplepolicy method)":[[13,"datasketches.TuplePolicy.__call__",false]],"__init__() (compact_theta_sketch method)":[[3,"datasketches.compact_theta_sketch.__init__",false]],"__init__() (compact_tuple_sketch method)":[[4,"datasketches.compact_tuple_sketch.__init__",false]],"__init__() (cpc_sketch method)":[[0,"datasketches.cpc_sketch.__init__",false]],"__init__() (cpc_union method)":[[0,"datasketches.cpc_union.__init__",false]],"__init__() (density_sketch method)":[[23,"datasketches.density_sketch.__init__",false]],"__init__() (ebpps_sketch method)":[[20,"datasketches.ebpps_sketch.__init__",false]],"__init__() (frequent_items_sketch method)":[[6,"datasketches.frequent_items_sketch.__init__",false]],"__init__() (frequent_strings_sketch method)":[[6,"datasketches.frequent_strings_sketch.__init__",false]],"__init__() (hll_sketch method)":[[1,"datasketches.hll_sketch.__init__",false]],"__init__() (hll_union method)":[[1,"datasketches.hll_union.__init__",false]],"__init__() (kll_doubles_sketch method)":[[16,"datasketches.kll_doubles_sketch.__init__",false]],"__init__() (kll_floats_sketch method)":[[16,"datasketches.kll_floats_sketch.__init__",false]],"__init__() (kll_ints_sketch method)":[[16,"datasketches.kll_ints_sketch.__init__",false]],"__init__() (kll_items_sketch method)":[[16,"datasketches.kll_items_sketch.__init__",false]],"__init__() (quantiles_doubles_sketch method)":[[17,"datasketches.quantiles_doubles_sketch.__init__",false]],"__init__() (quantiles_floats_sketch method)":[[17,"datasketches.quantiles_floats_sketch.__init__",false]],"__init__() (quantiles_ints_sketch method)":[[17,"datasketches.quantiles_ints_sketch.__init__",false]],"__init__() (quantiles_items_sketch method)":[[17,"datasketches.quantiles_items_sketch.__init__",false]],"__init__() (req_floats_sketch method)":[[18,"datasketches.req_floats_sketch.__init__",false]],"__init__() (req_ints_sketch method)":[[18,"datasketches.req_ints_sketch.__init__",false]],"__init__() (req_items_sketch method)":[[18,"datasketches.req_items_sketch.__init__",false]],"__init__() (tdigest_double method)":[[19,"datasketches.tdigest_double.__init__",false]],"__init__() (tdigest_float method)":[[19,"datasketches.tdigest_float.__init__",false]],"__init__() (theta_a_not_b method)":[[3,"datasketches.theta_a_not_b.__init__",false]],"__init__() (theta_intersection method)":[[3,"datasketches.theta_intersection.__init__",false]],"__init__() (theta_union method)":[[3,"datasketches.theta_union.__init__",false]],"__init__() (tuple_a_not_b method)":[[4,"datasketches.tuple_a_not_b.__init__",false]],"__init__() (tuple_intersection method)":[[4,"datasketches.tuple_intersection.__init__",false]],"__init__() (tuple_union method)":[[4,"datasketches.tuple_union.__init__",false]],"__init__() (update_theta_sketch method)":[[3,"datasketches.update_theta_sketch.__init__",false]],"__init__() (update_tuple_sketch method)":[[4,"datasketches.update_tuple_sketch.__init__",false]],"__init__() (var_opt_sketch method)":[[22,"datasketches.var_opt_sketch.__init__",false]],"__init__() (var_opt_union method)":[[22,"datasketches.var_opt_union.__init__",false]],"accumulatorpolicy (class in datasketches)":[[13,"datasketches.AccumulatorPolicy",false]],"c (ebpps_sketch property)":[[20,"datasketches.ebpps_sketch.c",false]],"compact (update_theta_sketch attribute)":[[3,"datasketches.update_theta_sketch.compact",false]],"compact (update_tuple_sketch attribute)":[[4,"datasketches.update_tuple_sketch.compact",false]],"compact_theta_sketch (class in datasketches)":[[3,"datasketches.compact_theta_sketch",false]],"compact_tuple_sketch (class in datasketches)":[[4,"datasketches.compact_tuple_sketch",false]],"compress (tdigest_double attribute)":[[19,"datasketches.tdigest_double.compress",false]],"compress (tdigest_float attribute)":[[19,"datasketches.tdigest_float.compress",false]],"compute (theta_a_not_b attribute)":[[3,"datasketches.theta_a_not_b.compute",false]],"compute (tuple_a_not_b attribute)":[[4,"datasketches.tuple_a_not_b.compute",false]],"count_min_sketch (class in _datasketches)":[[5,"datasketches.count_min_sketch",false]],"cpc_sketch (class in _datasketches)":[[0,"datasketches.cpc_sketch",false]],"cpc_union (class in _datasketches)":[[0,"datasketches.cpc_union",false]],"create_summary() (tuplepolicy method)":[[13,"datasketches.TuplePolicy.create_summary",false]],"default_seed (tuple_sketch attribute)":[[4,"datasketches.tuple_sketch.DEFAULT_SEED",false]],"density_sketch (class in datasketches)":[[23,"datasketches.density_sketch",false]],"deserialize() (compact_theta_sketch method)":[[3,"datasketches.compact_theta_sketch.deserialize",false]],"deserialize() (compact_tuple_sketch method)":[[4,"datasketches.compact_tuple_sketch.deserialize",false]],"deserialize() (count_min_sketch method)":[[5,"datasketches.count_min_sketch.deserialize",false]],"deserialize() (cpc_sketch method)":[[0,"datasketches.cpc_sketch.deserialize",false]],"deserialize() (density_sketch method)":[[23,"datasketches.density_sketch.deserialize",false]],"deserialize() (ebpps_sketch method)":[[20,"datasketches.ebpps_sketch.deserialize",false]],"deserialize() (frequent_items_sketch method)":[[6,"datasketches.frequent_items_sketch.deserialize",false]],"deserialize() (frequent_strings_sketch method)":[[6,"datasketches.frequent_strings_sketch.deserialize",false]],"deserialize() (hll_sketch method)":[[1,"datasketches.hll_sketch.deserialize",false]],"deserialize() (kll_doubles_sketch method)":[[16,"datasketches.kll_doubles_sketch.deserialize",false]],"deserialize() (kll_floats_sketch method)":[[16,"datasketches.kll_floats_sketch.deserialize",false]],"deserialize() (kll_ints_sketch method)":[[16,"datasketches.kll_ints_sketch.deserialize",false]],"deserialize() (kll_items_sketch method)":[[16,"datasketches.kll_items_sketch.deserialize",false]],"deserialize() (quantiles_doubles_sketch method)":[[17,"datasketches.quantiles_doubles_sketch.deserialize",false]],"deserialize() (quantiles_floats_sketch method)":[[17,"datasketches.quantiles_floats_sketch.deserialize",false]],"deserialize() (quantiles_ints_sketch method)":[[17,"datasketches.quantiles_ints_sketch.deserialize",false]],"deserialize() (quantiles_items_sketch method)":[[17,"datasketches.quantiles_items_sketch.deserialize",false]],"deserialize() (req_floats_sketch method)":[[18,"datasketches.req_floats_sketch.deserialize",false]],"deserialize() (req_ints_sketch method)":[[18,"datasketches.req_ints_sketch.deserialize",false]],"deserialize() (req_items_sketch method)":[[18,"datasketches.req_items_sketch.deserialize",false]],"deserialize() (tdigest_double method)":[[19,"datasketches.tdigest_double.deserialize",false]],"deserialize() (tdigest_float method)":[[19,"datasketches.tdigest_float.deserialize",false]],"deserialize() (var_opt_sketch method)":[[22,"datasketches.var_opt_sketch.deserialize",false]],"deserialize() (var_opt_union method)":[[22,"datasketches.var_opt_union.deserialize",false]],"dim (density_sketch property)":[[23,"datasketches.density_sketch.dim",false]],"dissimilarity_test() (theta_jaccard_similarity method)":[[9,"datasketches.theta_jaccard_similarity.dissimilarity_test",false]],"dissimilarity_test() (tuple_jaccard_similarity method)":[[9,"datasketches.tuple_jaccard_similarity.dissimilarity_test",false]],"ebpps_sketch (class in datasketches)":[[20,"datasketches.ebpps_sketch",false]],"epsilon (frequent_items_sketch property)":[[6,"datasketches.frequent_items_sketch.epsilon",false]],"epsilon (frequent_strings_sketch property)":[[6,"datasketches.frequent_strings_sketch.epsilon",false]],"estimate_subset_sum (var_opt_sketch attribute)":[[22,"datasketches.var_opt_sketch.estimate_subset_sum",false]],"exactly_equal() (theta_jaccard_similarity method)":[[9,"datasketches.theta_jaccard_similarity.exactly_equal",false]],"exactly_equal() (tuple_jaccard_similarity method)":[[9,"datasketches.tuple_jaccard_similarity.exactly_equal",false]],"filter (compact_tuple_sketch attribute)":[[4,"datasketches.compact_tuple_sketch.filter",false]],"filter (update_tuple_sketch attribute)":[[4,"datasketches.update_tuple_sketch.filter",false]],"frequent_items_error_type (class in datasketches)":[[6,"datasketches.frequent_items_error_type",false]],"frequent_items_sketch (class in datasketches)":[[6,"datasketches.frequent_items_sketch",false]],"frequent_strings_sketch (class in datasketches)":[[6,"datasketches.frequent_strings_sketch",false]],"from_bytes() (pyobjectserde method)":[[12,"datasketches.PyObjectSerDe.from_bytes",false]],"gaussiankernel (class in datasketches)":[[10,"datasketches.GaussianKernel",false]],"get_apriori_error() (frequent_items_sketch method)":[[6,"datasketches.frequent_items_sketch.get_apriori_error",false]],"get_apriori_error() (frequent_strings_sketch method)":[[6,"datasketches.frequent_strings_sketch.get_apriori_error",false]],"get_cdf (kll_doubles_sketch attribute)":[[16,"datasketches.kll_doubles_sketch.get_cdf",false]],"get_cdf (kll_floats_sketch attribute)":[[16,"datasketches.kll_floats_sketch.get_cdf",false]],"get_cdf (kll_ints_sketch attribute)":[[16,"datasketches.kll_ints_sketch.get_cdf",false]],"get_cdf (kll_items_sketch attribute)":[[16,"datasketches.kll_items_sketch.get_cdf",false]],"get_cdf (quantiles_doubles_sketch attribute)":[[17,"datasketches.quantiles_doubles_sketch.get_cdf",false]],"get_cdf (quantiles_floats_sketch attribute)":[[17,"datasketches.quantiles_floats_sketch.get_cdf",false]],"get_cdf (quantiles_ints_sketch attribute)":[[17,"datasketches.quantiles_ints_sketch.get_cdf",false]],"get_cdf (quantiles_items_sketch attribute)":[[17,"datasketches.quantiles_items_sketch.get_cdf",false]],"get_cdf (req_floats_sketch attribute)":[[18,"datasketches.req_floats_sketch.get_cdf",false]],"get_cdf (req_ints_sketch attribute)":[[18,"datasketches.req_ints_sketch.get_cdf",false]],"get_cdf (req_items_sketch attribute)":[[18,"datasketches.req_items_sketch.get_cdf",false]],"get_cdf (tdigest_double attribute)":[[19,"datasketches.tdigest_double.get_cdf",false]],"get_cdf (tdigest_float attribute)":[[19,"datasketches.tdigest_float.get_cdf",false]],"get_compact_serialization_bytes (hll_sketch attribute)":[[1,"datasketches.hll_sketch.get_compact_serialization_bytes",false]],"get_epsilon_for_lg_size() (frequent_items_sketch method)":[[6,"datasketches.frequent_items_sketch.get_epsilon_for_lg_size",false]],"get_epsilon_for_lg_size() (frequent_strings_sketch method)":[[6,"datasketches.frequent_strings_sketch.get_epsilon_for_lg_size",false]],"get_estimate (count_min_sketch attribute)":[[5,"datasketches.count_min_sketch.get_estimate",false]],"get_estimate (cpc_sketch attribute)":[[0,"datasketches.cpc_sketch.get_estimate",false]],"get_estimate (density_sketch attribute)":[[23,"datasketches.density_sketch.get_estimate",false]],"get_estimate (frequent_items_sketch attribute)":[[6,"datasketches.frequent_items_sketch.get_estimate",false]],"get_estimate (frequent_strings_sketch attribute)":[[6,"datasketches.frequent_strings_sketch.get_estimate",false]],"get_estimate (hll_sketch attribute)":[[1,"datasketches.hll_sketch.get_estimate",false]],"get_estimate (hll_union attribute)":[[1,"datasketches.hll_union.get_estimate",false]],"get_estimate (theta_sketch attribute)":[[3,"datasketches.theta_sketch.get_estimate",false]],"get_estimate (tuple_sketch attribute)":[[4,"datasketches.tuple_sketch.get_estimate",false]],"get_frequent_items (frequent_items_sketch attribute)":[[6,"datasketches.frequent_items_sketch.get_frequent_items",false]],"get_frequent_items (frequent_strings_sketch attribute)":[[6,"datasketches.frequent_strings_sketch.get_frequent_items",false]],"get_lower_bound (count_min_sketch attribute)":[[5,"datasketches.count_min_sketch.get_lower_bound",false]],"get_lower_bound (cpc_sketch attribute)":[[0,"datasketches.cpc_sketch.get_lower_bound",false]],"get_lower_bound (frequent_items_sketch attribute)":[[6,"datasketches.frequent_items_sketch.get_lower_bound",false]],"get_lower_bound (frequent_strings_sketch attribute)":[[6,"datasketches.frequent_strings_sketch.get_lower_bound",false]],"get_lower_bound (hll_sketch attribute)":[[1,"datasketches.hll_sketch.get_lower_bound",false]],"get_lower_bound (hll_union attribute)":[[1,"datasketches.hll_union.get_lower_bound",false]],"get_lower_bound (theta_sketch attribute)":[[3,"datasketches.theta_sketch.get_lower_bound",false]],"get_lower_bound (tuple_sketch attribute)":[[4,"datasketches.tuple_sketch.get_lower_bound",false]],"get_max_updatable_serialization_bytes() (hll_sketch method)":[[1,"datasketches.hll_sketch.get_max_updatable_serialization_bytes",false]],"get_max_value (kll_doubles_sketch attribute)":[[16,"datasketches.kll_doubles_sketch.get_max_value",false]],"get_max_value (kll_floats_sketch attribute)":[[16,"datasketches.kll_floats_sketch.get_max_value",false]],"get_max_value (kll_ints_sketch attribute)":[[16,"datasketches.kll_ints_sketch.get_max_value",false]],"get_max_value (kll_items_sketch attribute)":[[16,"datasketches.kll_items_sketch.get_max_value",false]],"get_max_value (quantiles_doubles_sketch attribute)":[[17,"datasketches.quantiles_doubles_sketch.get_max_value",false]],"get_max_value (quantiles_floats_sketch attribute)":[[17,"datasketches.quantiles_floats_sketch.get_max_value",false]],"get_max_value (quantiles_ints_sketch attribute)":[[17,"datasketches.quantiles_ints_sketch.get_max_value",false]],"get_max_value (quantiles_items_sketch attribute)":[[17,"datasketches.quantiles_items_sketch.get_max_value",false]],"get_max_value (req_floats_sketch attribute)":[[18,"datasketches.req_floats_sketch.get_max_value",false]],"get_max_value (req_ints_sketch attribute)":[[18,"datasketches.req_ints_sketch.get_max_value",false]],"get_max_value (req_items_sketch attribute)":[[18,"datasketches.req_items_sketch.get_max_value",false]],"get_max_value (tdigest_double attribute)":[[19,"datasketches.tdigest_double.get_max_value",false]],"get_max_value (tdigest_float attribute)":[[19,"datasketches.tdigest_float.get_max_value",false]],"get_min_value (kll_doubles_sketch attribute)":[[16,"datasketches.kll_doubles_sketch.get_min_value",false]],"get_min_value (kll_floats_sketch attribute)":[[16,"datasketches.kll_floats_sketch.get_min_value",false]],"get_min_value (kll_ints_sketch attribute)":[[16,"datasketches.kll_ints_sketch.get_min_value",false]],"get_min_value (kll_items_sketch attribute)":[[16,"datasketches.kll_items_sketch.get_min_value",false]],"get_min_value (quantiles_doubles_sketch attribute)":[[17,"datasketches.quantiles_doubles_sketch.get_min_value",false]],"get_min_value (quantiles_floats_sketch attribute)":[[17,"datasketches.quantiles_floats_sketch.get_min_value",false]],"get_min_value (quantiles_ints_sketch attribute)":[[17,"datasketches.quantiles_ints_sketch.get_min_value",false]],"get_min_value (quantiles_items_sketch attribute)":[[17,"datasketches.quantiles_items_sketch.get_min_value",false]],"get_min_value (req_floats_sketch attribute)":[[18,"datasketches.req_floats_sketch.get_min_value",false]],"get_min_value (req_ints_sketch attribute)":[[18,"datasketches.req_ints_sketch.get_min_value",false]],"get_min_value (req_items_sketch attribute)":[[18,"datasketches.req_items_sketch.get_min_value",false]],"get_min_value (tdigest_double attribute)":[[19,"datasketches.tdigest_double.get_min_value",false]],"get_min_value (tdigest_float attribute)":[[19,"datasketches.tdigest_float.get_min_value",false]],"get_normalized_rank_error() (kll_doubles_sketch method)":[[16,"datasketches.kll_doubles_sketch.get_normalized_rank_error",false]],"get_normalized_rank_error() (kll_floats_sketch method)":[[16,"datasketches.kll_floats_sketch.get_normalized_rank_error",false]],"get_normalized_rank_error() (kll_ints_sketch method)":[[16,"datasketches.kll_ints_sketch.get_normalized_rank_error",false]],"get_normalized_rank_error() (kll_items_sketch method)":[[16,"datasketches.kll_items_sketch.get_normalized_rank_error",false]],"get_normalized_rank_error() (quantiles_doubles_sketch method)":[[17,"datasketches.quantiles_doubles_sketch.get_normalized_rank_error",false]],"get_normalized_rank_error() (quantiles_floats_sketch method)":[[17,"datasketches.quantiles_floats_sketch.get_normalized_rank_error",false]],"get_normalized_rank_error() (quantiles_ints_sketch method)":[[17,"datasketches.quantiles_ints_sketch.get_normalized_rank_error",false]],"get_normalized_rank_error() (quantiles_items_sketch method)":[[17,"datasketches.quantiles_items_sketch.get_normalized_rank_error",false]],"get_pmf (kll_doubles_sketch attribute)":[[16,"datasketches.kll_doubles_sketch.get_pmf",false]],"get_pmf (kll_floats_sketch attribute)":[[16,"datasketches.kll_floats_sketch.get_pmf",false]],"get_pmf (kll_ints_sketch attribute)":[[16,"datasketches.kll_ints_sketch.get_pmf",false]],"get_pmf (kll_items_sketch attribute)":[[16,"datasketches.kll_items_sketch.get_pmf",false]],"get_pmf (quantiles_doubles_sketch attribute)":[[17,"datasketches.quantiles_doubles_sketch.get_pmf",false]],"get_pmf (quantiles_floats_sketch attribute)":[[17,"datasketches.quantiles_floats_sketch.get_pmf",false]],"get_pmf (quantiles_ints_sketch attribute)":[[17,"datasketches.quantiles_ints_sketch.get_pmf",false]],"get_pmf (quantiles_items_sketch attribute)":[[17,"datasketches.quantiles_items_sketch.get_pmf",false]],"get_pmf (req_floats_sketch attribute)":[[18,"datasketches.req_floats_sketch.get_pmf",false]],"get_pmf (req_ints_sketch attribute)":[[18,"datasketches.req_ints_sketch.get_pmf",false]],"get_pmf (req_items_sketch attribute)":[[18,"datasketches.req_items_sketch.get_pmf",false]],"get_pmf (tdigest_double attribute)":[[19,"datasketches.tdigest_double.get_pmf",false]],"get_pmf (tdigest_float attribute)":[[19,"datasketches.tdigest_float.get_pmf",false]],"get_quantile (kll_doubles_sketch attribute)":[[16,"datasketches.kll_doubles_sketch.get_quantile",false]],"get_quantile (kll_floats_sketch attribute)":[[16,"datasketches.kll_floats_sketch.get_quantile",false]],"get_quantile (kll_ints_sketch attribute)":[[16,"datasketches.kll_ints_sketch.get_quantile",false]],"get_quantile (kll_items_sketch attribute)":[[16,"datasketches.kll_items_sketch.get_quantile",false]],"get_quantile (quantiles_doubles_sketch attribute)":[[17,"datasketches.quantiles_doubles_sketch.get_quantile",false]],"get_quantile (quantiles_floats_sketch attribute)":[[17,"datasketches.quantiles_floats_sketch.get_quantile",false]],"get_quantile (quantiles_ints_sketch attribute)":[[17,"datasketches.quantiles_ints_sketch.get_quantile",false]],"get_quantile (quantiles_items_sketch attribute)":[[17,"datasketches.quantiles_items_sketch.get_quantile",false]],"get_quantile (req_floats_sketch attribute)":[[18,"datasketches.req_floats_sketch.get_quantile",false]],"get_quantile (req_ints_sketch attribute)":[[18,"datasketches.req_ints_sketch.get_quantile",false]],"get_quantile (req_items_sketch attribute)":[[18,"datasketches.req_items_sketch.get_quantile",false]],"get_quantile (tdigest_double attribute)":[[19,"datasketches.tdigest_double.get_quantile",false]],"get_quantile (tdigest_float attribute)":[[19,"datasketches.tdigest_float.get_quantile",false]],"get_quantiles (kll_doubles_sketch attribute)":[[16,"datasketches.kll_doubles_sketch.get_quantiles",false]],"get_quantiles (kll_floats_sketch attribute)":[[16,"datasketches.kll_floats_sketch.get_quantiles",false]],"get_quantiles (kll_ints_sketch attribute)":[[16,"datasketches.kll_ints_sketch.get_quantiles",false]],"get_quantiles (kll_items_sketch attribute)":[[16,"datasketches.kll_items_sketch.get_quantiles",false]],"get_quantiles (quantiles_doubles_sketch attribute)":[[17,"datasketches.quantiles_doubles_sketch.get_quantiles",false]],"get_quantiles (quantiles_floats_sketch attribute)":[[17,"datasketches.quantiles_floats_sketch.get_quantiles",false]],"get_quantiles (quantiles_ints_sketch attribute)":[[17,"datasketches.quantiles_ints_sketch.get_quantiles",false]],"get_quantiles (quantiles_items_sketch attribute)":[[17,"datasketches.quantiles_items_sketch.get_quantiles",false]],"get_quantiles (req_floats_sketch attribute)":[[18,"datasketches.req_floats_sketch.get_quantiles",false]],"get_quantiles (req_ints_sketch attribute)":[[18,"datasketches.req_ints_sketch.get_quantiles",false]],"get_quantiles (req_items_sketch attribute)":[[18,"datasketches.req_items_sketch.get_quantiles",false]],"get_rank (kll_doubles_sketch attribute)":[[16,"datasketches.kll_doubles_sketch.get_rank",false]],"get_rank (kll_floats_sketch attribute)":[[16,"datasketches.kll_floats_sketch.get_rank",false]],"get_rank (kll_ints_sketch attribute)":[[16,"datasketches.kll_ints_sketch.get_rank",false]],"get_rank (kll_items_sketch attribute)":[[16,"datasketches.kll_items_sketch.get_rank",false]],"get_rank (quantiles_doubles_sketch attribute)":[[17,"datasketches.quantiles_doubles_sketch.get_rank",false]],"get_rank (quantiles_floats_sketch attribute)":[[17,"datasketches.quantiles_floats_sketch.get_rank",false]],"get_rank (quantiles_ints_sketch attribute)":[[17,"datasketches.quantiles_ints_sketch.get_rank",false]],"get_rank (quantiles_items_sketch attribute)":[[17,"datasketches.quantiles_items_sketch.get_rank",false]],"get_rank (req_floats_sketch attribute)":[[18,"datasketches.req_floats_sketch.get_rank",false]],"get_rank (req_ints_sketch attribute)":[[18,"datasketches.req_ints_sketch.get_rank",false]],"get_rank (req_items_sketch attribute)":[[18,"datasketches.req_items_sketch.get_rank",false]],"get_rank (tdigest_double attribute)":[[19,"datasketches.tdigest_double.get_rank",false]],"get_rank (tdigest_float attribute)":[[19,"datasketches.tdigest_float.get_rank",false]],"get_rank_lower_bound (req_floats_sketch attribute)":[[18,"datasketches.req_floats_sketch.get_rank_lower_bound",false]],"get_rank_lower_bound (req_ints_sketch attribute)":[[18,"datasketches.req_ints_sketch.get_rank_lower_bound",false]],"get_rank_lower_bound (req_items_sketch attribute)":[[18,"datasketches.req_items_sketch.get_rank_lower_bound",false]],"get_rank_upper_bound (req_floats_sketch attribute)":[[18,"datasketches.req_floats_sketch.get_rank_upper_bound",false]],"get_rank_upper_bound (req_ints_sketch attribute)":[[18,"datasketches.req_ints_sketch.get_rank_upper_bound",false]],"get_rank_upper_bound (req_items_sketch attribute)":[[18,"datasketches.req_items_sketch.get_rank_upper_bound",false]],"get_rel_err() (hll_sketch method)":[[1,"datasketches.hll_sketch.get_rel_err",false]],"get_rel_err() (hll_union method)":[[1,"datasketches.hll_union.get_rel_err",false]],"get_relative_error (count_min_sketch attribute)":[[5,"datasketches.count_min_sketch.get_relative_error",false]],"get_result (cpc_union attribute)":[[0,"datasketches.cpc_union.get_result",false]],"get_result (hll_union attribute)":[[1,"datasketches.hll_union.get_result",false]],"get_result (theta_intersection attribute)":[[3,"datasketches.theta_intersection.get_result",false]],"get_result (theta_union attribute)":[[3,"datasketches.theta_union.get_result",false]],"get_result (tuple_intersection attribute)":[[4,"datasketches.tuple_intersection.get_result",false]],"get_result (tuple_union attribute)":[[4,"datasketches.tuple_union.get_result",false]],"get_result (var_opt_union attribute)":[[22,"datasketches.var_opt_union.get_result",false]],"get_rse() (req_floats_sketch method)":[[18,"datasketches.req_floats_sketch.get_RSE",false]],"get_rse() (req_ints_sketch method)":[[18,"datasketches.req_ints_sketch.get_RSE",false]],"get_rse() (req_items_sketch method)":[[18,"datasketches.req_items_sketch.get_RSE",false]],"get_seed_hash (theta_sketch attribute)":[[3,"datasketches.theta_sketch.get_seed_hash",false]],"get_seed_hash (tuple_sketch attribute)":[[4,"datasketches.tuple_sketch.get_seed_hash",false]],"get_serialized_size_bytes (count_min_sketch attribute)":[[5,"datasketches.count_min_sketch.get_serialized_size_bytes",false]],"get_serialized_size_bytes (ebpps_sketch attribute)":[[20,"datasketches.ebpps_sketch.get_serialized_size_bytes",false]],"get_serialized_size_bytes (frequent_items_sketch attribute)":[[6,"datasketches.frequent_items_sketch.get_serialized_size_bytes",false]],"get_serialized_size_bytes (frequent_strings_sketch attribute)":[[6,"datasketches.frequent_strings_sketch.get_serialized_size_bytes",false]],"get_serialized_size_bytes (tdigest_double attribute)":[[19,"datasketches.tdigest_double.get_serialized_size_bytes",false]],"get_serialized_size_bytes (tdigest_float attribute)":[[19,"datasketches.tdigest_float.get_serialized_size_bytes",false]],"get_serialized_size_bytes (var_opt_sketch attribute)":[[22,"datasketches.var_opt_sketch.get_serialized_size_bytes",false]],"get_serialized_size_bytes (var_opt_union attribute)":[[22,"datasketches.var_opt_union.get_serialized_size_bytes",false]],"get_size() (pyobjectserde method)":[[12,"datasketches.PyObjectSerDe.get_size",false]],"get_total_weight (tdigest_double attribute)":[[19,"datasketches.tdigest_double.get_total_weight",false]],"get_total_weight (tdigest_float attribute)":[[19,"datasketches.tdigest_float.get_total_weight",false]],"get_updatable_serialization_bytes (hll_sketch attribute)":[[1,"datasketches.hll_sketch.get_updatable_serialization_bytes",false]],"get_upper_bound (count_min_sketch attribute)":[[5,"datasketches.count_min_sketch.get_upper_bound",false]],"get_upper_bound (cpc_sketch attribute)":[[0,"datasketches.cpc_sketch.get_upper_bound",false]],"get_upper_bound (frequent_items_sketch attribute)":[[6,"datasketches.frequent_items_sketch.get_upper_bound",false]],"get_upper_bound (frequent_strings_sketch attribute)":[[6,"datasketches.frequent_strings_sketch.get_upper_bound",false]],"get_upper_bound (hll_sketch attribute)":[[1,"datasketches.hll_sketch.get_upper_bound",false]],"get_upper_bound (hll_union attribute)":[[1,"datasketches.hll_union.get_upper_bound",false]],"get_upper_bound (theta_sketch attribute)":[[3,"datasketches.theta_sketch.get_upper_bound",false]],"get_upper_bound (tuple_sketch attribute)":[[4,"datasketches.tuple_sketch.get_upper_bound",false]],"has_result (theta_intersection attribute)":[[3,"datasketches.theta_intersection.has_result",false]],"has_result (tuple_intersection attribute)":[[4,"datasketches.tuple_intersection.has_result",false]],"hll_4 (tgt_hll_type attribute)":[[1,"datasketches.tgt_hll_type.HLL_4",false]],"hll_6 (tgt_hll_type attribute)":[[1,"datasketches.tgt_hll_type.HLL_6",false]],"hll_8 (tgt_hll_type attribute)":[[1,"datasketches.tgt_hll_type.HLL_8",false]],"hll_sketch (class in _datasketches)":[[1,"datasketches.hll_sketch",false]],"hll_union (class in _datasketches)":[[1,"datasketches.hll_union",false]],"is_compact (hll_sketch attribute)":[[1,"datasketches.hll_sketch.is_compact",false]],"is_empty (count_min_sketch attribute)":[[5,"datasketches.count_min_sketch.is_empty",false]],"is_empty (cpc_sketch attribute)":[[0,"datasketches.cpc_sketch.is_empty",false]],"is_empty (density_sketch attribute)":[[23,"datasketches.density_sketch.is_empty",false]],"is_empty (ebpps_sketch attribute)":[[20,"datasketches.ebpps_sketch.is_empty",false]],"is_empty (frequent_items_sketch attribute)":[[6,"datasketches.frequent_items_sketch.is_empty",false]],"is_empty (frequent_strings_sketch attribute)":[[6,"datasketches.frequent_strings_sketch.is_empty",false]],"is_empty (hll_sketch attribute)":[[1,"datasketches.hll_sketch.is_empty",false]],"is_empty (hll_union attribute)":[[1,"datasketches.hll_union.is_empty",false]],"is_empty (kll_doubles_sketch attribute)":[[16,"datasketches.kll_doubles_sketch.is_empty",false]],"is_empty (kll_floats_sketch attribute)":[[16,"datasketches.kll_floats_sketch.is_empty",false]],"is_empty (kll_ints_sketch attribute)":[[16,"datasketches.kll_ints_sketch.is_empty",false]],"is_empty (kll_items_sketch attribute)":[[16,"datasketches.kll_items_sketch.is_empty",false]],"is_empty (quantiles_doubles_sketch attribute)":[[17,"datasketches.quantiles_doubles_sketch.is_empty",false]],"is_empty (quantiles_floats_sketch attribute)":[[17,"datasketches.quantiles_floats_sketch.is_empty",false]],"is_empty (quantiles_ints_sketch attribute)":[[17,"datasketches.quantiles_ints_sketch.is_empty",false]],"is_empty (quantiles_items_sketch attribute)":[[17,"datasketches.quantiles_items_sketch.is_empty",false]],"is_empty (req_floats_sketch attribute)":[[18,"datasketches.req_floats_sketch.is_empty",false]],"is_empty (req_ints_sketch attribute)":[[18,"datasketches.req_ints_sketch.is_empty",false]],"is_empty (req_items_sketch attribute)":[[18,"datasketches.req_items_sketch.is_empty",false]],"is_empty (tdigest_double attribute)":[[19,"datasketches.tdigest_double.is_empty",false]],"is_empty (tdigest_float attribute)":[[19,"datasketches.tdigest_float.is_empty",false]],"is_empty (theta_sketch attribute)":[[3,"datasketches.theta_sketch.is_empty",false]],"is_empty (tuple_sketch attribute)":[[4,"datasketches.tuple_sketch.is_empty",false]],"is_empty (var_opt_sketch attribute)":[[22,"datasketches.var_opt_sketch.is_empty",false]],"is_estimation_mode (density_sketch attribute)":[[23,"datasketches.density_sketch.is_estimation_mode",false]],"is_estimation_mode (kll_doubles_sketch attribute)":[[16,"datasketches.kll_doubles_sketch.is_estimation_mode",false]],"is_estimation_mode (kll_floats_sketch attribute)":[[16,"datasketches.kll_floats_sketch.is_estimation_mode",false]],"is_estimation_mode (kll_ints_sketch attribute)":[[16,"datasketches.kll_ints_sketch.is_estimation_mode",false]],"is_estimation_mode (kll_items_sketch attribute)":[[16,"datasketches.kll_items_sketch.is_estimation_mode",false]],"is_estimation_mode (quantiles_doubles_sketch attribute)":[[17,"datasketches.quantiles_doubles_sketch.is_estimation_mode",false]],"is_estimation_mode (quantiles_floats_sketch attribute)":[[17,"datasketches.quantiles_floats_sketch.is_estimation_mode",false]],"is_estimation_mode (quantiles_ints_sketch attribute)":[[17,"datasketches.quantiles_ints_sketch.is_estimation_mode",false]],"is_estimation_mode (quantiles_items_sketch attribute)":[[17,"datasketches.quantiles_items_sketch.is_estimation_mode",false]],"is_estimation_mode (req_floats_sketch attribute)":[[18,"datasketches.req_floats_sketch.is_estimation_mode",false]],"is_estimation_mode (req_ints_sketch attribute)":[[18,"datasketches.req_ints_sketch.is_estimation_mode",false]],"is_estimation_mode (req_items_sketch attribute)":[[18,"datasketches.req_items_sketch.is_estimation_mode",false]],"is_estimation_mode (theta_sketch attribute)":[[3,"datasketches.theta_sketch.is_estimation_mode",false]],"is_estimation_mode (tuple_sketch attribute)":[[4,"datasketches.tuple_sketch.is_estimation_mode",false]],"is_hra (req_floats_sketch attribute)":[[18,"datasketches.req_floats_sketch.is_hra",false]],"is_hra (req_ints_sketch attribute)":[[18,"datasketches.req_ints_sketch.is_hra",false]],"is_hra (req_items_sketch attribute)":[[18,"datasketches.req_items_sketch.is_hra",false]],"is_ordered (theta_sketch attribute)":[[3,"datasketches.theta_sketch.is_ordered",false]],"is_ordered (tuple_sketch attribute)":[[4,"datasketches.tuple_sketch.is_ordered",false]],"jaccard() (theta_jaccard_similarity method)":[[9,"datasketches.theta_jaccard_similarity.jaccard",false]],"jaccard() (tuple_jaccard_similarity method)":[[9,"datasketches.tuple_jaccard_similarity.jaccard",false]],"k (density_sketch property)":[[23,"datasketches.density_sketch.k",false]],"k (ebpps_sketch property)":[[20,"datasketches.ebpps_sketch.k",false]],"k (kll_doubles_sketch property)":[[16,"datasketches.kll_doubles_sketch.k",false]],"k (kll_floats_sketch property)":[[16,"datasketches.kll_floats_sketch.k",false]],"k (kll_ints_sketch property)":[[16,"datasketches.kll_ints_sketch.k",false]],"k (kll_items_sketch property)":[[16,"datasketches.kll_items_sketch.k",false]],"k (quantiles_doubles_sketch property)":[[17,"datasketches.quantiles_doubles_sketch.k",false]],"k (quantiles_floats_sketch property)":[[17,"datasketches.quantiles_floats_sketch.k",false]],"k (quantiles_ints_sketch property)":[[17,"datasketches.quantiles_ints_sketch.k",false]],"k (quantiles_items_sketch property)":[[17,"datasketches.quantiles_items_sketch.k",false]],"k (req_floats_sketch property)":[[18,"datasketches.req_floats_sketch.k",false]],"k (req_ints_sketch property)":[[18,"datasketches.req_ints_sketch.k",false]],"k (req_items_sketch property)":[[18,"datasketches.req_items_sketch.k",false]],"k (tdigest_double property)":[[19,"datasketches.tdigest_double.k",false]],"k (tdigest_float property)":[[19,"datasketches.tdigest_float.k",false]],"k (var_opt_sketch property)":[[22,"datasketches.var_opt_sketch.k",false]],"kernelfunction (class in datasketches)":[[10,"datasketches.KernelFunction",false]],"kll_doubles_sketch (class in datasketches)":[[16,"datasketches.kll_doubles_sketch",false]],"kll_floats_sketch (class in datasketches)":[[16,"datasketches.kll_floats_sketch",false]],"kll_ints_sketch (class in datasketches)":[[16,"datasketches.kll_ints_sketch",false]],"kll_items_sketch (class in datasketches)":[[16,"datasketches.kll_items_sketch",false]],"ks_test() (in module datasketches)":[[11,"datasketches.ks_test",false]],"lg_config_k (hll_sketch property)":[[1,"datasketches.hll_sketch.lg_config_k",false]],"lg_config_k (hll_union property)":[[1,"datasketches.hll_union.lg_config_k",false]],"lg_k (cpc_sketch property)":[[0,"datasketches.cpc_sketch.lg_k",false]],"maxintpolicy (class in datasketches)":[[13,"datasketches.MaxIntPolicy",false]],"merge (count_min_sketch attribute)":[[5,"datasketches.count_min_sketch.merge",false]],"merge (density_sketch attribute)":[[23,"datasketches.density_sketch.merge",false]],"merge (ebpps_sketch attribute)":[[20,"datasketches.ebpps_sketch.merge",false]],"merge (frequent_items_sketch attribute)":[[6,"datasketches.frequent_items_sketch.merge",false]],"merge (frequent_strings_sketch attribute)":[[6,"datasketches.frequent_strings_sketch.merge",false]],"merge (kll_doubles_sketch attribute)":[[16,"datasketches.kll_doubles_sketch.merge",false]],"merge (kll_floats_sketch attribute)":[[16,"datasketches.kll_floats_sketch.merge",false]],"merge (kll_ints_sketch attribute)":[[16,"datasketches.kll_ints_sketch.merge",false]],"merge (kll_items_sketch attribute)":[[16,"datasketches.kll_items_sketch.merge",false]],"merge (quantiles_doubles_sketch attribute)":[[17,"datasketches.quantiles_doubles_sketch.merge",false]],"merge (quantiles_floats_sketch attribute)":[[17,"datasketches.quantiles_floats_sketch.merge",false]],"merge (quantiles_ints_sketch attribute)":[[17,"datasketches.quantiles_ints_sketch.merge",false]],"merge (quantiles_items_sketch attribute)":[[17,"datasketches.quantiles_items_sketch.merge",false]],"merge (req_floats_sketch attribute)":[[18,"datasketches.req_floats_sketch.merge",false]],"merge (req_ints_sketch attribute)":[[18,"datasketches.req_ints_sketch.merge",false]],"merge (req_items_sketch attribute)":[[18,"datasketches.req_items_sketch.merge",false]],"merge (tdigest_double attribute)":[[19,"datasketches.tdigest_double.merge",false]],"merge (tdigest_float attribute)":[[19,"datasketches.tdigest_float.merge",false]],"minintpolicy (class in datasketches)":[[13,"datasketches.MinIntPolicy",false]],"n (density_sketch property)":[[23,"datasketches.density_sketch.n",false]],"n (ebpps_sketch property)":[[20,"datasketches.ebpps_sketch.n",false]],"n (kll_doubles_sketch property)":[[16,"datasketches.kll_doubles_sketch.n",false]],"n (kll_floats_sketch property)":[[16,"datasketches.kll_floats_sketch.n",false]],"n (kll_ints_sketch property)":[[16,"datasketches.kll_ints_sketch.n",false]],"n (kll_items_sketch property)":[[16,"datasketches.kll_items_sketch.n",false]],"n (quantiles_doubles_sketch property)":[[17,"datasketches.quantiles_doubles_sketch.n",false]],"n (quantiles_floats_sketch property)":[[17,"datasketches.quantiles_floats_sketch.n",false]],"n (quantiles_ints_sketch property)":[[17,"datasketches.quantiles_ints_sketch.n",false]],"n (quantiles_items_sketch property)":[[17,"datasketches.quantiles_items_sketch.n",false]],"n (req_floats_sketch property)":[[18,"datasketches.req_floats_sketch.n",false]],"n (req_ints_sketch property)":[[18,"datasketches.req_ints_sketch.n",false]],"n (req_items_sketch property)":[[18,"datasketches.req_items_sketch.n",false]],"n (var_opt_sketch property)":[[22,"datasketches.var_opt_sketch.n",false]],"no_false_negatives (frequent_items_error_type attribute)":[[6,"datasketches.frequent_items_error_type.NO_FALSE_NEGATIVES",false]],"no_false_positives (frequent_items_error_type attribute)":[[6,"datasketches.frequent_items_error_type.NO_FALSE_POSITIVES",false]],"normalized_rank_error (kll_doubles_sketch attribute)":[[16,"datasketches.kll_doubles_sketch.normalized_rank_error",false]],"normalized_rank_error (kll_floats_sketch attribute)":[[16,"datasketches.kll_floats_sketch.normalized_rank_error",false]],"normalized_rank_error (kll_ints_sketch attribute)":[[16,"datasketches.kll_ints_sketch.normalized_rank_error",false]],"normalized_rank_error (kll_items_sketch attribute)":[[16,"datasketches.kll_items_sketch.normalized_rank_error",false]],"normalized_rank_error (quantiles_doubles_sketch attribute)":[[17,"datasketches.quantiles_doubles_sketch.normalized_rank_error",false]],"normalized_rank_error (quantiles_floats_sketch attribute)":[[17,"datasketches.quantiles_floats_sketch.normalized_rank_error",false]],"normalized_rank_error (quantiles_ints_sketch attribute)":[[17,"datasketches.quantiles_ints_sketch.normalized_rank_error",false]],"normalized_rank_error (quantiles_items_sketch attribute)":[[17,"datasketches.quantiles_items_sketch.normalized_rank_error",false]],"num_active_items (frequent_items_sketch property)":[[6,"datasketches.frequent_items_sketch.num_active_items",false]],"num_active_items (frequent_strings_sketch property)":[[6,"datasketches.frequent_strings_sketch.num_active_items",false]],"num_buckets (count_min_sketch property)":[[5,"datasketches.count_min_sketch.num_buckets",false]],"num_hashes (count_min_sketch property)":[[5,"datasketches.count_min_sketch.num_hashes",false]],"num_retained (density_sketch property)":[[23,"datasketches.density_sketch.num_retained",false]],"num_retained (kll_doubles_sketch property)":[[16,"datasketches.kll_doubles_sketch.num_retained",false]],"num_retained (kll_floats_sketch property)":[[16,"datasketches.kll_floats_sketch.num_retained",false]],"num_retained (kll_ints_sketch property)":[[16,"datasketches.kll_ints_sketch.num_retained",false]],"num_retained (kll_items_sketch property)":[[16,"datasketches.kll_items_sketch.num_retained",false]],"num_retained (quantiles_doubles_sketch property)":[[17,"datasketches.quantiles_doubles_sketch.num_retained",false]],"num_retained (quantiles_floats_sketch property)":[[17,"datasketches.quantiles_floats_sketch.num_retained",false]],"num_retained (quantiles_ints_sketch property)":[[17,"datasketches.quantiles_ints_sketch.num_retained",false]],"num_retained (quantiles_items_sketch property)":[[17,"datasketches.quantiles_items_sketch.num_retained",false]],"num_retained (req_floats_sketch property)":[[18,"datasketches.req_floats_sketch.num_retained",false]],"num_retained (req_ints_sketch property)":[[18,"datasketches.req_ints_sketch.num_retained",false]],"num_retained (req_items_sketch property)":[[18,"datasketches.req_items_sketch.num_retained",false]],"num_retained (theta_sketch property)":[[3,"datasketches.theta_sketch.num_retained",false]],"num_retained (tuple_sketch property)":[[4,"datasketches.tuple_sketch.num_retained",false]],"num_samples (var_opt_sketch property)":[[22,"datasketches.var_opt_sketch.num_samples",false]],"pydoublesserde (class in datasketches)":[[12,"datasketches.PyDoublesSerDe",false]],"pyfloatsserde (class in datasketches)":[[12,"datasketches.PyFloatsSerDe",false]],"pyintsserde (class in datasketches)":[[12,"datasketches.PyIntsSerDe",false]],"pylongsserde (class in datasketches)":[[12,"datasketches.PyLongsSerDe",false]],"pyobjectserde (class in datasketches)":[[12,"datasketches.PyObjectSerDe",false]],"pystringsserde (class in datasketches)":[[12,"datasketches.PyStringsSerDe",false]],"quantiles_doubles_sketch (class in datasketches)":[[17,"datasketches.quantiles_doubles_sketch",false]],"quantiles_floats_sketch (class in datasketches)":[[17,"datasketches.quantiles_floats_sketch",false]],"quantiles_ints_sketch (class in datasketches)":[[17,"datasketches.quantiles_ints_sketch",false]],"quantiles_items_sketch (class in datasketches)":[[17,"datasketches.quantiles_items_sketch",false]],"req_floats_sketch (class in datasketches)":[[18,"datasketches.req_floats_sketch",false]],"req_ints_sketch (class in datasketches)":[[18,"datasketches.req_ints_sketch",false]],"req_items_sketch (class in datasketches)":[[18,"datasketches.req_items_sketch",false]],"reset (hll_sketch attribute)":[[1,"datasketches.hll_sketch.reset",false]],"reset (hll_union attribute)":[[1,"datasketches.hll_union.reset",false]],"reset (tuple_union attribute)":[[4,"datasketches.tuple_union.reset",false]],"reset (update_theta_sketch attribute)":[[3,"datasketches.update_theta_sketch.reset",false]],"reset (update_tuple_sketch attribute)":[[4,"datasketches.update_tuple_sketch.reset",false]],"reset (var_opt_union attribute)":[[22,"datasketches.var_opt_union.reset",false]],"seed (count_min_sketch property)":[[5,"datasketches.count_min_sketch.seed",false]],"serialize (compact_theta_sketch attribute)":[[3,"datasketches.compact_theta_sketch.serialize",false]],"serialize (compact_tuple_sketch attribute)":[[4,"datasketches.compact_tuple_sketch.serialize",false]],"serialize (count_min_sketch attribute)":[[5,"datasketches.count_min_sketch.serialize",false]],"serialize (cpc_sketch attribute)":[[0,"datasketches.cpc_sketch.serialize",false]],"serialize (density_sketch attribute)":[[23,"datasketches.density_sketch.serialize",false]],"serialize (ebpps_sketch attribute)":[[20,"datasketches.ebpps_sketch.serialize",false]],"serialize (frequent_items_sketch attribute)":[[6,"datasketches.frequent_items_sketch.serialize",false]],"serialize (frequent_strings_sketch attribute)":[[6,"datasketches.frequent_strings_sketch.serialize",false]],"serialize (kll_doubles_sketch attribute)":[[16,"datasketches.kll_doubles_sketch.serialize",false]],"serialize (kll_floats_sketch attribute)":[[16,"datasketches.kll_floats_sketch.serialize",false]],"serialize (kll_ints_sketch attribute)":[[16,"datasketches.kll_ints_sketch.serialize",false]],"serialize (kll_items_sketch attribute)":[[16,"datasketches.kll_items_sketch.serialize",false]],"serialize (quantiles_doubles_sketch attribute)":[[17,"datasketches.quantiles_doubles_sketch.serialize",false]],"serialize (quantiles_floats_sketch attribute)":[[17,"datasketches.quantiles_floats_sketch.serialize",false]],"serialize (quantiles_ints_sketch attribute)":[[17,"datasketches.quantiles_ints_sketch.serialize",false]],"serialize (quantiles_items_sketch attribute)":[[17,"datasketches.quantiles_items_sketch.serialize",false]],"serialize (req_floats_sketch attribute)":[[18,"datasketches.req_floats_sketch.serialize",false]],"serialize (req_ints_sketch attribute)":[[18,"datasketches.req_ints_sketch.serialize",false]],"serialize (req_items_sketch attribute)":[[18,"datasketches.req_items_sketch.serialize",false]],"serialize (tdigest_double attribute)":[[19,"datasketches.tdigest_double.serialize",false]],"serialize (tdigest_float attribute)":[[19,"datasketches.tdigest_float.serialize",false]],"serialize (var_opt_sketch attribute)":[[22,"datasketches.var_opt_sketch.serialize",false]],"serialize (var_opt_union attribute)":[[22,"datasketches.var_opt_union.serialize",false]],"serialize_compact (hll_sketch attribute)":[[1,"datasketches.hll_sketch.serialize_compact",false]],"serialize_updatable (hll_sketch attribute)":[[1,"datasketches.hll_sketch.serialize_updatable",false]],"similarity_test() (theta_jaccard_similarity method)":[[9,"datasketches.theta_jaccard_similarity.similarity_test",false]],"similarity_test() (tuple_jaccard_similarity method)":[[9,"datasketches.tuple_jaccard_similarity.similarity_test",false]],"suggest_num_buckets() (count_min_sketch method)":[[5,"datasketches.count_min_sketch.suggest_num_buckets",false]],"suggest_num_hashes() (count_min_sketch method)":[[5,"datasketches.count_min_sketch.suggest_num_hashes",false]],"tdigest_double (class in datasketches)":[[19,"datasketches.tdigest_double",false]],"tdigest_float (class in datasketches)":[[19,"datasketches.tdigest_float",false]],"tgt_hll_type (class in _datasketches)":[[1,"datasketches.tgt_hll_type",false]],"tgt_type (hll_sketch property)":[[1,"datasketches.hll_sketch.tgt_type",false]],"theta (theta_sketch property)":[[3,"datasketches.theta_sketch.theta",false]],"theta (tuple_sketch property)":[[4,"datasketches.tuple_sketch.theta",false]],"theta64 (theta_sketch property)":[[3,"datasketches.theta_sketch.theta64",false]],"theta64 (tuple_sketch property)":[[4,"datasketches.tuple_sketch.theta64",false]],"theta_a_not_b (class in datasketches)":[[3,"datasketches.theta_a_not_b",false]],"theta_intersection (class in datasketches)":[[3,"datasketches.theta_intersection",false]],"theta_jaccard_similarity (class in datasketches)":[[9,"datasketches.theta_jaccard_similarity",false]],"theta_sketch (class in datasketches)":[[3,"datasketches.theta_sketch",false]],"theta_union (class in datasketches)":[[3,"datasketches.theta_union",false]],"to_bytes() (pyobjectserde method)":[[12,"datasketches.PyObjectSerDe.to_bytes",false]],"to_string (count_min_sketch attribute)":[[5,"datasketches.count_min_sketch.to_string",false]],"to_string (cpc_sketch attribute)":[[0,"datasketches.cpc_sketch.to_string",false]],"to_string (density_sketch attribute)":[[23,"datasketches.density_sketch.to_string",false]],"to_string (ebpps_sketch attribute)":[[20,"datasketches.ebpps_sketch.to_string",false]],"to_string (frequent_items_sketch attribute)":[[6,"datasketches.frequent_items_sketch.to_string",false]],"to_string (frequent_strings_sketch attribute)":[[6,"datasketches.frequent_strings_sketch.to_string",false]],"to_string (hll_sketch attribute)":[[1,"datasketches.hll_sketch.to_string",false]],"to_string (kll_doubles_sketch attribute)":[[16,"datasketches.kll_doubles_sketch.to_string",false]],"to_string (kll_floats_sketch attribute)":[[16,"datasketches.kll_floats_sketch.to_string",false]],"to_string (kll_ints_sketch attribute)":[[16,"datasketches.kll_ints_sketch.to_string",false]],"to_string (kll_items_sketch attribute)":[[16,"datasketches.kll_items_sketch.to_string",false]],"to_string (quantiles_doubles_sketch attribute)":[[17,"datasketches.quantiles_doubles_sketch.to_string",false]],"to_string (quantiles_floats_sketch attribute)":[[17,"datasketches.quantiles_floats_sketch.to_string",false]],"to_string (quantiles_ints_sketch attribute)":[[17,"datasketches.quantiles_ints_sketch.to_string",false]],"to_string (quantiles_items_sketch attribute)":[[17,"datasketches.quantiles_items_sketch.to_string",false]],"to_string (req_floats_sketch attribute)":[[18,"datasketches.req_floats_sketch.to_string",false]],"to_string (req_ints_sketch attribute)":[[18,"datasketches.req_ints_sketch.to_string",false]],"to_string (req_items_sketch attribute)":[[18,"datasketches.req_items_sketch.to_string",false]],"to_string (tdigest_double attribute)":[[19,"datasketches.tdigest_double.to_string",false]],"to_string (tdigest_float attribute)":[[19,"datasketches.tdigest_float.to_string",false]],"to_string (theta_sketch attribute)":[[3,"datasketches.theta_sketch.to_string",false]],"to_string (tuple_sketch attribute)":[[4,"datasketches.tuple_sketch.to_string",false]],"to_string (var_opt_sketch attribute)":[[22,"datasketches.var_opt_sketch.to_string",false]],"to_string (var_opt_union attribute)":[[22,"datasketches.var_opt_union.to_string",false]],"total_weight (count_min_sketch property)":[[5,"datasketches.count_min_sketch.total_weight",false]],"total_weight (frequent_items_sketch property)":[[6,"datasketches.frequent_items_sketch.total_weight",false]],"total_weight (frequent_strings_sketch property)":[[6,"datasketches.frequent_strings_sketch.total_weight",false]],"trim (update_theta_sketch attribute)":[[3,"datasketches.update_theta_sketch.trim",false]],"trim (update_tuple_sketch attribute)":[[4,"datasketches.update_tuple_sketch.trim",false]],"tuple_a_not_b (class in datasketches)":[[4,"datasketches.tuple_a_not_b",false]],"tuple_intersection (class in datasketches)":[[4,"datasketches.tuple_intersection",false]],"tuple_jaccard_similarity (class in datasketches)":[[9,"datasketches.tuple_jaccard_similarity",false]],"tuple_sketch (class in datasketches)":[[4,"datasketches.tuple_sketch",false]],"tuple_union (class in datasketches)":[[4,"datasketches.tuple_union",false]],"tuplepolicy (class in datasketches)":[[13,"datasketches.TuplePolicy",false]],"update (count_min_sketch attribute)":[[5,"datasketches.count_min_sketch.update",false]],"update (cpc_sketch attribute)":[[0,"datasketches.cpc_sketch.update",false]],"update (cpc_union attribute)":[[0,"datasketches.cpc_union.update",false]],"update (density_sketch attribute)":[[23,"datasketches.density_sketch.update",false]],"update (ebpps_sketch attribute)":[[20,"datasketches.ebpps_sketch.update",false]],"update (frequent_items_sketch attribute)":[[6,"datasketches.frequent_items_sketch.update",false]],"update (frequent_strings_sketch attribute)":[[6,"datasketches.frequent_strings_sketch.update",false]],"update (hll_sketch attribute)":[[1,"datasketches.hll_sketch.update",false]],"update (hll_union attribute)":[[1,"datasketches.hll_union.update",false]],"update (kll_doubles_sketch attribute)":[[16,"datasketches.kll_doubles_sketch.update",false]],"update (kll_floats_sketch attribute)":[[16,"datasketches.kll_floats_sketch.update",false]],"update (kll_ints_sketch attribute)":[[16,"datasketches.kll_ints_sketch.update",false]],"update (kll_items_sketch attribute)":[[16,"datasketches.kll_items_sketch.update",false]],"update (quantiles_doubles_sketch attribute)":[[17,"datasketches.quantiles_doubles_sketch.update",false]],"update (quantiles_floats_sketch attribute)":[[17,"datasketches.quantiles_floats_sketch.update",false]],"update (quantiles_ints_sketch attribute)":[[17,"datasketches.quantiles_ints_sketch.update",false]],"update (quantiles_items_sketch attribute)":[[17,"datasketches.quantiles_items_sketch.update",false]],"update (req_floats_sketch attribute)":[[18,"datasketches.req_floats_sketch.update",false]],"update (req_ints_sketch attribute)":[[18,"datasketches.req_ints_sketch.update",false]],"update (req_items_sketch attribute)":[[18,"datasketches.req_items_sketch.update",false]],"update (tdigest_double attribute)":[[19,"datasketches.tdigest_double.update",false]],"update (tdigest_float attribute)":[[19,"datasketches.tdigest_float.update",false]],"update (theta_intersection attribute)":[[3,"datasketches.theta_intersection.update",false]],"update (theta_union attribute)":[[3,"datasketches.theta_union.update",false]],"update (tuple_intersection attribute)":[[4,"datasketches.tuple_intersection.update",false]],"update (tuple_union attribute)":[[4,"datasketches.tuple_union.update",false]],"update (update_theta_sketch attribute)":[[3,"datasketches.update_theta_sketch.update",false]],"update (update_tuple_sketch attribute)":[[4,"datasketches.update_tuple_sketch.update",false]],"update (var_opt_sketch attribute)":[[22,"datasketches.var_opt_sketch.update",false]],"update (var_opt_union attribute)":[[22,"datasketches.var_opt_union.update",false]],"update_summary() (tuplepolicy method)":[[13,"datasketches.TuplePolicy.update_summary",false]],"update_theta_sketch (class in datasketches)":[[3,"datasketches.update_theta_sketch",false]],"update_tuple_sketch (class in datasketches)":[[4,"datasketches.update_tuple_sketch",false]],"var_opt_sketch (class in datasketches)":[[22,"datasketches.var_opt_sketch",false]],"var_opt_union (class in datasketches)":[[22,"datasketches.var_opt_union",false]]},"objects":{"_datasketches":[[5,0,1,"datasketches.count_min_sketch","count_min_sketch"],[0,0,1,"datasketches.cpc_sketch","cpc_sketch"],[0,0,1,"datasketches.cpc_union","cpc_union"],[1,0,1,"datasketches.hll_sketch","hll_sketch"],[1,0,1,"datasketches.hll_union","hll_union"],[1,0,1,"datasketches.tgt_hll_type","tgt_hll_type"]],"_datasketches.count_min_sketch":[[5,1,1,"datasketches.count_min_sketch.deserialize","deserialize"],[5,2,1,"datasketches.count_min_sketch.get_estimate","get_estimate"],[5,2,1,"datasketches.count_min_sketch.get_lower_bound","get_lower_bound"],[5,2,1,"datasketches.count_min_sketch.get_relative_error","get_relative_error"],[5,2,1,"datasketches.count_min_sketch.get_serialized_size_bytes","get_serialized_size_bytes"],[5,2,1,"datasketches.count_min_sketch.get_upper_bound","get_upper_bound"],[5,2,1,"datasketches.count_min_sketch.is_empty","is_empty"],[5,2,1,"datasketches.count_min_sketch.merge","merge"],[5,3,1,"datasketches.count_min_sketch.num_buckets","num_buckets"],[5,3,1,"datasketches.count_min_sketch.num_hashes","num_hashes"],[5,3,1,"datasketches.count_min_sketch.seed","seed"],[5,2,1,"datasketches.count_min_sketch.serialize","serialize"],[5,1,1,"datasketches.count_min_sketch.suggest_num_buckets","suggest_num_buckets"],[5,1,1,"datasketches.count_min_sketch.suggest_num_hashes","suggest_num_hashes"],[5,2,1,"datasketches.count_min_sketch.to_string","to_string"],[5,3,1,"datasketches.count_min_sketch.total_weight","total_weight"],[5,2,1,"datasketches.count_min_sketch.update","update"]],"_datasketches.cpc_sketch":[[0,1,1,"datasketches.cpc_sketch.__init__","__init__"],[0,1,1,"datasketches.cpc_sketch.deserialize","deserialize"],[0,2,1,"datasketches.cpc_sketch.get_estimate","get_estimate"],[0,2,1,"datasketches.cpc_sketch.get_lower_bound","get_lower_bound"],[0,2,1,"datasketches.cpc_sketch.get_upper_bound","get_upper_bound"],[0,2,1,"datasketches.cpc_sketch.is_empty","is_empty"],[0,3,1,"datasketches.cpc_sketch.lg_k","lg_k"],[0,2,1,"datasketches.cpc_sketch.serialize","serialize"],[0,2,1,"datasketches.cpc_sketch.to_string","to_string"],[0,2,1,"datasketches.cpc_sketch.update","update"]],"_datasketches.cpc_union":[[0,1,1,"datasketches.cpc_union.__init__","__init__"],[0,2,1,"datasketches.cpc_union.get_result","get_result"],[0,2,1,"datasketches.cpc_union.update","update"]],"_datasketches.hll_sketch":[[1,1,1,"datasketches.hll_sketch.__init__","__init__"],[1,1,1,"datasketches.hll_sketch.deserialize","deserialize"],[1,2,1,"datasketches.hll_sketch.get_compact_serialization_bytes","get_compact_serialization_bytes"],[1,2,1,"datasketches.hll_sketch.get_estimate","get_estimate"],[1,2,1,"datasketches.hll_sketch.get_lower_bound","get_lower_bound"],[1,1,1,"datasketches.hll_sketch.get_max_updatable_serialization_bytes","get_max_updatable_serialization_bytes"],[1,1,1,"datasketches.hll_sketch.get_rel_err","get_rel_err"],[1,2,1,"datasketches.hll_sketch.get_updatable_serialization_bytes","get_updatable_serialization_bytes"],[1,2,1,"datasketches.hll_sketch.get_upper_bound","get_upper_bound"],[1,2,1,"datasketches.hll_sketch.is_compact","is_compact"],[1,2,1,"datasketches.hll_sketch.is_empty","is_empty"],[1,3,1,"datasketches.hll_sketch.lg_config_k","lg_config_k"],[1,2,1,"datasketches.hll_sketch.reset","reset"],[1,2,1,"datasketches.hll_sketch.serialize_compact","serialize_compact"],[1,2,1,"datasketches.hll_sketch.serialize_updatable","serialize_updatable"],[1,3,1,"datasketches.hll_sketch.tgt_type","tgt_type"],[1,2,1,"datasketches.hll_sketch.to_string","to_string"],[1,2,1,"datasketches.hll_sketch.update","update"]],"_datasketches.hll_union":[[1,1,1,"datasketches.hll_union.__init__","__init__"],[1,2,1,"datasketches.hll_union.get_estimate","get_estimate"],[1,2,1,"datasketches.hll_union.get_lower_bound","get_lower_bound"],[1,1,1,"datasketches.hll_union.get_rel_err","get_rel_err"],[1,2,1,"datasketches.hll_union.get_result","get_result"],[1,2,1,"datasketches.hll_union.get_upper_bound","get_upper_bound"],[1,2,1,"datasketches.hll_union.is_empty","is_empty"],[1,3,1,"datasketches.hll_union.lg_config_k","lg_config_k"],[1,2,1,"datasketches.hll_union.reset","reset"],[1,2,1,"datasketches.hll_union.update","update"]],"_datasketches.tgt_hll_type":[[1,2,1,"datasketches.tgt_hll_type.HLL_4","HLL_4"],[1,2,1,"datasketches.tgt_hll_type.HLL_6","HLL_6"],[1,2,1,"datasketches.tgt_hll_type.HLL_8","HLL_8"]],"datasketches":[[13,0,1,"","AccumulatorPolicy"],[10,0,1,"","GaussianKernel"],[10,0,1,"","KernelFunction"],[13,0,1,"","MaxIntPolicy"],[13,0,1,"","MinIntPolicy"],[12,0,1,"","PyDoublesSerDe"],[12,0,1,"","PyFloatsSerDe"],[12,0,1,"","PyIntsSerDe"],[12,0,1,"","PyLongsSerDe"],[12,0,1,"","PyObjectSerDe"],[12,0,1,"","PyStringsSerDe"],[13,0,1,"","TuplePolicy"],[3,0,1,"","compact_theta_sketch"],[4,0,1,"","compact_tuple_sketch"],[23,0,1,"","density_sketch"],[20,0,1,"","ebpps_sketch"],[6,0,1,"","frequent_items_error_type"],[6,0,1,"","frequent_items_sketch"],[6,0,1,"","frequent_strings_sketch"],[16,0,1,"","kll_doubles_sketch"],[16,0,1,"","kll_floats_sketch"],[16,0,1,"","kll_ints_sketch"],[16,0,1,"","kll_items_sketch"],[11,4,1,"","ks_test"],[17,0,1,"","quantiles_doubles_sketch"],[17,0,1,"","quantiles_floats_sketch"],[17,0,1,"","quantiles_ints_sketch"],[17,0,1,"","quantiles_items_sketch"],[18,0,1,"","req_floats_sketch"],[18,0,1,"","req_ints_sketch"],[18,0,1,"","req_items_sketch"],[19,0,1,"","tdigest_double"],[19,0,1,"","tdigest_float"],[3,0,1,"","theta_a_not_b"],[3,0,1,"","theta_intersection"],[9,0,1,"","theta_jaccard_similarity"],[3,0,1,"","theta_sketch"],[3,0,1,"","theta_union"],[4,0,1,"","tuple_a_not_b"],[4,0,1,"","tuple_intersection"],[9,0,1,"","tuple_jaccard_similarity"],[4,0,1,"","tuple_sketch"],[4,0,1,"","tuple_union"],[3,0,1,"","update_theta_sketch"],[4,0,1,"","update_tuple_sketch"],[22,0,1,"","var_opt_sketch"],[22,0,1,"","var_opt_union"]],"datasketches.KernelFunction":[[10,1,1,"","__call__"]],"datasketches.PyObjectSerDe":[[12,1,1,"","from_bytes"],[12,1,1,"","get_size"],[12,1,1,"","to_bytes"]],"datasketches.TuplePolicy":[[13,1,1,"","__call__"],[13,1,1,"","create_summary"],[13,1,1,"","update_summary"]],"datasketches.compact_theta_sketch":[[3,1,1,"","__init__"],[3,1,1,"","deserialize"],[3,2,1,"","serialize"]],"datasketches.compact_tuple_sketch":[[4,1,1,"","__init__"],[4,1,1,"","deserialize"],[4,2,1,"","filter"],[4,2,1,"","serialize"]],"datasketches.density_sketch":[[23,1,1,"","__init__"],[23,1,1,"","deserialize"],[23,3,1,"","dim"],[23,2,1,"","get_estimate"],[23,2,1,"","is_empty"],[23,2,1,"","is_estimation_mode"],[23,3,1,"","k"],[23,2,1,"","merge"],[23,3,1,"","n"],[23,3,1,"","num_retained"],[23,2,1,"","serialize"],[23,2,1,"","to_string"],[23,2,1,"","update"]],"datasketches.ebpps_sketch":[[20,1,1,"","__init__"],[20,3,1,"","c"],[20,1,1,"","deserialize"],[20,2,1,"","get_serialized_size_bytes"],[20,2,1,"","is_empty"],[20,3,1,"","k"],[20,2,1,"","merge"],[20,3,1,"","n"],[20,2,1,"","serialize"],[20,2,1,"","to_string"],[20,2,1,"","update"]],"datasketches.frequent_items_error_type":[[6,2,1,"","NO_FALSE_NEGATIVES"],[6,2,1,"","NO_FALSE_POSITIVES"]],"datasketches.frequent_items_sketch":[[6,1,1,"","__init__"],[6,1,1,"","deserialize"],[6,3,1,"","epsilon"],[6,1,1,"","get_apriori_error"],[6,1,1,"","get_epsilon_for_lg_size"],[6,2,1,"","get_estimate"],[6,2,1,"","get_frequent_items"],[6,2,1,"","get_lower_bound"],[6,2,1,"","get_serialized_size_bytes"],[6,2,1,"","get_upper_bound"],[6,2,1,"","is_empty"],[6,2,1,"","merge"],[6,3,1,"","num_active_items"],[6,2,1,"","serialize"],[6,2,1,"","to_string"],[6,3,1,"","total_weight"],[6,2,1,"","update"]],"datasketches.frequent_strings_sketch":[[6,1,1,"","__init__"],[6,1,1,"","deserialize"],[6,3,1,"","epsilon"],[6,1,1,"","get_apriori_error"],[6,1,1,"","get_epsilon_for_lg_size"],[6,2,1,"","get_estimate"],[6,2,1,"","get_frequent_items"],[6,2,1,"","get_lower_bound"],[6,2,1,"","get_serialized_size_bytes"],[6,2,1,"","get_upper_bound"],[6,2,1,"","is_empty"],[6,2,1,"","merge"],[6,3,1,"","num_active_items"],[6,2,1,"","serialize"],[6,2,1,"","to_string"],[6,3,1,"","total_weight"],[6,2,1,"","update"]],"datasketches.kll_doubles_sketch":[[16,1,1,"","__init__"],[16,1,1,"","deserialize"],[16,2,1,"","get_cdf"],[16,2,1,"","get_max_value"],[16,2,1,"","get_min_value"],[16,1,1,"","get_normalized_rank_error"],[16,2,1,"","get_pmf"],[16,2,1,"","get_quantile"],[16,2,1,"","get_quantiles"],[16,2,1,"","get_rank"],[16,2,1,"","is_empty"],[16,2,1,"","is_estimation_mode"],[16,3,1,"","k"],[16,2,1,"","merge"],[16,3,1,"","n"],[16,2,1,"","normalized_rank_error"],[16,3,1,"","num_retained"],[16,2,1,"","serialize"],[16,2,1,"","to_string"],[16,2,1,"","update"]],"datasketches.kll_floats_sketch":[[16,1,1,"","__init__"],[16,1,1,"","deserialize"],[16,2,1,"","get_cdf"],[16,2,1,"","get_max_value"],[16,2,1,"","get_min_value"],[16,1,1,"","get_normalized_rank_error"],[16,2,1,"","get_pmf"],[16,2,1,"","get_quantile"],[16,2,1,"","get_quantiles"],[16,2,1,"","get_rank"],[16,2,1,"","is_empty"],[16,2,1,"","is_estimation_mode"],[16,3,1,"","k"],[16,2,1,"","merge"],[16,3,1,"","n"],[16,2,1,"","normalized_rank_error"],[16,3,1,"","num_retained"],[16,2,1,"","serialize"],[16,2,1,"","to_string"],[16,2,1,"","update"]],"datasketches.kll_ints_sketch":[[16,1,1,"","__init__"],[16,1,1,"","deserialize"],[16,2,1,"","get_cdf"],[16,2,1,"","get_max_value"],[16,2,1,"","get_min_value"],[16,1,1,"","get_normalized_rank_error"],[16,2,1,"","get_pmf"],[16,2,1,"","get_quantile"],[16,2,1,"","get_quantiles"],[16,2,1,"","get_rank"],[16,2,1,"","is_empty"],[16,2,1,"","is_estimation_mode"],[16,3,1,"","k"],[16,2,1,"","merge"],[16,3,1,"","n"],[16,2,1,"","normalized_rank_error"],[16,3,1,"","num_retained"],[16,2,1,"","serialize"],[16,2,1,"","to_string"],[16,2,1,"","update"]],"datasketches.kll_items_sketch":[[16,1,1,"","__init__"],[16,1,1,"","deserialize"],[16,2,1,"","get_cdf"],[16,2,1,"","get_max_value"],[16,2,1,"","get_min_value"],[16,1,1,"","get_normalized_rank_error"],[16,2,1,"","get_pmf"],[16,2,1,"","get_quantile"],[16,2,1,"","get_quantiles"],[16,2,1,"","get_rank"],[16,2,1,"","is_empty"],[16,2,1,"","is_estimation_mode"],[16,3,1,"","k"],[16,2,1,"","merge"],[16,3,1,"","n"],[16,2,1,"","normalized_rank_error"],[16,3,1,"","num_retained"],[16,2,1,"","serialize"],[16,2,1,"","to_string"],[16,2,1,"","update"]],"datasketches.quantiles_doubles_sketch":[[17,1,1,"","__init__"],[17,1,1,"","deserialize"],[17,2,1,"","get_cdf"],[17,2,1,"","get_max_value"],[17,2,1,"","get_min_value"],[17,1,1,"","get_normalized_rank_error"],[17,2,1,"","get_pmf"],[17,2,1,"","get_quantile"],[17,2,1,"","get_quantiles"],[17,2,1,"","get_rank"],[17,2,1,"","is_empty"],[17,2,1,"","is_estimation_mode"],[17,3,1,"","k"],[17,2,1,"","merge"],[17,3,1,"","n"],[17,2,1,"","normalized_rank_error"],[17,3,1,"","num_retained"],[17,2,1,"","serialize"],[17,2,1,"","to_string"],[17,2,1,"","update"]],"datasketches.quantiles_floats_sketch":[[17,1,1,"","__init__"],[17,1,1,"","deserialize"],[17,2,1,"","get_cdf"],[17,2,1,"","get_max_value"],[17,2,1,"","get_min_value"],[17,1,1,"","get_normalized_rank_error"],[17,2,1,"","get_pmf"],[17,2,1,"","get_quantile"],[17,2,1,"","get_quantiles"],[17,2,1,"","get_rank"],[17,2,1,"","is_empty"],[17,2,1,"","is_estimation_mode"],[17,3,1,"","k"],[17,2,1,"","merge"],[17,3,1,"","n"],[17,2,1,"","normalized_rank_error"],[17,3,1,"","num_retained"],[17,2,1,"","serialize"],[17,2,1,"","to_string"],[17,2,1,"","update"]],"datasketches.quantiles_ints_sketch":[[17,1,1,"","__init__"],[17,1,1,"","deserialize"],[17,2,1,"","get_cdf"],[17,2,1,"","get_max_value"],[17,2,1,"","get_min_value"],[17,1,1,"","get_normalized_rank_error"],[17,2,1,"","get_pmf"],[17,2,1,"","get_quantile"],[17,2,1,"","get_quantiles"],[17,2,1,"","get_rank"],[17,2,1,"","is_empty"],[17,2,1,"","is_estimation_mode"],[17,3,1,"","k"],[17,2,1,"","merge"],[17,3,1,"","n"],[17,2,1,"","normalized_rank_error"],[17,3,1,"","num_retained"],[17,2,1,"","serialize"],[17,2,1,"","to_string"],[17,2,1,"","update"]],"datasketches.quantiles_items_sketch":[[17,1,1,"","__init__"],[17,1,1,"","deserialize"],[17,2,1,"","get_cdf"],[17,2,1,"","get_max_value"],[17,2,1,"","get_min_value"],[17,1,1,"","get_normalized_rank_error"],[17,2,1,"","get_pmf"],[17,2,1,"","get_quantile"],[17,2,1,"","get_quantiles"],[17,2,1,"","get_rank"],[17,2,1,"","is_empty"],[17,2,1,"","is_estimation_mode"],[17,3,1,"","k"],[17,2,1,"","merge"],[17,3,1,"","n"],[17,2,1,"","normalized_rank_error"],[17,3,1,"","num_retained"],[17,2,1,"","serialize"],[17,2,1,"","to_string"],[17,2,1,"","update"]],"datasketches.req_floats_sketch":[[18,1,1,"","__init__"],[18,1,1,"","deserialize"],[18,1,1,"","get_RSE"],[18,2,1,"","get_cdf"],[18,2,1,"","get_max_value"],[18,2,1,"","get_min_value"],[18,2,1,"","get_pmf"],[18,2,1,"","get_quantile"],[18,2,1,"","get_quantiles"],[18,2,1,"","get_rank"],[18,2,1,"","get_rank_lower_bound"],[18,2,1,"","get_rank_upper_bound"],[18,2,1,"","is_empty"],[18,2,1,"","is_estimation_mode"],[18,2,1,"","is_hra"],[18,3,1,"","k"],[18,2,1,"","merge"],[18,3,1,"","n"],[18,3,1,"","num_retained"],[18,2,1,"","serialize"],[18,2,1,"","to_string"],[18,2,1,"","update"]],"datasketches.req_ints_sketch":[[18,1,1,"","__init__"],[18,1,1,"","deserialize"],[18,1,1,"","get_RSE"],[18,2,1,"","get_cdf"],[18,2,1,"","get_max_value"],[18,2,1,"","get_min_value"],[18,2,1,"","get_pmf"],[18,2,1,"","get_quantile"],[18,2,1,"","get_quantiles"],[18,2,1,"","get_rank"],[18,2,1,"","get_rank_lower_bound"],[18,2,1,"","get_rank_upper_bound"],[18,2,1,"","is_empty"],[18,2,1,"","is_estimation_mode"],[18,2,1,"","is_hra"],[18,3,1,"","k"],[18,2,1,"","merge"],[18,3,1,"","n"],[18,3,1,"","num_retained"],[18,2,1,"","serialize"],[18,2,1,"","to_string"],[18,2,1,"","update"]],"datasketches.req_items_sketch":[[18,1,1,"","__init__"],[18,1,1,"","deserialize"],[18,1,1,"","get_RSE"],[18,2,1,"","get_cdf"],[18,2,1,"","get_max_value"],[18,2,1,"","get_min_value"],[18,2,1,"","get_pmf"],[18,2,1,"","get_quantile"],[18,2,1,"","get_quantiles"],[18,2,1,"","get_rank"],[18,2,1,"","get_rank_lower_bound"],[18,2,1,"","get_rank_upper_bound"],[18,2,1,"","is_empty"],[18,2,1,"","is_estimation_mode"],[18,2,1,"","is_hra"],[18,3,1,"","k"],[18,2,1,"","merge"],[18,3,1,"","n"],[18,3,1,"","num_retained"],[18,2,1,"","serialize"],[18,2,1,"","to_string"],[18,2,1,"","update"]],"datasketches.tdigest_double":[[19,1,1,"","__init__"],[19,2,1,"","compress"],[19,1,1,"","deserialize"],[19,2,1,"","get_cdf"],[19,2,1,"","get_max_value"],[19,2,1,"","get_min_value"],[19,2,1,"","get_pmf"],[19,2,1,"","get_quantile"],[19,2,1,"","get_rank"],[19,2,1,"","get_serialized_size_bytes"],[19,2,1,"","get_total_weight"],[19,2,1,"","is_empty"],[19,3,1,"","k"],[19,2,1,"","merge"],[19,2,1,"","serialize"],[19,2,1,"","to_string"],[19,2,1,"","update"]],"datasketches.tdigest_float":[[19,1,1,"","__init__"],[19,2,1,"","compress"],[19,1,1,"","deserialize"],[19,2,1,"","get_cdf"],[19,2,1,"","get_max_value"],[19,2,1,"","get_min_value"],[19,2,1,"","get_pmf"],[19,2,1,"","get_quantile"],[19,2,1,"","get_rank"],[19,2,1,"","get_serialized_size_bytes"],[19,2,1,"","get_total_weight"],[19,2,1,"","is_empty"],[19,3,1,"","k"],[19,2,1,"","merge"],[19,2,1,"","serialize"],[19,2,1,"","to_string"],[19,2,1,"","update"]],"datasketches.theta_a_not_b":[[3,1,1,"","__init__"],[3,2,1,"","compute"]],"datasketches.theta_intersection":[[3,1,1,"","__init__"],[3,2,1,"","get_result"],[3,2,1,"","has_result"],[3,2,1,"","update"]],"datasketches.theta_jaccard_similarity":[[9,1,1,"","dissimilarity_test"],[9,1,1,"","exactly_equal"],[9,1,1,"","jaccard"],[9,1,1,"","similarity_test"]],"datasketches.theta_sketch":[[3,2,1,"","get_estimate"],[3,2,1,"","get_lower_bound"],[3,2,1,"","get_seed_hash"],[3,2,1,"","get_upper_bound"],[3,2,1,"","is_empty"],[3,2,1,"","is_estimation_mode"],[3,2,1,"","is_ordered"],[3,3,1,"","num_retained"],[3,3,1,"","theta"],[3,3,1,"","theta64"],[3,2,1,"","to_string"]],"datasketches.theta_union":[[3,1,1,"","__init__"],[3,2,1,"","get_result"],[3,2,1,"","update"]],"datasketches.tuple_a_not_b":[[4,1,1,"","__init__"],[4,2,1,"","compute"]],"datasketches.tuple_intersection":[[4,1,1,"","__init__"],[4,2,1,"","get_result"],[4,2,1,"","has_result"],[4,2,1,"","update"]],"datasketches.tuple_jaccard_similarity":[[9,1,1,"","dissimilarity_test"],[9,1,1,"","exactly_equal"],[9,1,1,"","jaccard"],[9,1,1,"","similarity_test"]],"datasketches.tuple_sketch":[[4,2,1,"","DEFAULT_SEED"],[4,2,1,"","get_estimate"],[4,2,1,"","get_lower_bound"],[4,2,1,"","get_seed_hash"],[4,2,1,"","get_upper_bound"],[4,2,1,"","is_empty"],[4,2,1,"","is_estimation_mode"],[4,2,1,"","is_ordered"],[4,3,1,"","num_retained"],[4,3,1,"","theta"],[4,3,1,"","theta64"],[4,2,1,"","to_string"]],"datasketches.tuple_union":[[4,1,1,"","__init__"],[4,2,1,"","get_result"],[4,2,1,"","reset"],[4,2,1,"","update"]],"datasketches.update_theta_sketch":[[3,1,1,"","__init__"],[3,2,1,"","compact"],[3,2,1,"","reset"],[3,2,1,"","trim"],[3,2,1,"","update"]],"datasketches.update_tuple_sketch":[[4,1,1,"","__init__"],[4,2,1,"","compact"],[4,2,1,"","filter"],[4,2,1,"","reset"],[4,2,1,"","trim"],[4,2,1,"","update"]],"datasketches.var_opt_sketch":[[22,1,1,"","__init__"],[22,1,1,"","deserialize"],[22,2,1,"","estimate_subset_sum"],[22,2,1,"","get_serialized_size_bytes"],[22,2,1,"","is_empty"],[22,3,1,"","k"],[22,3,1,"","n"],[22,3,1,"","num_samples"],[22,2,1,"","serialize"],[22,2,1,"","to_string"],[22,2,1,"","update"]],"datasketches.var_opt_union":[[22,1,1,"","__init__"],[22,1,1,"","deserialize"],[22,2,1,"","get_result"],[22,2,1,"","get_serialized_size_bytes"],[22,2,1,"","reset"],[22,2,1,"","serialize"],[22,2,1,"","to_string"],[22,2,1,"","update"]]},"objnames":{"0":["py","class","Python class"],"1":["py","method","Python method"],"2":["py","attribute","Python attribute"],"3":["py","property","Python property"],"4":["py","function","Python function"]},"objtypes":{"0":"py:class","1":"py:method","2":"py:attribute","3":"py:property","4":"py:function"},"terms":{"":[1,6,20,21,22],"0":[3,4,5,6,10,16,17,18],"01668v2":18,"05":5,"1":[0,1,3,4,5,6,10,16,17,18,19],"10":[1,17],"100":17,"1000":17,"11":0,"12":[3,4,18],"128":17,"13":16,"14":6,"16":1,"18":6,"1982":6,"1985":2,"1e":6,"1e9":6,"2":[0,1,3,4,6,17,18],"20":17,"200":[16,19],"2002":6,"2003":6,"2004":18,"2006":6,"2021":17,"2023":20,"21":1,"3":[0,1,3,4,6,17,18],"30":17,"32":12,"33":16,"4":[1,12,17],"40":17,"47":16,"483":17,"5":[5,6,17],"500":17,"50th":17,"517":17,"6":1,"64":[0,3,4,5,12,17],"65":16,"7":[1,9,17],"75":6,"8":[1,6,12],"80":11,"900":17,"9001":[0,3,4,9],"93smirnov_test":11,"95":[5,17],"95th":17,"97":9,"99":[16,17],"A":[1,3,4,6,10,11,12,13,16,17,22],"As":[0,17],"For":[0,1,5,6,16,17,18,19,24],"If":[1,6,9,16,17,18,19],"In":[0,1,16,20],"It":[3,16,17,18,19],"One":2,"That":15,"The":[0,1,2,3,4,5,6,7,10,11,12,13,15,16,17,18,19,20,21,22,23],"Then":16,"There":[3,6],"These":[1,8,9,15,21,24],"With":[16,17,18],"_":11,"__call__":[10,13],"__eq__":6,"__hash__":6,"__init__":[0,1,3,4,6,16,17,18,19,20,22,23],"__lt__":[16,17,18],"_datasketch":[0,1,3,4,5,6,9,11,16,17,18,19,20,22,23],"ab":18,"abbadi":6,"abil":18,"about":[1,15,16,17],"abov":[7,16],"absolut":8,"abstract":[3,4,8,10,12,13],"accept":24,"account":11,"accumulatori":13,"accumulatorpolici":13,"accur":19,"accuraci":[0,1,2,3,5,6,16,17,18,19],"achiev":5,"activ":[6,14],"actual":[9,17],"ad":13,"add":16,"addit":[0,2,6,12],"addition":16,"advanc":21,"affect":[16,17],"after":[18,21],"against":[0,9],"agraw":6,"algorithm":[0,1,2,3,6,14,18,19],"all":[1,3,6,12,13,15,16,17,19,20,22],"alloc":12,"allow":[0,4,12,13,18],"along":6,"also":[0,3,10,14,15,17,19],"altern":[15,19],"although":[1,19,20],"alwai":[6,13,16,17,20,21],"an":[0,1,2,3,4,5,6,7,9,10,12,13,15,16,17,18,19,20,21,22,23],"analog":[16,17,18,19],"analysi":[4,11,16,17,18],"analyz":14,"ani":[3,4,5,6,7,13,16,17],"anoth":[0,6,18],"answer":15,"appl":0,"appli":[2,3,4,6,13,15,16,18,21,22],"applic":2,"approach":15,"approx":[5,18],"approxim":[0,1,3,4,5,6,10,15,16,17,18,19,23],"ar":[0,1,3,4,5,6,8,9,11,12,13,14,15,16,17,18,19,21,24],"arbitrari":[4,6],"arg":[0,1,3,4,5,6,10,12,13,16,17,18,19,20,22,23],"arg0":3,"arg1":3,"around":16,"arrai":[6,10,16,17,18,19],"art":2,"arxiv":18,"as_pmf":[16,17],"associ":[4,6,16,17,18,19],"assum":[6,11],"avail":16,"avoid":3,"axi":16,"b":[3,4,10,20],"back":0,"background":6,"backward":[6,15],"bag":6,"bandwidth":10,"base":[0,1,2,3,4,5,6,8,10,12,13,15,18,19,20,21,23],"basi":[10,19],"basic":[3,4,10],"becaus":16,"been":[7,16,17,18,22],"befor":[6,7],"behavior":1,"being":21,"below":16,"best":[16,17],"better":[1,2,3],"between":[1,3,4,6,8,9,16,17,18,23],"beyond":3,"bias":19,"big":14,"bin":[0,16],"binari":[12,17],"bit":[0,1,3,4,5,12,17],"blob":23,"bool":[1,3,4,9,11,16,17,18],"both":[11,18,19,21],"bound":[0,1,3,4,5,6,9,14,15,16,18,21,22],"bracket":16,"bucket":[1,5],"buffer":19,"build":23,"byte":[0,1,3,4,5,6,12,16,17,18,19,20,22,23],"c":[0,20],"call":[16,20],"came":2,"can":[0,1,3,4,6,11,13,15,16,17,18,19],"cannot":16,"capabl":[0,6,18],"capac":6,"cardin":[0,3],"case":[1,6,8,17,20],"caus":6,"cdf":[15,16,17,18,19],"centroid":19,"certain":[7,8,10,16,20],"characterist":19,"choic":1,"choos":18,"chosen":19,"class":[0,1,3,4,5,6,9,10,12,13,16,17,18,19,20,22,23],"classic":[15,17],"close":[7,19],"closest":19,"cm":5,"code":[6,18],"collect":1,"com":23,"combin":[8,13],"come":[11,17],"common":19,"commonli":[6,16],"compact":[1,3,4,15,16,18],"compact_theta_sketch":3,"compact_tuple_sketch":4,"compactor":18,"compar":[0,16,17,18],"comparison":[0,18],"compat":[6,12,15,17],"complic":4,"compress":[1,2,3,14,19],"comput":[3,4,6,8,9,15,19,20,22,23],"concept":2,"concret":8,"confid":[5,9,16,17],"configur":[0,1,5,16,17,18,19,20,22,23],"consecut":[16,17,18,19],"consid":[9,17],"consist":13,"constant":[1,6,16,17,18],"construct":[1,18,22],"consum":[1,12],"contain":[3,6,7],"context":10,"contrast":[5,20],"control":[16,17,18,19,23],"coreset":23,"cormod":[5,18],"correspond":[0,1,3,4,5,6,16,17,18,20,22,23],"cost":[1,12],"could":[16,17,18],"count":[1,3,4,6,17,18],"count_min_sketch":[5,7],"counter":6,"countmin":[7,14],"coupon":1,"cpc":[1,2,14],"cpc_sketch":[0,2],"cpc_union":0,"creat":[0,3,4,6,13,16,17,18,19,20,22,23],"create_summari":13,"creation":20,"criterion":18,"critic":12,"cross":[12,17],"cumul":[15,16,17,18,19],"current":[1,3,4,5,6,7,11,15,20,22],"custom":[4,10,12,13],"data":[2,3,6,11,12,13,14,15,16,17,18,19,20,22,23],"datasketch":[2,11,19],"datum":[0,1,3,4],"debug":18,"decreas":[15,18],"decrement":6,"dedic":[3,4],"default":[1,3,4,10,16,17,18,19],"default_se":4,"defin":[3,4,6,10,16,20],"definit":[16,17,18],"delta":5,"demain":6,"denot":[5,6],"densiti":[8,10,14,24],"density_sketch":[10,23,24],"depend":[5,16,19],"deprec":[14,15],"derial":19,"deriv":[3,16,17,18],"describ":[0,5,18,19],"deseri":[0,1,3,4,5,6,8,14,16,17,18,19,20,22,23],"design":[15,24],"desing":22,"detail":[18,21],"determin":[7,11],"determinist":6,"develop":[0,14],"deviat":[0,1,3,4,18],"differ":[0,1,2,3,6,12,13,18,19,21],"digest":[14,15],"dim":23,"dimac":5,"dimens":[0,23],"dimension":16,"discov":6,"discrep":23,"discuss":18,"disjoint":[16,17,18,19],"dissimilar":9,"dissimilarity_test":9,"distanc":23,"distinct":[0,1,3,4,6],"distribut":[1,11,15,16,17,18,19],"divid":[16,17,18,19],"do":[6,19],"document":16,"doe":[0,5,6,7,15,16,18,19,21],"domain":[16,19],"doubl":[16,17,18,20],"dtype":[16,17,18,19],"dun":19,"dure":1,"e":15,"e2":11,"each":[1,2,4,6,11,12,13,16,17,18,21],"earliest":2,"easili":[3,4],"ebpp":[14,21],"ebpps_sketch":[20,21],"edg":[16,17],"edo":[18,23],"edoliberti":23,"edu":5,"effect":[3,4,19],"effici":[0,3,6,14],"either":[6,15,16,17,18,19],"element":[2,6],"els":18,"empir":[0,16,17,18,19],"emploi":6,"empti":[0,1,3,4,6,16,17,18,19,20,22,23],"en":11,"enabl":[16,17],"encod":12,"end":[15,19],"endian":12,"enough":1,"ensur":[6,20,21],"entir":[7,15,21],"entri":[1,3,4,6],"entropi":0,"ep":16,"epsilon":[6,16],"equal":[11,15,16,17,18,20],"equival":[9,17,20,22],"error":[1,3,5,6,8,11,14,15,16,17,19,20,22,23],"ertl":19,"estim":[0,1,2,3,4,5,6,7,8,9,10,15,16,17,18,19,22,23,24],"estimate_subset_sum":22,"estimated_total_stream_weight":6,"estimated_total_weight":6,"evalu":[4,10],"even":[0,21],"everi":[3,4,5,6],"exact":[6,14,21],"exactli":[20,21],"exactly_equ":9,"exampl":[4,5,6,8,10,12,17],"exce":[6,18,20],"excel":19,"except":[1,16,17,18],"excess":[3,4],"exclud":6,"exclus":[16,17,18],"exist":[3,4,13],"expect":[9,20],"expens":6,"express":18,"extend":[12,13],"extens":[4,18],"extern":6,"extrem":[0,6,19],"f688c8161a25582457b0a09deb4630a81406293b":23,"f_x":5,"factor":18,"failur":5,"fals":[0,1,3,4,5,6,9,11,16,17,18,19,20,22,23],"famili":[1,8,11,19],"far":[6,15,16,17,18,19,20],"fast":0,"favor":[15,17],"fed":1,"feed":[20,22],"few":[4,19],"fewer":[6,20,22],"field":6,"filter":4,"find":6,"fit":[16,17],"fix":4,"flag":[16,17],"flajolet":[1,2],"flavor":[1,6],"float":[0,1,3,4,5,6,9,10,11,12,15,16,17,18,19,20],"float32":[16,17,18,19],"float64":[16,17,19],"fm85":0,"follow":[6,16,18,23],"footprint":2,"form":[3,4,6,11],"format":[12,19],"found":6,"four":15,"fraction":[3,4,16,17,20],"framework":3,"frequenc":[5,6,17],"frequent":[5,7,14],"frequent_items_error_typ":6,"frequent_items_sketch":[6,7],"frequent_strings_sketch":[6,7],"from":[2,3,4,6,7,10,11,12,16,17,18,19,20,21,22,23],"from_byt":12,"full":[1,5],"funciton":10,"function":[0,1,3,4,5,6,8,11,14,15,16,17,18,19],"futur":0,"g":15,"gaussian":10,"gaussiankernel":10,"gde":23,"gener":[6,7,10,15,16,17,18],"get":[16,17],"get_apriori_error":6,"get_cdf":[16,17,18,19],"get_compact_serialization_byt":1,"get_epsilon_for_lg_s":6,"get_estim":[0,1,3,4,5,6,23],"get_frequent_item":6,"get_lower_bound":[0,1,3,4,5,6],"get_max_updatable_serialization_byt":1,"get_max_valu":[16,17,18,19],"get_min_valu":[16,17,18,19],"get_n":17,"get_normalized_rank_error":[16,17,18],"get_pmf":[16,17,18,19],"get_quantil":[16,17,18,19],"get_rank":[16,17,18,19],"get_rank_lower_bound":18,"get_rank_upper_bound":18,"get_rel_err":1,"get_relative_error":5,"get_result":[0,1,3,4,20,22],"get_rs":18,"get_seed_hash":[3,4],"get_serialized_size_byt":[5,6,19,20,22],"get_siz":12,"get_total_weight":19,"get_updatable_serialization_byt":1,"get_upper_bound":[0,1,3,4,5,6],"github":23,"given":[0,1,3,4,5,6,10,11,12,15,16,17,18,19,20,22,23],"global":[6,15],"good":[2,3,15],"graham":[5,18],"gri":6,"grow":6,"guarante":[5,6,15,16,17,18],"ha":[1,3,4,5,7,16,17,18,19],"haa":20,"handl":[3,7,20],"has_result":[3,4],"hash":[0,3,4,5,6],"hat":5,"have":[1,6,11,15,16,17,18,22],"heavi":[5,6,7,14],"heaviest":7,"help":[9,18],"hentschel":20,"here":18,"heurist":15,"hi":0,"high":[0,1,15,18,19],"higher":[1,17],"highest":1,"highli":14,"hip":0,"histogram":[15,17],"histor":[0,15],"hitter":[5,6,7,14],"hll":[0,2,14],"hll_4":1,"hll_6":1,"hll_8":1,"hll_sketch":[1,2],"hll_union":1,"hold":[1,6,19],"how":[4,7,8,13,18],"howev":[6,16,18,19],"http":[5,11,18,23],"hyper":2,"hyperloglog":[0,2,3,14],"hypothesi":11,"hypothet":[16,17,18,19],"i":[0,1,2,3,4,5,6,7,8,10,11,12,13,14,15,16,17,18,19,20,21,22,23],"icon":0,"identifi":7,"imag":5,"implement":[0,1,4,6,7,10,12,13,16,17,18,19,23],"improv":[1,22],"includ":[15,16,17,18,19,20,21,22],"inclus":[1,16,17,18,21],"incom":[3,4,6],"increas":[16,17,18,19],"increment":6,"independ":16,"index":[9,14,16,17],"indic":[1,10],"inform":[19,20],"inherit":10,"init_number_of_sect":18,"initi":[1,3,4,6,18],"input":[0,1,3,4,6,10,11,16,17,18,19,21,23,24],"insert":[3,5,6],"inspir":23,"instanc":[6,16,17,18,19,20,22,23],"instead":[17,18],"insuffici":11,"int":[0,1,3,4,5,6,9,12,16,17,18,19,20,22,23],"int32":[16,17,18],"integ":[0,5,6,12,13,15],"integr":[1,3,4],"intern":6,"internet":6,"interpol":19,"interpret":16,"intersect":[2,3,4,13],"interv":[16,17,18,19],"introduc":6,"invers":[0,16],"involv":7,"is_compact":1,"is_empti":[0,1,3,4,5,6,16,17,18,19,20,22,23],"is_estimation_mod":[3,4,16,17,18,23],"is_hra":18,"is_ord":[3,4],"item":[1,3,4,5,7,12,14,15,16,17,18,19,20,21,22,23],"iter":20,"its":[0,12,16,17,19,20],"itself":6,"j":20,"j_":9,"jaccard":[3,4,8,14],"java":17,"job":15,"just":16,"justin":18,"k":[0,1,2,3,4,6,7,16,17,18,19,20,22,23],"kappa":0,"karnin":[18,23],"karnin19a":23,"karp":6,"keep":[1,4,20],"kei":[2,4],"kept":13,"kernel":[8,14,23,24],"kernel_funct":8,"kernel_sketch":8,"kernelfunct":[10,23],"kevin":0,"kll":[14,15,17],"kll_doubles_sketch":[11,16],"kll_floats_sketch":[11,16],"kll_ints_sketch":[11,16],"kll_items_sketch":[11,16],"known":[0,2,6,10,14,21],"kolmogorov":[8,14],"ks_test":[8,11],"kwarg":[0,1,3,4,5,6,10,12,13,16,17,18,19,20,22,23],"lang":0,"languag":[12,17],"larg":[1,15,16,17],"larger":[2,16,20],"largest":13,"last":[16,17,18],"lazi":16,"lb":[6,9],"le":5,"learn":[10,23],"least":[6,8],"left":[16,17,18],"legaci":6,"lemma":18,"len":12,"length":[6,16,17,18,20,21,22,23],"less":[15,16,17,18],"let":16,"letter":20,"level":[5,18],"leverag":1,"lg_config_k":1,"lg_k":[0,1,3,4],"lg_max_k":[1,6],"lg_max_map_s":6,"liberti":[18,23],"librari":[2,4,6,7,10,11,15,19,24],"like":[1,7,11,16],"limit":[6,20],"line":[16,17,18,19],"list":[5,7,9],"littl":12,"load_factor":6,"log":[1,2],"log2":[1,6],"logarithm":[0,3,4,6],"logic":[6,15],"longer":2,"look":6,"loos":18,"lopez":6,"low":[15,18,19],"lower":[0,1,3,4,5,6,9,16,18,19,22],"lower_bound":9,"m":[6,16,17,18,19],"machin":[10,23],"mai":[5,6,14,15,16,18,20],"maintain":[3,7],"make":16,"mani":[3,19],"map":6,"mapcap":6,"mapsiz":6,"margin":20,"martin":2,"mass":[15,16,17,18,19],"mass_i":16,"match":[0,3,4,22],"mathemat":[10,18,19],"max":[13,16,17,18,19],"max_k":22,"max_map_s":6,"maximum":[1,3,4,5,6,16,17,18,19,20,22],"maxintpolici":13,"maxmapcap":6,"maxmaps":6,"mean":[4,6,16,17,20],"measur":[3,4,9,16,17,18,19],"median":[6,17,19],"member":[3,6],"memori":[1,2,6],"merg":[0,1,4,5,6,16,17,18,19,20,23],"mergingdigest":19,"method":[0,1,3,4,5,6,10,12,16,17,18,19,20,22,23],"metwal":6,"middl":19,"might":[6,16],"million":17,"min":[13,16,17,18,19],"minim":21,"minimum":[2,3,16,17,18,19,22],"minintpolici":13,"misra":6,"miss":6,"mlr":23,"mode":[1,3,4,16,17,18,23],"modifi":[11,18,19],"modul":14,"monoton":[16,17,18,19],"more":[0,6,19],"most":[7,17],"much":[1,6],"multipli":17,"multiset":6,"munro":6,"must":[1,3,4,10,12,13,16,17,18],"muthukrishnan":5,"n":[1,16,17,18,20,22,23],"name":6,"nan":[16,17,18],"natur":[16,17],"ndarrai":[16,17,18,19],"nearli":[0,16],"necessari":[16,17,18,19],"necessarili":7,"necesssari":19,"need":[3,5,6,13,20,21,22],"network":17,"never":[5,6,16,18],"new":[0,1,6,13,17,20,22,23],"newli":0,"no_false_neg":6,"no_false_posit":6,"node":17,"nomin":[3,4,18],"non":[0,1,3,4,5,6,16,17,18,19,20,22,23],"none":[0,1,3,4,5,6,16,17,18,19,20,22,23],"normal":[16,17,18,19],"normalized_rank_error":[16,17],"note":[6,9,11,16,18],"novemb":17,"now":24,"null":[11,12],"num_active_item":6,"num_bucket":5,"num_byt":12,"num_hash":5,"num_retain":[3,4,16,17,18,23],"num_sampl":22,"num_std_dev":1,"number":[0,1,2,3,4,5,6,12,16,17,18,19,20,22,23],"numer":[15,19,20],"numpi":10,"numsect":18,"object":[0,1,3,4,5,6,7,9,10,12,13,16,17,18,19,20,22,23],"obtain":[5,16,17,18],"occurr":5,"off":[1,2,16,17,18,19],"offer":[1,2,7],"offest":12,"offset":12,"often":7,"one":[2,5,6,7,8,16,17,18,19,23],"onli":[1,6,15,16,17,18,19,24],"oper":[0,2,3,4,13,16,18,19],"opposit":16,"opt":22,"optim":[0,14,16,21],"option":[0,3,4,6,16,17,18,19,20,22],"order":[3,4,5,13,15,20],"org":[11,18],"ortiz":6,"other":[3,4,5,16,17,19],"otherwis":[0,1,3,4,5,6,9,11,16,17,18,19,20,22,23],"otmar":19,"our":6,"output":18,"outsid":7,"over":[6,15,17],"overal":17,"overestim":[5,19],"overload":[0,1,3,4,5,11,16,17,18,19],"overrid":[10,12],"p":[3,4,11,20],"packag":3,"packet":[6,17],"page":[14,19],"pair":[6,8,11],"papadimitri":6,"paper":[0,3,5,18,19,23],"paramet":[0,1,3,4,5,6,10,12,13,16,17,18,19,20,22,23],"partial":20,"particular":18,"particularli":10,"pass":[16,17],"pattern":10,"pavel":18,"pdf":[5,23],"per":[1,16],"percentag":7,"percentil":[16,17],"perform":[0,1,2,3,4,8,10,11,16,18,19],"permiss":5,"phillip":1,"physic":6,"plot":16,"plu":6,"pmf":[15,16,17,18,19],"point":[0,1,3,4,10,12,15,16,17,18,19,20,23],"polici":[4,8,14],"portion":[15,20],"posit":6,"possibl":0,"power":[6,18],"pp":20,"practic":[3,6],"pre":12,"precis":[17,20],"predic":[4,21,22],"present":22,"press":23,"print":[20,22],"priori":[1,6,18],"priorit":19,"probabilist":[1,2,5,14,15,16,17,18],"probabilitii":[14,21],"probabl":[0,5,6,15,16,17,18,19,20,21,22],"problem":14,"proceed":23,"process":[19,20,22],"produc":[0,1,3,4,5,6,16,17,18,19,20,22,23],"project":[14,17],"pronounc":19,"proof":6,"properti":[0,1,2,3,4,5,6,15,16,17,18,19,20,22,23],"proport":[14,21],"prototyp":18,"proven":15,"provid":[0,1,2,3,4,5,6,7,9,10,11,12,13,15,16,17,18,19,22,23,24],"pub":5,"purg":6,"py":23,"pydoublesserd":12,"pyfloatsserd":12,"pyintsserd":12,"pylongsserd":12,"pyobjectserd":[4,6,12,16,17,18,20,22],"pystringsserd":12,"python":[13,18],"q":16,"q_hi":16,"q_lo":16,"qualifi":6,"quantil":[8,16,19,23],"quantiles_doubles_sketch":[11,17],"quantiles_floats_sketch":[11,17],"quantiles_ints_sketch":[11,17],"quantiles_items_sketch":[11,17],"queri":[5,15,16,17,22],"quickli":14,"quit":[0,4,15,16],"r":16,"r1":16,"r2":16,"r_":16,"r_i":16,"radial":10,"random":[6,20],"randomli":21,"rang":15,"rank":[15,16,17,18,19],"rate":[3,4],"reach":[1,6],"read":[0,1,3,4,5,6,12,19,20,22,23],"real":[16,17,18,19],"reason":1,"rebuild":6,"receiv":[1,17],"recognit":10,"recommend":1,"reconstruct":12,"redesign":6,"rediscov":6,"refer":[6,8,12,16,19],"reflect":11,"regardless":7,"reject":11,"rel":[1,5,7,14,15,20,21,22],"relat":[7,9,20,22],"relationship":16,"relative_error":5,"relev":13,"reli":10,"remain":18,"remov":[3,4,6],"repeat":6,"repres":[1,17,20],"req":[14,15,17,19],"req_floats_sketch":18,"req_ints_sketch":18,"req_items_sketch":18,"requir":[4,5,6,8,16,17,18,20,22,23],"reservoir":[20,22],"reset":[1,3,4,22],"respect":[16,17],"result":[0,3,4,6,16,17,18,19,21,22],"retain":[3,4,6,16,17,18,23],"retun":12,"return":[0,1,3,4,5,6,9,10,11,12,13,16,17,18,19,20,22,23],"right":[4,16,17,18],"roughli":[0,22],"round":18,"row":1,"rse":18,"rule":13,"run":6,"runtimeerror":[16,17,18,19],"rutger":5,"s1":16,"s2":16,"s_i":16,"s_m":16,"same":[1,3,11],"sampl":[3,4,16,17,18,23],"satisfi":5,"scheme":[12,16],"score":10,"search":14,"section":18,"section_s":18,"secur":0,"see":[16,19],"seed":[0,3,4,5,9],"seem":[16,19],"seen":[5,6,7,15,19,20],"select":4,"self":[0,1,3,4,5,6,10,12,13,16,17,18,19,20,22,23],"semin":2,"separ":[3,9,16,17,18],"serd":[4,6,8,14,16,17,18,20,22],"serial":[0,1,3,4,5,6,8,14,16,17,18,19,20,22,23],"serialize_compact":1,"serialize_updat":1,"set":[2,3,4,6,13,16,17,18,19,23],"sever":[2,3,4,6,12],"shenker":6,"should":[13,16,20],"show":19,"shown":16,"side":[16,17,19],"significantli":1,"similar":[2,3,4,8,10,13,14,19],"similarity_test":9,"similarli":17,"simpl":[2,3,6,12],"simultan":0,"sinc":[6,18],"singl":[16,17],"size":[1,3,4,5,6,11,12,14,16,17,18,19,21,22,23],"sk_1":11,"sk_2":11,"skech":18,"sketch":[0,1,2,6,8,9,11,12,19,20,22],"sketch_a":9,"sketch_b":9,"slightli":19,"slot":1,"sm":16,"small":[1,6,11,15],"smaller":[0,1,6,16,22],"smallest":13,"smirnov":[8,14],"snly":7,"so":[0,6,15,16,17,18,19,20],"solut":2,"some":[6,8,16],"sometim":16,"somewhat":[2,21],"sort":[3,4,16,17,18,19],"sourc":[3,4],"sourch":4,"space":[0,1,2,3,6],"special":18,"specif":[6,8,10,15,16,17],"specifi":[0,1,5,6,8,12,13,16,18],"speed":[0,6],"split":[16,17,18,19],"split_point":[16,17,18,19],"sqrt":18,"standard":[0,1,3,4,18],"start":[1,6,12,18],"start_full_s":1,"start_max_s":1,"state":[1,2,3,4,6,18,22],"static":[0,1,3,4,5,6,16,17,18,19,20,22,23],"still":19,"stochast":[16,17],"storag":[1,12,15],"store":[2,3,6],"str":[0,1,3,4,5],"straightforward":15,"stream":[0,1,3,4,5,6,7,15,16,17,18,19,20,21,22,23],"strictli":20,"string":[0,1,3,4,5,6,7,12,16,17,18,19,20,22,23],"string_cont":12,"subset":[21,22],"subtract":16,"suggest":5,"suggest_num_bucket":5,"suggest_num_hash":5,"sum":[6,16,17,18,21,22],"summari":[0,1,3,4,5,6,8,13,16,17,18,19,20,22,23],"support":[2,6,19],"surviv":0,"t":[14,15,17],"tabl":[1,6],"take":11,"target":1,"target_hll_typ":1,"task":2,"tdigest":19,"tdigest_doubl":19,"tdigest_float":19,"ted":19,"templat":17,"tend":19,"term":1,"termin":12,"test":[8,9,14],"tgt_hll_type":1,"tgt_type":1,"thaler":18,"than":[0,1,2,3,6,15,16,17,18,20],"thei":[4,11,15,21],"them":8,"theta":[1,2,4,8,9,14],"theta64":[3,4],"theta_a_not_b":3,"theta_intersect":3,"theta_jaccard_similar":[3,9],"theta_sketch":[2,3,4,9],"theta_union":3,"thi":[0,1,4,5,6,11,12,13,14,16,17,18,19,20,22,23],"those":[7,8,15],"thousand":[16,17],"three":[1,12,15],"threshold":9,"through":[3,4,6],"throw":[16,17,18,19],"thu":[16,18],"tian":20,"tight":18,"time":[1,6,16,17,18],"to_byt":12,"to_str":[0,1,3,4,5,6,16,17,18,19,20,22,23],"too":[6,11],"tool":18,"top":[6,7],"topk":14,"total":[5,17,18,19,20,22],"total_weight":[5,6],"toward":19,"track":6,"trade":[1,2,16,17,18,19],"tradeoff":0,"translat":16,"trial":[16,17],"trim":[3,4],"true":[0,1,3,4,5,6,9,11,16,17,18,19,20,22,23],"true_mass":16,"true_rank":16,"tupl":[2,3,8,9,12,14],"tuple_a_not_b":[3,4],"tuple_intersect":4,"tuple_jaccard_similar":[4,9],"tuple_polici":8,"tuple_sketch":[2,4,8,9,13],"tuple_union":4,"tuplepolici":[4,13],"two":[0,6,7,10,11,16,18,23],"type":[1,2,4,6,7,10,11,12,13,15],"typic":[6,15],"u":16,"ub":[6,9],"under":14,"underestim":[5,19],"underli":11,"understand":[15,18],"unequ":20,"uniform":[15,20,22],"union":[0,1,3,4,13,22],"uniqu":[0,1,2,16,17,18,19],"unlik":19,"unsurprisingli":10,"up":[1,6],"updat":[0,1,3,4,5,6,13,16,17,18,19,20,22,23],"update_summari":13,"update_theta_sketch":3,"update_tuple_sketch":4,"upon":20,"upper":[0,1,3,4,5,6,9,16,18,22],"upper_bound":[1,9],"us":[1,3,4,5,6,8,9,10,11,12,13,15,16,17,18,19,20,21,22,23],"usag":6,"user":[0,10,18],"usual":6,"v99":23,"valid":[3,4,18],"valu":[0,1,2,3,4,5,6,10,11,12,13,15,16,17,18,19,20,22],"var":22,"var_opt_sketch":[21,22],"var_opt_union":22,"variabl":[6,18],"varianc":[14,21],"variant":[3,6,7],"varopt":[14,20,21],"vector":[10,16,17,18,19,23],"veri":[4,6,15,16,17,19],"version":[1,6,7,12,15,16,17,18,19],"vesel\u00fd":18,"via":18,"view":16,"visibl":18,"w":6,"warmup":1,"we":[6,11,16,18],"weight":[5,6,7,16,17,18,19,20,21,22],"well":[0,2,15,19,22],"were":[2,6,16,17],"what":[6,15],"when":[0,1,3,4,5,8,13,15,17,18,22],"where":[1,6,12,13,16,20],"whether":[1,3,4,18],"which":[2,3,4,5,6,7,10,12,15,16,17,18,19],"while":[2,3,15,19],"whose":7,"wiki":11,"wikipedia":11,"win":0,"within":[5,8],"without":15,"work":[2,15,17,18],"wors":16,"worst":6,"would":6,"written":[12,18],"x":[5,16],"y":[16,20],"year":6,"yield":16,"you":17,"zero":16,"zohar":[18,23]},"titles":["Compressed Probabilistic Counting (CPC)","HyperLogLog (HLL)","Distinct Counting","Theta Sketch","Tuple Sketch","CountMin Sketch","Frequent Items","Frequency Sketches","Helper Classes","Jaccard Similarity","Kernel Function","Kolmogorov-Smirnov Test","Serialize/Deserialize (SerDe)","Tuple Policy","Apache DataSketches","Quantiles Sketches","KLL Sketch","Quantiles Sketch (Deprecated)","Relative Error Quantiles (REQ) Sketch","t-digest","Exact and Bounded, Probabilitiy Proportional to Size (EBPPS) Sampling","Random Sampling Sketches","Variance Optimal Sampling (VarOpt)","Density Sketch","Vector Sketches"],"titleterms":{"apach":14,"bound":20,"class":[8,14],"compress":0,"count":[0,2,14],"countmin":5,"cpc":0,"datasketch":14,"densiti":23,"deprec":17,"deseri":12,"digest":19,"distinct":[2,14],"ebpp":20,"error":18,"estim":14,"exact":20,"frequenc":[7,14],"frequent":6,"function":10,"helper":[8,14],"hll":1,"hyperloglog":1,"indic":14,"item":6,"jaccard":9,"kernel":10,"kll":16,"kolmogorov":11,"optim":22,"polici":13,"probabilist":0,"probabilitii":20,"proport":20,"quantil":[14,15,17,18],"random":[14,21],"rel":18,"req":18,"sampl":[14,20,21,22],"serd":12,"serial":12,"similar":9,"size":20,"sketch":[3,4,5,7,14,15,16,17,18,21,23,24],"smirnov":11,"t":19,"tabl":14,"test":11,"theta":3,"tupl":[4,13],"varianc":22,"varopt":22,"vector":[14,24]}}) \ No newline at end of file diff --git a/docs/main/vector/density_sketch.html b/docs/main/vector/density_sketch.html new file mode 100644 index 00000000..33445703 --- /dev/null +++ b/docs/main/vector/density_sketch.html @@ -0,0 +1,246 @@ + + + + + + + + + Density Sketch — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Density Sketch

+

Builds a coreset from the given set of input points. +Provides density estimate at a given point.

+

Based on the following paper: Zohar Karnin, Edo Liberty +“Discrepancy, Coresets, and Sketches in Machine Learning” +https://proceedings.mlr.press/v99/karnin19a/karnin19a.pdf

+

Inspired by the following implementation: https://github.com/edoliberty/streaming-quantiles/blob/f688c8161a25582457b0a09deb4630a81406293b/gde.py

+

Requires the use of a KernelFunction to compute the distance between two vectors.

+
+
+class density_sketch(*args, **kwargs)
+

Static Methods:

+
+
+deserialize(bytes: bytes, kernel: _datasketches.KernelFunction) _datasketches.density_sketch
+

Reads a bytes object and returns the corresponding density_sketch

+
+ +

Non-static Methods:

+
+
+__init__(self, k: int, dim: int, kernel: _datasketches.KernelFunction) None
+

Creates a new density sketch

+
+
Parameters:
+
    +
  • k (int) – controls the size and error of the sketch

  • +
  • dim (int) – dimension of the input data

  • +
  • kernel (KernelFunction) – instance of a kernel

  • +
+
+
+
+ +
+
+property dim
+

The configured parameter dim

+
+ +
+
+get_estimate
+

Returns an approximate density at the given point

+
+ +
+
+is_empty
+

Returns True if the sketch is empty, otherwise False

+
+ +
+
+is_estimation_mode
+

Returns True if the sketch is in estimation mode, otherwise False

+
+ +
+
+property k
+

The configured parameter k

+
+ +
+
+merge
+

Merges the provided sketch into this one

+
+ +
+
+property n
+

The length of the input stream

+
+ +
+
+property num_retained
+

The number of retained items (samples) in the sketch

+
+ +
+
+serialize
+

Serializes the sketch into a bytes object

+
+ +
+
+to_string
+

Produces a string summary of the sketch

+
+ +
+
+update
+

Updates the sketch with the given vector

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/main/vector/index.html b/docs/main/vector/index.html new file mode 100644 index 00000000..56c6d446 --- /dev/null +++ b/docs/main/vector/index.html @@ -0,0 +1,133 @@ + + + + + + + + + Vector Sketches — datasketches 0.1 documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Vector Sketches

+

These sketches are designed to accept vector inputs. For now, the library provides only the +density_sketch for Kernel Density Estimation.

+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/make.bat b/docs/make.bat deleted file mode 100644 index 747ffb7b..00000000 --- a/docs/make.bat +++ /dev/null @@ -1,35 +0,0 @@ -@ECHO OFF - -pushd %~dp0 - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set SOURCEDIR=source -set BUILDDIR=build - -%SPHINXBUILD% >NUL 2>NUL -if errorlevel 9009 ( - echo. - echo.The 'sphinx-build' command was not found. Make sure you have Sphinx - echo.installed, then set the SPHINXBUILD environment variable to point - echo.to the full path of the 'sphinx-build' executable. Alternatively you - echo.may add the Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.https://www.sphinx-doc.org/ - exit /b 1 -) - -if "%1" == "" goto help - -%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% -goto end - -:help -%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% - -:end -popd diff --git a/docs/source/conf.py b/docs/source/conf.py deleted file mode 100644 index 865f760c..00000000 --- a/docs/source/conf.py +++ /dev/null @@ -1,36 +0,0 @@ -# Configuration file for the Sphinx documentation builder. -# -# For the full list of built-in configuration values, see the documentation: -# https://www.sphinx-doc.org/en/master/usage/configuration.html - -# -- Project information ----------------------------------------------------- -# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information - -import sys -import os - -# need to fix the paths so that sphinx can find the source code. -sys.path.insert(0, os.path.abspath("../../datasketches")) -sys.path.insert(0, os.path.abspath("../../src")) - - -project = 'datasketches' -copyright = '2023' -author = 'Apache Software Foundation' -release = '0.1' -add_module_names = False - -# -- General configuration --------------------------------------------------- -# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration - -extensions = ["sphinx.ext.autodoc"] -templates_path = ['_templates'] -exclude_patterns = [] - - - -# -- Options for HTML output ------------------------------------------------- -# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output - -html_theme = 'sphinx_rtd_theme' -html_static_path = ['_static'] diff --git a/include/kernel_function.hpp b/include/kernel_function.hpp deleted file mode 100644 index 93bc6d2a..00000000 --- a/include/kernel_function.hpp +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#include -#include -#include -#include -#include -#include - -#include - -#ifndef _KERNEL_FUNCTION_HPP_ -#define _KERNEL_FUNCTION_HPP_ - -namespace nb = nanobind; - -namespace datasketches { - -/** - * @brief kernel_function provides the underlying base class from - * which native Python kernels ultimately inherit. The actual - * kernels implement KernelFunction, as shown in KernelFunction.py - */ -struct kernel_function : public nb::intrusive_base { - virtual double operator()(nb::handle& a, nb::handle& b) const = 0; - virtual ~kernel_function() = default; -}; - -/** - * @brief KernelFunction provides the "trampoline" class for nanobind - * that allows for a native Python implementation of kernel - * functions. - */ -struct KernelFunction : public kernel_function { - NB_TRAMPOLINE(kernel_function, 1); - - /** - * @brief Evaluates K(a,b), the kernel function for the given points a and b - * @param a the first vector - * @param b the second vector - * @return The function value K(a,b) - */ - double operator()(nb::handle& a, nb::handle& b) const override { - NB_OVERRIDE_PURE_NAME( - "__call__", // Name of function in python - operator(), // Name of function in C++ - a, b // Arguments - ); - } -}; - -/* The kernel_function_holder provides a concrete class that dispatches calls - * from the sketch to the kernel_function. This class is needed to provide a - * concrete object to produce a compiled library, but library users should - * never need to use this directly. - */ -struct kernel_function_holder { - explicit kernel_function_holder(kernel_function* kernel) : _kernel(kernel) {} - kernel_function_holder(const kernel_function_holder& other) : _kernel(other._kernel) {} - kernel_function_holder(kernel_function_holder&& other) : _kernel(std::move(other._kernel)) {} - kernel_function_holder& operator=(const kernel_function_holder& other) { _kernel = other._kernel; return *this; } - kernel_function_holder& operator=(kernel_function_holder&& other) { std::swap(_kernel, other._kernel); return *this; } - - double operator()(const std::vector& a, nb::object& b) const { - const npy_intp size_a[1] { static_cast(a.size()) }; - nb::handle a_obj(PyArray_SimpleNewFromData(1, size_a, NPY_DOUBLE, const_cast(a.data()))); - return _kernel->operator()( - a_obj, - b - ); - } - - double operator()(const std::vector& a, const std::vector& b) const { - const npy_intp size_a[1] { static_cast(a.size()) }; - const npy_intp size_b[1] { static_cast(b.size()) }; - nb::handle a_obj(PyArray_SimpleNewFromData(1, size_a, NPY_DOUBLE, const_cast(a.data()))); - nb::handle b_obj(PyArray_SimpleNewFromData(1, size_b, NPY_DOUBLE, const_cast(b.data()))); - double val = _kernel->operator()( - a_obj, - b_obj - ); - return val; - } - - private: - nb::ref _kernel; -}; - -} - -#endif // _KERNEL_FUNCTION_HPP_ diff --git a/include/py_object_lt.hpp b/include/py_object_lt.hpp deleted file mode 100644 index 3dc3ab3d..00000000 --- a/include/py_object_lt.hpp +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#ifndef _PY_OBJECT_LT_HPP_ -#define _PY_OBJECT_LT_HPP_ - -#include - -/* - This header defines a less than operator on generic python - objects. The implementation calls the object's built-in __lt__() - method. If that method is not defined, the call may fail. -*/ - -struct py_object_lt { - bool operator()(const nanobind::object& a, const nanobind::object& b) const { - return a < b; - } -}; - -#endif // _PY_OBJECT_LT_HPP_ \ No newline at end of file diff --git a/include/py_object_ostream.hpp b/include/py_object_ostream.hpp deleted file mode 100644 index 415f7ab5..00000000 --- a/include/py_object_ostream.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#ifndef _PY_OBJECT_OSTREAM_HPP_ -#define _PY_OBJECT_OSTREAM_HPP_ - -#include - -#include -#include - -/* - This header defines an ostream output operator on a generic python - object. The implementation calls the object's built-in __str__() - method. If that method is not defined, the call may fail. - - NOTE: This header must be included before the inclusion of - any sketch classes. -*/ - -namespace datasketches { - -static std::ostream& operator<<(std::ostream& os, const nanobind::object& obj) { - os << std::string(nanobind::str(obj).c_str()); - return os; -} - -} - -#endif // _PY_OBJECT_OSTREAM_HPP_ diff --git a/include/py_serde.hpp b/include/py_serde.hpp deleted file mode 100644 index 1ff56988..00000000 --- a/include/py_serde.hpp +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#include -#include -#include - -#ifndef _PY_SERDE_HPP_ -#define _PY_SERDE_HPP_ - -namespace nb = nanobind; - -namespace datasketches { - -/** - * @brief The py_object_serde is an abstract class that implements the - * datasketches serde interface, and is used to allow custom Python - * serialization of items wrapped as generic nb::object types. The actual - * Python implementation classes must extend the PyObjectSerDe class. - */ -struct py_object_serde { - /** - * @brief Get the serialized size of an object, in bytes - * - * @param item A provided item - * @return int64_t The serialized size of the item, in bytes - */ - virtual int64_t get_size(const nb::object& item) const = 0; - - /** - * @brief Serializes an item to a bytes object - * - * @param item A provided item - * @return The serialized image of the item as a Python bytes object - */ - virtual nb::bytes to_bytes(const nb::object& item) const = 0; - - /** - * @brief Constructs an object from a serialized image, reading the - * incoming buffer starting at the specified offset. - * - * @param bytes A buffer containing items from a serialized sketch - * @param offset The starting offset into the bytes buffer - * @return A Python tuple of the reconstructed item and the total number of bytes read - */ - virtual nb::tuple from_bytes(nb::bytes& bytes, size_t offset) const = 0; - - virtual ~py_object_serde() = default; - - // these methods are required by the serde interface; see common/include/serde.hpp for - // default implementations for C++ std::string and numeric types. - size_t size_of_item(const nb::object& item) const; - size_t serialize(void* ptr, size_t capacity, const nb::object* items, unsigned num) const; - size_t deserialize(const void* ptr, size_t capacity, nb::object* items, unsigned num) const; -}; - -/** - * @brief The PyObjectSerDe class provides a concrete base class - * that nanobind uses as a "trampoline" to pass calls through to - * the abstract py_object_serde class. Custom Python serde implementations - * must extend this class. - */ -struct PyObjectSerDe : public py_object_serde { - NB_TRAMPOLINE(py_object_serde, 3); - - // trampoline definitions -- need one for each virtual function - int64_t get_size(const nb::object& item) const override { - NB_OVERRIDE_PURE( - get_size, // Name of function in C++ (must match Python name) - item // Argument(s) - ); - } - - nb::bytes to_bytes(const nb::object& item) const override { - NB_OVERRIDE_PURE( - to_bytes, // Name of function in C++ (must match Python name) - item // Argument(s) - ); - } - - nb::tuple from_bytes(nb::bytes& bytes, size_t offset) const override { - NB_OVERRIDE_PURE( - from_bytes, // Name of function in C++ (must match Python name) - bytes, offset // Argument(s) - ); - } -}; - -} - -#endif // _PY_SERDE_HPP_ diff --git a/include/quantile_conditional.hpp b/include/quantile_conditional.hpp deleted file mode 100644 index 2e3c55bf..00000000 --- a/include/quantile_conditional.hpp +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#ifndef _QUANTILE_CONDITIONAL_HPP_ -#define _QUANTILE_CONDITIONAL_HPP_ - -/* - This header defines conditionally compiled functions shared - across the set of quantile family sketches. -*/ - -#include "common_defs.hpp" -#include "py_serde.hpp" - -#include -#include -#include -#include - -namespace nb = nanobind; - -// Serialization -// std::string and arithmetic types, where we don't need a separate serde -template::value || std::is_same::value, bool>::type = 0> -void add_serialization(nb::class_& clazz) { - clazz.def( - "serialize", - [](const SK& sk) { - auto bytes = sk.serialize(); - return nb::bytes(reinterpret_cast(bytes.data()), bytes.size()); - }, - "Serializes the sketch into a bytes object." - ) - .def_static( - "deserialize", - [](const nb::bytes& bytes) { return SK::deserialize(bytes.c_str(), bytes.size()); }, - nb::arg("bytes"), - "Deserializes the sketch from a bytes object." - ); -} - -// nb::object and other types where the caller must provide a serde -template::value && !std::is_same::value, bool>::type = 0> -void add_serialization(nb::class_& clazz) { - clazz.def( - "serialize", - [](const SK& sk, datasketches::py_object_serde& serde) { - auto bytes = sk.serialize(0, serde); - return nb::bytes(reinterpret_cast(bytes.data()), bytes.size()); - }, nb::arg("serde"), - "Serializes the sketch into a bytes object using the provided serde." - ) - .def_static( - "deserialize", - [](const nb::bytes& bytes, datasketches::py_object_serde& serde) { - return SK::deserialize(bytes.c_str(), bytes.size(), serde); - }, nb::arg("bytes"), nb::arg("serde"), - "Deserializes the sketch from a bytes object using the provided serde." - ); -} - -// Vector Updates -// * Only allowed for POD types based on numpy restriction, which -// is equivalent to both std::is_trivial and std::is_standard_layout. -// * Nothing is added to types that are not PODs. -// POD type -template::value && std::is_standard_layout::value, bool>::type = 0> -void add_vector_update(nb::class_& clazz) { - clazz.def( - "update", - [](SK& sk, nb::ndarray items) { - if (items.ndim() != 1) { - throw std::invalid_argument("input data must have only one dimension. Found: " - + std::to_string(items.ndim())); - } - auto v = items.template view>(); - for (uint32_t i = 0; i < v.shape(0); ++i) sk.update(v(i)); - }, - nb::arg("array"), - "Updates the sketch with the values in the given array" - ); -} - -// non-POD type -template::value || !std::is_standard_layout::value, bool>::type = 0> -void add_vector_update(nb::class_& clazz) { - unused(clazz); -} - -#endif // _QUANTILE_CONDITIONAL_HPP_ \ No newline at end of file diff --git a/include/tuple_policy.hpp b/include/tuple_policy.hpp deleted file mode 100644 index bd70309f..00000000 --- a/include/tuple_policy.hpp +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#include -#include -#include -#include -#include - -#ifndef _TUPLE_POLICY_HPP_ -#define _TUPLE_POLICY_HPP_ - -namespace nb = nanobind; - -namespace datasketches { - -/** - * @brief tuple_policy provides the underlying base class from - * which native Python policies ultimately inherit. The actual - * policies implement TuplePolicy, as shown in TuplePolicy.py - */ -struct tuple_policy : public nb::intrusive_base { - virtual nb::object create_summary() const = 0; - virtual nb::object update_summary(nb::object& summary, const nb::object& update) const = 0; - virtual nb::object operator()(nb::object& summary, const nb::object& update) const = 0; - virtual ~tuple_policy() = default; -}; - -/** - * @brief TuplePolicy provides the "trampoline" class for nanobind - * that allows for a native Python implementation of tuple - * sketch policies. - */ -struct TuplePolicy : public tuple_policy { - NB_TRAMPOLINE(tuple_policy, 3); - - /** - * @brief Create a summary object - * - * @return nb::object representing a new summary - */ - nb::object create_summary() const override { - NB_OVERRIDE_PURE( - create_summary, // Name of function in C++ (must match Python name) - // Argument(s) -- if any - ); - } - - /** - * @brief Update a summary object using this policy - * - * @param summary The current summary to update - * @param update The new value with which to update the summary - * @return nb::object The updated summary - */ - nb::object update_summary(nb::object& summary, const nb::object& update) const override { - NB_OVERRIDE_PURE( - update_summary, // Name of function in C++ (must match Python name) - summary, update // Arguments - ); - } - - /** - * @brief Applies this policy to summary with the provided update - * - * @param summary The current summary on which to apply the policy - * @param update An update to apply to the current summary - * @return nb::object The potentially modified summary - */ - nb::object operator()(nb::object& summary, const nb::object& update) const override { - NB_OVERRIDE_PURE_NAME( - "__call__", // Name of function in python - operator(), // Name of function in C++ - summary, update // Arguments - ); - } -}; - -/* The tuple_policy_holder provides a concrete class that dispatches calls - * from the sketch to the tuple_policy. This class is needed to provide a - * concrete object to produce a compiled library, but library users should - * never need to use this directly. - */ -struct tuple_policy_holder { - explicit tuple_policy_holder(tuple_policy* policy) : _policy(policy) {} - tuple_policy_holder(const tuple_policy_holder& other) : _policy(other._policy) {} - tuple_policy_holder(tuple_policy_holder&& other) : _policy(std::move(other._policy)) {} - tuple_policy_holder& operator=(const tuple_policy_holder& other) { _policy = other._policy; return *this; } - tuple_policy_holder& operator=(tuple_policy_holder&& other) { std::swap(_policy, other._policy); return *this; } - - nb::object create() const { return _policy->create_summary(); } - - void update(nb::object& summary, const nb::object& update) const { - summary = _policy->update_summary(summary, update); - } - - void operator()(nb::object& summary, const nb::object& update) const { - summary = _policy->operator()(summary, update); - } - - private: - nb::ref _policy; -}; - -/* A degenerate policy used to enable Jaccard Similarity on tuple sketches, - * where the computation requires a union and intersection over the keys but - * does not need to observe the summaries. - */ -struct dummy_jaccard_policy { - void operator()(nb::object&, const nb::object&) const { - return; - } -}; - -} - -#endif // _TUPLE_POLICY_HPP_ \ No newline at end of file diff --git a/jupyter/CPCSketch.ipynb b/jupyter/CPCSketch.ipynb deleted file mode 100644 index cb14be97..00000000 --- a/jupyter/CPCSketch.ipynb +++ /dev/null @@ -1,345 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## CPC Sketch Examples" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Basic Sketch Usage" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "from datasketches import cpc_sketch, cpc_union" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We'll create a sketch with log2(k) = 12" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "sk = cpc_sketch(12)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Insert ~2 million points. Values are hashed, so using sequential integers is fine for demonstration purposes." - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "### CPC sketch summary:\n", - " lgK : 12\n", - " seed hash : 93cc\n", - " C : 38212\n", - " flavor : 4\n", - " merged : false\n", - " compressed : false\n", - " interesting col : 5\n", - " HIP estimate : 2.09721e+06\n", - " kxp : 11.4725\n", - " offset : 6\n", - " table : allocated\n", - " num SV : 135\n", - " window : allocated\n", - "### End sketch summary\n", - "\n" - ] - } - ], - "source": [ - "n = 1 << 21\n", - "for i in range(0, n):\n", - " sk.update(i)\n", - "print(sk)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Since we know the exact value of n we can look at the estimate and upper/lower bounds as a % of the true value. We'll look at the bounds at 1 standard deviation. In this case, the true value does lie within the bounds, but since these are probabilistic bounds the true value will sometimes be outside them (especially at 1 standard deviation)." - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Upper bound (1 std. dev) as % of true value: 100.9281\n" - ] - } - ], - "source": [ - "print(\"Upper bound (1 std. dev) as % of true value: \", round(100*sk.get_upper_bound(1) / n, 4))" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Estimate as % of true value: 100.0026\n" - ] - } - ], - "source": [ - "print(\"Estimate as % of true value: \", round(100*sk.get_estimate() / n, 4))" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Lower bound (1 std. dev) as % of true value: 99.0935\n" - ] - } - ], - "source": [ - "print(\"Lower bound (1 std. dev) as % of true value: \", round(100*sk.get_lower_bound(1) / n, 4))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Finally, we can serialize and deserialize the sketch, which will give us back the same structure." - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "2484" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sk_bytes = sk.serialize()\n", - "len(sk_bytes)" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "### CPC sketch summary:\n", - " lgK : 12\n", - " seed hash : 93cc\n", - " C : 38212\n", - " flavor : 4\n", - " merged : false\n", - " compressed : false\n", - " interesting col : 5\n", - " HIP estimate : 2.09721e+06\n", - " kxp : 11.4725\n", - " offset : 6\n", - " table : allocated\n", - " num SV : 135\n", - " window : allocated\n", - "### End sketch summary\n", - "\n" - ] - } - ], - "source": [ - "sk2 = cpc_sketch.deserialize(sk_bytes)\n", - "print(sk2)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Sketch Union Usage" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Here, we'll create two sketches with partial overlap in values. For good measure, we'll let k be larger in one sketch. For most applications we'd generally create all new data using the same size sketch, allowing differences to creep in when combining new and historica data." - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [], - "source": [ - "k = 12\n", - "n = 1 << 20\n", - "offset = int(3 * n / 4)" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [], - "source": [ - "sk1 = cpc_sketch(k)\n", - "sk2 = cpc_sketch(k + 1)\n", - "for i in range(0, n):\n", - " sk1.update(i)\n", - " sk2.update(i + offset)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Create a union object and add the sketches to that. To demonstrate smoothly handling multiple sketch sizes, we'll use a size of k+1 here." - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [], - "source": [ - "union = cpc_union(k+1)\n", - "union.update(sk1)\n", - "union.update(sk2)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Note how log config k has automatically adopted the value of the smaller input sketch." - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "### CPC sketch summary:\n", - " lgK : 12\n", - " seed hash : 93cc\n", - " C : 37418\n", - " flavor : 4\n", - " merged : true\n", - " compressed : false\n", - " interesting col : 5\n", - " HIP estimate : 0\n", - " kxp : 4096\n", - " offset : 6\n", - " table : allocated\n", - " num SV : 123\n", - " window : allocated\n", - "### End sketch summary\n", - "\n" - ] - } - ], - "source": [ - "result = union.get_result()\n", - "print(result)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can again compare against the exact result, in this case 1.75*n" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Estimate as % of true value: 99.6646\n" - ] - } - ], - "source": [ - "print(\"Estimate as % of true value: \", round(100*result.get_estimate() / (7*n/4), 4))" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.0" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/jupyter/FrequentItemsSketch.ipynb b/jupyter/FrequentItemsSketch.ipynb deleted file mode 100644 index 2f6ac900..00000000 --- a/jupyter/FrequentItemsSketch.ipynb +++ /dev/null @@ -1,354 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Frequent Items Sketch Examples" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Basic Sketch Usage" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "More so than other sketches in the library, the Frequent Items sketch can take some practice to use since it identifies exceptionally heavy hitters rather than returning a \"top N\" list. We assume readers have already familiarized themselves with the [sketch documentation](https://datasketches.github.io/docs/Frequency/FrequentItemsOverview.html) and are aware of the key concepts around use of this sketch." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "from datasketches import frequent_strings_sketch, frequent_items_error_type" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We'll use a very small sketch in this case so that we can easily fill it, otherwise the difference between error types is more difficult to demonstrate." - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "k = 3\n", - "fi = frequent_strings_sketch(k)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "A brief digression into implementation details to help explain what we're doing here. The Frequent Items sketch maintains a list of items, but purges the least frequent items when the list fills. For this example, we'll keep inserting items until after a purge takes place.\n", - "\n", - "We'll insert items with exponentially decreasing weights, which in this case gives us a more interesting set of results when we later query things." - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Update 1: 1 items\n", - "Update 2: 2 items\n", - "Update 3: 3 items\n", - "Update 4: 4 items\n", - "Update 5: 5 items\n", - "Update 6: 6 items\n", - "Update 7: 3 items\n", - "Update 8: 4 items\n" - ] - } - ], - "source": [ - "n = 8\n", - "for i in range(0,n):\n", - " fi.update(str(i), 2 ** (n-i))\n", - " i += 1\n", - " print('Update ' + str(i) + ': ' + str(fi.get_num_active_items()) + ' items')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can see where the purge happened, and in this case we inserted a low-weight item after the purge. We can now compare querying items to exclude either false positives or false negatives.\n", - " - `NO_FALSE_POSITIVES` returns all items with a _lower_ bound above the a posteriori error\n", - " - `NO_FALSE_NEGATIVES` returns all items with an _upper_ bound above the a posteriori error\n", - "\n", - "The latter option will always include any results from the first set and may include others. Items are returned as (id, estimate, lower_bound, upper_bound) and are sorted by decreasing weight." - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[('0', 256, 224, 256), ('1', 128, 96, 128)]" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "fi.get_frequent_items(frequent_items_error_type.NO_FALSE_POSITIVES)" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[('0', 256, 224, 256),\n", - " ('1', 128, 96, 128),\n", - " ('2', 64, 32, 64),\n", - " ('7', 34, 2, 34)]" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "fi.get_frequent_items(frequent_items_error_type.NO_FALSE_NEGATIVES)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The sketch also allows us to query for individual items directly." - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "256\n", - "64\n", - "2\n" - ] - } - ], - "source": [ - "print(fi.get_estimate(\"0\"))\n", - "print(fi.get_upper_bound(\"2\"))\n", - "print(fi.get_lower_bound(\"7\"))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can also query for items not in the the list, whether the item has never been seen or if it has been evicted from the active set." - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "fi.get_estimate(\"5\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The sketch may also be serialized for archiving, and reconstructed." - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "84" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sk_bytes = fi.serialize()\n", - "len(sk_bytes)" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "### Frequent items sketch summary:\n", - " lg cur map size : 3\n", - " lg max map size : 3\n", - " num active items : 4\n", - " total weight : 510\n", - " max error : 32\n", - "### End sketch summary\n", - "\n" - ] - } - ], - "source": [ - "fi2 = frequent_strings_sketch.deserialize(sk_bytes)\n", - "print(fi2)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Merging Example" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Frequent Items sketches support `merge()` to combine sketches. Keep in mind that the combined sketches may not have any meaningfully frequent items, even if there were frequent items in one of the input sketches.\n", - "\n", - "We'll start by creating a sketch with lots of equally-weighted very light items, but with a combined weight several times greater than that of the first sketch, and then merge that into the first sketch." - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [], - "source": [ - "fi2 = frequent_strings_sketch(k)\n", - "wt = fi.get_total_weight()\n", - "for i in range(0,4*wt):\n", - " fi2.update(str(i))\n", - "fi.merge(fi2)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Even though all these new items have weight 1, there are so many of them that we have nothing if we ask for no false positives." - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "len(fi.get_frequent_items(frequent_items_error_type.NO_FALSE_POSITIVES))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We do, however, see a few potentially heavy items if we request no false negatives." - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "3" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "len(fi.get_frequent_items(frequent_items_error_type.NO_FALSE_NEGATIVES))" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.0" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/jupyter/HLLSketch.ipynb b/jupyter/HLLSketch.ipynb deleted file mode 100644 index 93332ce8..00000000 --- a/jupyter/HLLSketch.ipynb +++ /dev/null @@ -1,346 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## HLL Sketch Examples" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Basic Sketch Usage" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "from datasketches import hll_sketch, hll_union, tgt_hll_type" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We'll create a sketch with log2(k) = 12" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "sk = hll_sketch(12)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Insert ~2 million points. Values are hashed, so using sequential integers is fine for demonstration purposes." - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "### HLL SKETCH SUMMARY: \n", - " Log Config K : 12\n", - " Hll Target : HLL_4\n", - " Current Mode : HLL\n", - " LB : 2.06958e+06\n", - " Estimate : 2.09635e+06\n", - " UB : 2.12379e+06\n", - " OutOfOrder flag: 0\n", - " CurMin : 7\n", - " NumAtCurMin : 72\n", - " HipAccum : 2.09635e+06\n", - " KxQ0 : 5.80703\n", - " KxQ1 : 0\n", - "\n" - ] - } - ], - "source": [ - "n = 1 << 21\n", - "for i in range(0, n):\n", - " sk.update(i)\n", - "print(sk)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Since we know the exact value of n we can look at the estimate and upper/lower bounds as a % of the true value. We'll look at the bounds at 1 standard deviation. In this case, the true value does lie within the bounds, but since these are probabilistic bounds the true value will sometimes be outside them (especially at 1 standard deviation)." - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Upper bound (1 std. dev) as % of true value: 101.2703\n" - ] - } - ], - "source": [ - "print(\"Upper bound (1 std. dev) as % of true value: \", round(100*sk.get_upper_bound(1) / n, 4))" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Estimate as % of true value: 99.9618\n" - ] - } - ], - "source": [ - "print(\"Estimate as % of true value: \", round(100*sk.get_estimate() / n, 4))" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Lower bound (1 std. dev) as % of true value: 98.6852\n" - ] - } - ], - "source": [ - "print(\"Lower bound (1 std. dev) as % of true value: \", round(100*sk.get_lower_bound(1) / n, 4))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Finally, we can serialize and deserialize the sketch, which will give us back the same structure." - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "2096" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sk_bytes = sk.serialize_compact()\n", - "len(sk_bytes)" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "### HLL SKETCH SUMMARY: \n", - " Log Config K : 12\n", - " Hll Target : HLL_4\n", - " Current Mode : HLL\n", - " LB : 2.06958e+06\n", - " Estimate : 2.09635e+06\n", - " UB : 2.12379e+06\n", - " OutOfOrder flag: 0\n", - " CurMin : 7\n", - " NumAtCurMin : 72\n", - " HipAccum : 2.09635e+06\n", - " KxQ0 : 5.80703\n", - " KxQ1 : 0\n", - "\n" - ] - } - ], - "source": [ - "sk2 = hll_sketch.deserialize(sk_bytes)\n", - "print(sk2)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Sketch Union Usage" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Here, we'll create two sketches with partial overlap in values. For good measure, we'll let k be larger in one sketch. For most applications we'd generally create all new data using the same size sketch, allowing differences to creep in when combining new and historica data." - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [], - "source": [ - "k = 12\n", - "n = 1 << 20\n", - "offset = int(3 * n / 4)" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [], - "source": [ - "sk1 = hll_sketch(k)\n", - "sk2 = hll_sketch(k + 1)\n", - "for i in range(0, n):\n", - " sk1.update(i)\n", - " sk2.update(i + offset)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Create a union object and add the sketches to that. To demonstrate smoothly handling multiple sketch sizes, we'll use a size of k+1 here." - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [], - "source": [ - "union = hll_union(k+1)\n", - "union.update(sk1)\n", - "union.update(sk2)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Note how log config k has automatically adopted the value of the smaller input sketch." - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "### HLL SKETCH SUMMARY: \n", - " Log Config K : 12\n", - " Hll Target : HLL_4\n", - " Current Mode : HLL\n", - " LB : 1.80197e+06\n", - " Estimate : 1.83108e+06\n", - " UB : 1.86121e+06\n", - " OutOfOrder flag: 1\n", - " CurMin : 6\n", - " NumAtCurMin : 2\n", - " HipAccum : 1.76932e+06\n", - " KxQ0 : 6.60752\n", - " KxQ1 : 0\n", - "\n" - ] - } - ], - "source": [ - "result = union.get_result()\n", - "print(result)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can again compare against the exact result, in this case 1.75*n" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Estimate as % of true value: 99.7859\n" - ] - } - ], - "source": [ - "print(\"Estimate as % of true value: \", round(100*result.get_estimate() / (7*n/4), 4))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.0" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/jupyter/KLLSketch.ipynb b/jupyter/KLLSketch.ipynb deleted file mode 100644 index 07b58607..00000000 --- a/jupyter/KLLSketch.ipynb +++ /dev/null @@ -1,463 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## KLL Sketch Examples" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Basic Sketch Usage" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "from datasketches import kll_floats_sketch, kll_ints_sketch" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Options are a `kll_floats_sketch` or `kll_ints_sketch`. We'll use the former so we can draw samples from a Gaussian distribution. We start by creating a sketch with $k=200$, which gives a normalized rank error of about 1.65%, and feeding in 1 million points." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "n = 1000000\n", - "kll = kll_floats_sketch(200)\n", - "from numpy.random import randn\n", - "for i in range(0, n):\n", - " kll.update(randn()) " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Since the data is distributed as $\\cal{N}(0,1)$, 0.0 should be near the median rank (0.5)" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0.497608" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "kll.get_rank(0.0)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "And the median should also be near 0.0" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0.003108405973762274" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "kll.get_quantile(0.5)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We track the min and max values as well. They are stored separately from the quantile data so we can always determine the full _empirical_ data range. In this case they should be very roughly symmetric around 0.0. We can query these values explicitly, or implicitly by asking for the values at ranks 0.0 and 1.0." - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[-4.6000142097473145, 4.779754638671875]" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "[kll.get_min_value(), kll.get_max_value()]" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[-4.6000142097473145, 4.779754638671875]" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "kll.get_quantiles([0.0, 1.0])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "And out of curiosity, we can check how many items the sketch has seen and how many it is retaining" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "1000000" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "kll.get_n()" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "614" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "kll.get_num_retained()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Finally, we can serialize the sketch for archiving, and reconstruct it later. Note that the serialized image does _not_ contain information on whether it is a floats or ints sketch." - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "2536" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sk_bytes = kll.serialize()\n", - "len(sk_bytes)" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "### KLL sketch summary:\n", - " K : 200\n", - " min K : 200\n", - " M : 8\n", - " N : 1000000\n", - " Epsilon : 1.33%\n", - " Epsilon PMF : 1.65%\n", - " Empty : false\n", - " Estimation mode: true\n", - " Levels : 13\n", - " Sorted : true\n", - " Capacity items : 617\n", - " Retained items : 614\n", - " Storage bytes : 2536\n", - " Min value : -4.6\n", - " Max value : 4.78\n", - "### End sketch summary\n", - "\n" - ] - } - ], - "source": [ - "kll2 = kll_floats_sketch.deserialize(sk_bytes)\n", - "print(kll2)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Merging Sketches" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "KLL sketches have a `merge()` operation to combine sketches. The resulting sketch will have no worse error bounds than if the full data had been sent to a single sketch." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Our previous sketch used $\\cal{N}(0,1)$, so now we'll generate a shifted Gaussian distributed as $\\cal{N}(4,1)$. For added variety, we can use half as many points. The next section will generate a plot, so we will defer queries of the merged skech to that section." - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [], - "source": [ - "sk2 = kll_floats_sketch(200)\n", - "for i in range(0, int(n/2)):\n", - " sk2.update(4 + randn())" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "### KLL sketch summary:\n", - " K : 200\n", - " min K : 200\n", - " M : 8\n", - " N : 1500000\n", - " Epsilon : 1.33%\n", - " Epsilon PMF : 1.65%\n", - " Empty : false\n", - " Estimation mode: true\n", - " Levels : 13\n", - " Sorted : false\n", - " Capacity items : 617\n", - " Retained items : 580\n", - " Storage bytes : 2400\n", - " Min value : -4.6\n", - " Max value : 9.06\n", - "### End sketch summary\n", - "\n" - ] - } - ], - "source": [ - "kll.merge(sk2)\n", - "print(kll)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Generating Histograms" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The KLL sketch allows us compute histograms via the probability mass function (pmf). Since histograms are a typical plot type when visualizing data distributions, we will create such a figure. To instead create a cumulative distribution function (cdf) from the sketch, simply replace the call to `get_pmf()` with `get_cdf()`." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We want our x-axis to have evenly distributed bins, so the first step is to split the empirical data range\n", - "into a set of bins." - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [], - "source": [ - "xmin = kll.get_min_value()\n", - "num_splits = 30\n", - "step = (kll.get_max_value() - xmin) / num_splits\n", - "splits = [xmin + (i*step) for i in range(0, num_splits)]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "`get_pmf()` returns the probability mass in the range $(x_{i-1}, x_i]$, for each bin $i$. If we use the minimum value for $x_{i-1}$ this covers the low end, but `get_pmf()` also returns an extra bin with all mass greater than the last-provided split point. As a result, the pmf array is 1 larger than the list of split points. We need to be sure to append a value to the split points for plotting." - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [], - "source": [ - "pmf = kll.get_pmf(splits)\n", - "x = splits # this will hold the x-axis values, so need to append the max value\n", - "x.append(kll.get_max_value())" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We need some plotting-related imports and options" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [], - "source": [ - "import seaborn as sns\n", - "import matplotlib.pyplot as plt\n", - "%matplotlib inline\n", - "sns.set(color_codes=True)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Using a negative width in the plot gives right-aligned bins, which matches the bin definition noted earlier." - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "plt.bar(x=x,height=pmf,align='edge',width=-0.43)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The leftmost peak came from the first sketch, with data centered around 0.0. The smaller, rightmost peak came from our second sketch, which had half as many samples and was centered around 4.0. The KLL sketch captures the shape of the combiend distribution." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.0" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/jupyter/ThetaSketchNotebook.ipynb b/jupyter/ThetaSketchNotebook.ipynb deleted file mode 100644 index 11f58cf4..00000000 --- a/jupyter/ThetaSketchNotebook.ipynb +++ /dev/null @@ -1,403 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Theta Sketch Examples" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Basic Sketch Usage" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "from datasketches import theta_sketch, update_theta_sketch, compact_theta_sketch\n", - "from datasketches import theta_union, theta_intersection, theta_a_not_b" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "To start, we'll create a sketch with 1 million points in order to demonstrate basic sketch operations." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "### Theta sketch summary:\n", - " num retained entries : 6560\n", - " seed hash : 37836\n", - " empty? : false\n", - " ordered? : false\n", - " estimation mode? : true\n", - " theta (fraction) : 0.00654224\n", - " theta (raw 64-bit) : 60341508738660257\n", - " estimate : 1.00271e+06\n", - " lower bound 95% conf : 978261\n", - " upper bound 95% conf : 1.02778e+06\n", - " lg nominal size : 12\n", - " lg current size : 13\n", - " resize factor : 8\n", - "### End sketch summary\n", - "\n" - ] - } - ], - "source": [ - "n = 1000000\n", - "k = 12\n", - "sk1 = update_theta_sketch(k)\n", - "for i in range(0, n):\n", - " sk1.update(i)\n", - "print(sk1)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The summary contains most data of interest, but we can also query for specific information. And in this case, since we know the exact number of distinct items presented to the sketch, we can look at the estimate, upper, and lower bounds as a percentage of the exact value." - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Upper bound (1 std. dev) as % of true value:\t 101.5208\n", - "Sketch estimate as % of true value:\t\t 100.2715\n", - "Lower bound (1 std. dev) as % of true value:\t 99.0374\n" - ] - } - ], - "source": [ - "print(\"Upper bound (1 std. dev) as % of true value:\\t\", round(100*sk1.get_upper_bound(1) / n, 4))\n", - "print(\"Sketch estimate as % of true value:\\t\\t\", round(100*sk1.get_estimate() / n, 4))\n", - "print(\"Lower bound (1 std. dev) as % of true value:\\t\", round(100*sk1.get_lower_bound(1) / n, 4))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can serialize and reconstruct the sketch. Serialization necessarily produces a compact sketch, meaning the sketch can be deserialized and queried or used for further unions or set operations but can not be updated directly." - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "52504" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sk1_bytes = sk1.compact().serialize()\n", - "len(sk1_bytes)" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Estimate: \t\t 1002714.745231455\n", - "Estimation mode: \t True\n" - ] - } - ], - "source": [ - "new_sk1 = compact_theta_sketch.deserialize(sk1_bytes)\n", - "print(\"Estimate: \\t\\t\", new_sk1.get_estimate())\n", - "print(\"Estimation mode: \\t\", new_sk1.is_estimation_mode())" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Sketch Unions" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Theta Sketch unions make use of a separate union object. The union will accept input sketches with different values of $k$.\n", - "\n", - "For this example, we will create a sketch with distinct values that partially overlap those in `sk1`." - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "### Theta sketch summary:\n", - " num retained entries : 12488\n", - " seed hash : 37836\n", - " empty? : false\n", - " ordered? : false\n", - " estimation mode? : true\n", - " theta (fraction) : 0.0123336\n", - " theta (raw 64-bit) : 113757656857900725\n", - " estimate : 1.01252e+06\n", - " lower bound 95% conf : 994626\n", - " upper bound 95% conf : 1.03073e+06\n", - " lg nominal size : 13\n", - " lg current size : 14\n", - " resize factor : 8\n", - "### End sketch summary\n", - "\n" - ] - } - ], - "source": [ - "offset = int(3 * n / 4)\n", - "sk2 = update_theta_sketch(k+1)\n", - "for i in range(0, n):\n", - " sk2.update(i + offset)\n", - "print(sk2)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can now feed the sketches into the union. As constructed, the exact number of unique values presented to the two sketches is $\\frac{7}{4}n$." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Union estimate as % of true value: 99.6787\n" - ] - } - ], - "source": [ - "union = theta_union(k)\n", - "union.update(sk1)\n", - "union.update(sk2)\n", - "result = union.get_result()\n", - "print(\"Union estimate as % of true value: \", round(100*result.get_estimate()/(1.75*n), 4))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Sketch Intersections" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Beyond unions, theta sketches also support intersctions through the use of an intersection object. These set intersections can have vastly superior error bounds than the classic inclusion-exclusion rule used with sketches like HLL." - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Has result: True\n", - "### Theta sketch summary:\n", - " num retained entries : 1668\n", - " seed hash : 37836\n", - " empty? : false\n", - " ordered? : true\n", - " estimation mode? : true\n", - " theta (fraction) : 0.00654224\n", - " theta (raw 64-bit) : 60341508738660257\n", - " estimate : 254959\n", - " lower bound 95% conf : 242739\n", - " upper bound 95% conf : 267789\n", - "### End sketch summary\n", - "\n" - ] - } - ], - "source": [ - "intersection = theta_intersection()\n", - "intersection.update(sk1)\n", - "intersection.update(sk2)\n", - "print(\"Has result: \", intersection.has_result())\n", - "result = intersection.get_result()\n", - "print(result)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In this case, we expect the sets to have an overlap of $\\frac{1}{4}n$." - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Intersection estimate as % of true value: 101.9834\n" - ] - } - ], - "source": [ - "print(\"Intersection estimate as % of true value: \", round(100*result.get_estimate()/(0.25*n), 4))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Set Subtraction (A-not-B)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Finally, we have the set subtraction operation. Unlike `theta_union` and `theta_intersection`, `theta_a_not_b` always takes as input 2 sketches at a time, namely $a$ and $b$, and directly returns the result as a sketch." - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "### Theta sketch summary:\n", - " num retained entries : 4892\n", - " seed hash : 37836\n", - " empty? : false\n", - " ordered? : true\n", - " estimation mode? : true\n", - " theta (fraction) : 0.00654224\n", - " theta (raw 64-bit) : 60341508738660257\n", - " estimate : 747756\n", - " lower bound 95% conf : 726670\n", - " upper bound 95% conf : 769452\n", - "### End sketch summary\n", - "\n" - ] - } - ], - "source": [ - "anb = theta_a_not_b()\n", - "result = anb.compute(sk1, sk2)\n", - "print(result)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "By using the same two sketches as before, the expected result here is $\\frac{3}{4}n$." - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "A-not-B estimate as % of true value: 99.7008\n" - ] - } - ], - "source": [ - "print(\"A-not-B estimate as % of true value: \", round(100*result.get_estimate()/(0.75*n), 4))" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3.10.6 64-bit", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.6" - }, - "vscode": { - "interpreter": { - "hash": "b0fa6594d8f4cbf19f97940f81e996739fb7646882a419484c72d19e05852a7e" - } - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/jupyter/comparison-to-datasketch/README.md b/jupyter/comparison-to-datasketch/README.md deleted file mode 100644 index ed03e618..00000000 --- a/jupyter/comparison-to-datasketch/README.md +++ /dev/null @@ -1,37 +0,0 @@ -# A Comparison of Python Sketching Libraries - -These notebooks aim to provide a fair comparison between the Python support for -[Apache Software Foundation (ASF) DataSketches](https://pypi.org/project/datasketches/) and the [datasketch](https://pypi.org/project/datasketch/) -library. -The notebooks are not an attempt to fully characterize either library's implementation, rather to highlight differences that manifest as a result -of design choices for each library. - -## Summary - -As of the time of writing, November 2023, the versions under comparison are: -``` -Name: datasketches -Version: 4.1.0 - -Name: datasketch -Version: 1.6.4 -``` - -## 1. Distinct Counting - -### 1a. HyperLogLog -Each library implements various algorithms that fall under the HyperLogLog umbrella. -They can be summarized as follows - -| | ASF | datasketch | | -|-----------------------|--------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------|-----------------------------------------------------------------------------------------------------------| -| | HyperLogLog | HyperLogLog | HyperLogLog++ | -| Hash functions | 64 bit MurmurHash | SHA1 32 bit. Others are possible. | SHA1 64 bit. Others are possible. | -| Bucket sizes (bits) | 4, 6, 8 | 4 | 8 | -| Estimator | Exact mode for small cardinalities Historic Inverse Probability (HIP) for a single sketch; Harmonic mean after merging multiple sketches | No exact mode. Harmonic mean for all sketches | Harmonic mean for all sketches (single or merged) with bias corrections at small and large cardinalities | - - -Since `datasketch.hyperloglog.HyperLogLog` uses only $32$ bit hash functions, we do not regard this as an appropriate solution for -industry-applications because the error estimates will vary wildly when the input is large enough. -To ensure the fairest comparison between the sketches, we will only compare the ASF implementations with `datasketch.hyperloglog.HyperLogLogPlusPlus` -with the MurmurHash function over $64$ bits using `mmh3.hash64(x, signed=False)[0]`. \ No newline at end of file diff --git a/jupyter/comparison-to-datasketch/api-differences.ipynb b/jupyter/comparison-to-datasketch/api-differences.ipynb deleted file mode 100644 index dcd2a04b..00000000 --- a/jupyter/comparison-to-datasketch/api-differences.ipynb +++ /dev/null @@ -1,200 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "46ea1d79-8904-4ca0-9f40-2b8b11baa9f7", - "metadata": {}, - "source": [ - "# API Differences between the libraries\n", - "\n", - "We outline the key API differences between the libraries that users should be aware of when using sketches. The Apache DataSketches are designed to have, as far as possible, a consistent API. Therefore, although only the following examples are provided here, they roughly map on to all other sketches provided." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "9fba04a9-c359-40ad-937b-ff25103ddf56", - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import datasketches as asf\n", - "import datasketch as ds\n", - "import mmh3" - ] - }, - { - "cell_type": "markdown", - "id": "5168ce81-9a7f-4889-878c-c6285e1bf580", - "metadata": {}, - "source": [ - "1. The `update()` method for `asf.hll_sketch` accepts inputs as integers, strings, bytes, and floats. On the other hand, `datasketch.HyperLogLogPlusPlus` only accepts byte and string type inputs." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "4e410c91-b156-4c91-9d85-fe1695c6492e", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "4.000000029802323" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Datasketches HLL can accept multiple inputs\n", - "# These are treated as different items in a single sketch.\n", - "asf_hll_types = asf.hll_sketch(14, asf.HLL_8)\n", - "asf_hll_types.update(1)\n", - "asf_hll_types.update(1.0)\n", - "asf_hll_types.update(str(1))\n", - "\n", - "xx = 1\n", - "xx_bytes = xx.to_bytes(64, \"little\")\n", - "asf_hll_types.update(xx_bytes)\n", - "\n", - "asf_hll_types.get_estimate()" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "ac159800-f984-40b5-9a1d-f26213f7ce49", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Exception on integer input\n", - "Exception on float input\n", - "Accepts bytes input\n", - "Accepts string input\n", - "2.000122080247517\n" - ] - } - ], - "source": [ - "# datasketch HLL needs bytes\n", - "dhll_type = ds.HyperLogLogPlusPlus(14, hashfunc=lambda x: mmh3.hash64(x, signed=False)[0])\n", - "try:\n", - " dhll_type.update(1)\n", - "except:\n", - " print(\"Exception on integer input\")\n", - " \n", - "try:\n", - " dhll_type.update(1.0)\n", - "except:\n", - " print(\"Exception on float input\")\n", - " \n", - "try:\n", - " dhll_type.update(xx_bytes)\n", - " print(\"Accepts bytes input\")\n", - "except:\n", - " print(\"Exception on string input\")\n", - " \n", - "try:\n", - " dhll_type.update(str(1))\n", - " print(\"Accepts string input\")\n", - "except:\n", - " print(\"Exception on string input\")\n", - " \n", - "print(dhll_type.count()) # only two distinct items inserted into the sketch." - ] - }, - { - "cell_type": "markdown", - "id": "5cfe6a15-a932-4351-aa34-ddf99ebc2e39", - "metadata": {}, - "source": [ - "2. The ASF HLL implementation comes with `get_upper_bound()` and `get_lower_bound()` functions. These enable the user to understand with what confidence. On the other hand, the `datasketch` implementation returns only the estimated count.\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "id": "7e6e81d4-4aa4-4692-82ae-e1b9209a9896", - "metadata": {}, - "outputs": [], - "source": [ - "a_hll = asf.hll_sketch(14, asf.HLL_8)\n", - "d_hll = ds.HyperLogLogPlusPlus(14, hashfunc=lambda x: mmh3.hash64(x, signed=False)[0])\n", - "\n", - "n = 1<<15\n", - "for x in range(n):\n", - " a_hll.update(x)\n", - " d_hll.update(str(x))" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "id": "6a01bf67-a885-4bfc-a9ed-69a728af55f1", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Lower bound (1 std. dev) as % of true value: 99.5952\n", - "ASF HyperLogLog estimate as % of true value: 100.2430\n", - "Upper bound (1 std. dev) as % of true value: 100.8992\n" - ] - } - ], - "source": [ - "#asf_hll_sketch = all_asf_hll[0] \n", - "print(f\"Lower bound (1 std. dev) as % of true value: {(100*a_hll.get_lower_bound(1) / n):.4f}\")\n", - "print(f\"ASF HyperLogLog estimate as % of true value: {(100*a_hll.get_estimate() / n):.4f}\")\n", - "print(f\"Upper bound (1 std. dev) as % of true value: {(100*a_hll.get_upper_bound(1) / n):.4f}\")\n" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "id": "bcd01928-30ca-4d82-8fb4-b704ba0498da", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "datasketch HyperLogLog estimate as % of true value: 100.6836\n" - ] - } - ], - "source": [ - "print(f\"datasketch HyperLogLog estimate as % of true value: {(100*d_hll.count() / n):.4f}\")" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.11.4" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/jupyter/comparison-to-datasketch/cardinality_error_experiment.py b/jupyter/comparison-to-datasketch/cardinality_error_experiment.py deleted file mode 100644 index 114d49c9..00000000 --- a/jupyter/comparison-to-datasketch/cardinality_error_experiment.py +++ /dev/null @@ -1,172 +0,0 @@ -#!/usr/bin/env python - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -import sys -import argparse -from datetime import datetime -import pandas as pd -import numpy as np -from utils import distinct_number_sequence -import datasketches as ds -import datasketch as d -import mmh3 -import os -import matplotlib.pyplot as plt - -class ErrorCardinalityProfile: - """Generates an experiment comparing the error over different cardinalities""" - def __init__(self, sketch_lgk:int, lg_trials:int, max_lgN:int): - self.sketch_lgk = sketch_lgk - self.num_trials = 2**lg_trials - self.max_lgN = max_lgN - self.max_num_distincts = np.uint64(2 ** self.max_lgN) - self.directory_name = "hll_accuracy_profile_" + datetime.today().strftime('%Y%m%d') - if not os.path.exists(self.directory_name): - os.mkdir(self.directory_name) - self.file_extension = "_" + datetime.today().strftime('%H%M') + f"lgK_{self.sketch_lgk}_lgT_{lg_trials}" - - # Need to remove repeated items for the program logic in self.run() - self.plot_points = self._generate_plot_points() - self.plot_points.extend(self._generate_plot_points()) - self.plot_points = list(set(self.plot_points)) - self.plot_points.sort() - print(self.plot_points) - - # Initialise the data structures for results - self.DataSketches_results_arr = np.zeros((len(self.plot_points), self.num_trials), dtype=float) - self.datasketch_results_arr = np.zeros_like(self.DataSketches_results_arr) - self.DataSketches_results_df = pd.DataFrame(index=self.plot_points, columns=None) - self.datasketch_results_df = pd.DataFrame(index=self.plot_points, columns=None) - self.data = np.random.randn(len(self.plot_points), self.num_trials) - print("Data shape: ", self.data.shape) - - def _generate_plot_points(self) -> list: - """ - Generates the standard sequence defining the input cardinalites for the experiment - This is just two points at each power of 2 - """ - all_plot_points = [] - for lgk in range(1, self.max_lgN+1): - points = np.unique(np.logspace(start=lgk, stop=lgk+1, num=8, endpoint=False, base=2, dtype=np.uint64)) - all_plot_points.extend(points) - all_plot_points.sort() - return all_plot_points - - def _bad_hll_range(self) -> list: - """Generates 16 logspaced points in the n ≈ 2.5k range.""" - log2_sketch_threshold = np.log2(2.5* (2**self.sketch_lgk)) - start = np.floor(log2_sketch_threshold).astype(np.uint64) - stop = np.ceil(log2_sketch_threshold).astype(np.uint64)+1 - points = np.logspace(start, stop, num=50, endpoint=False, base=2, dtype=np.uint64)[1:] - return points - - def _is_power_of_two(self, a): - """Bitwise operations to check value a is a power of two""" - return (a & (a-1) == 0) and a != 0 - - def _results_to_df(self, start_:int, end_:int, arr:np.array, df:pd.DataFrame): - """Concatenates the array between columns start_,...end_ - 1 to the dataframe""" - new_df = pd.DataFrame(arr[:, start_:end_], index=df.index, columns=np.arange(start_, end_).tolist()) - print("concatenating: ", new_df) - concat_df = pd.concat([df, new_df], axis=1) - return concat_df - - def run(self): - """Runs the experiment""" - seq_start = np.uint64(2345234) - distinct_number = np.uint64(3462) - previous_log_trial_index = 0 - ds_all_results = np.zeros((self.num_trials, len(self.plot_points))) - d_all_results = np.zeros_like(ds_all_results) - - for trial in range(1, self.num_trials+1): - #print(f"Trial = {trial}\t{self._is_power_of_two(trial)}") - # Initialise the sketches - hll = ds.hll_sketch(self.sketch_lgk, ds.HLL_8) - h = d.HyperLogLogPlusPlus(p=self.sketch_lgk, hashfunc=lambda x: mmh3.hash64(x, signed=False)[0]) - plot_point_index = 0 # Return to the start of the plot points list to generate the data - plot_point_value = self.plot_points[plot_point_index] - total_updates = 0 - seq_start += distinct_number # Start a new input sequence - - # Temporary result data structure - ds_results = np.zeros((len(self.plot_points),)) - d_results = np.zeros_like(ds_results) - - - for new_number in distinct_number_sequence(seq_start): - hll.update(new_number) - h.update(str(new_number).encode('utf8')) - total_updates += 1 - #print(f"Trial: {trial:<5} updates: {total_updates:<5}Index: {plot_point_index:<5} Value: {plot_point_value:<5}\n") - if total_updates == plot_point_value: - ds_results[plot_point_index] = (hll.get_estimate() - plot_point_value) / plot_point_value - d_results[plot_point_index] = (h.count() - plot_point_value) / plot_point_value - plot_point_index += 1 - #print(f"PPI:{plot_point_index:<3}PPV:{plot_point_value}") - - if plot_point_index < len(self.plot_points): - plot_point_value = self.plot_points[plot_point_index] - else: - #print("Already at the end") - break - - # After the break statement, control returns here. Now need to decide whether to write or continue. - ds_all_results[trial-1, :] = ds_results # subtract 1 as we use 1-based indexing for the trial count. - d_all_results[trial - 1, :] = d_results # subtract 1 as we use 1-based indexing for the trial count. - if self._is_power_of_two(trial) and trial > 1: - # write the array only a logarithmic number of times - temporary_ds_results = ds_all_results[0:trial, : ] - temporary_d_results = d_all_results[0:trial, :] - print(f"#################### PARTIAL RESULTS FOR {trial} TRIALS: DATASKETCHES ####################") - previous_log_trial_index = trial - self.DataSketches_results_df = pd.DataFrame(temporary_ds_results.T, index=self.DataSketches_results_df.index, columns=np.arange(trial).tolist()) - self.DataSketches_results_df.to_csv( - self.directory_name + "/DataSketches_hll" + self.file_extension + f"trials_{trial}.csv", - index_label="n") - self.datasketch_results_df = pd.DataFrame(temporary_d_results.T, - index=self.datasketch_results_df.index, - columns=np.arange(trial).tolist()) - self.datasketch_results_df.to_csv( - self.directory_name + "/datasketch_hll" + self.file_extension + f"trials_{trial}.csv", - index_label="n" - ) - print(self.DataSketches_results_df) - - print(f"#################### PARTIAL RESULTS FOR {trial} TRIALS: datasketch ####################") - print(self.datasketch_results_df) - - -def main(argv): - assert len(argv) == 3 - SKETCH_LGK = argv['lgk'] - LG_TRIALS = argv['lgt'] - MAX_LG_N = argv['lgN'] # FOR SETTING NUMBER OF DISTINCTS - experiment = ErrorCardinalityProfile(SKETCH_LGK, LG_TRIALS, MAX_LG_N) - experiment.run() - - - -if __name__ == "__main__": - parser = argparse.ArgumentParser(description='Error-cardinality profile of HyperLogLog') - parser.add_argument('-lgk', '--lgk', help='Log2(k) value for the number of buckets in the sketch.',type=int, required=True) - parser.add_argument('-lgt', '--lgt', help='Log2(T) value for number of trials t.',type=int, required=True) - parser.add_argument('-lgN', '--lgN', help='Largest permissible log2(.) value for input size.',type=int, required=True) - args = vars(parser.parse_args()) - main(args) diff --git a/jupyter/comparison-to-datasketch/single-sketch-accuracy.ipynb b/jupyter/comparison-to-datasketch/single-sketch-accuracy.ipynb deleted file mode 100644 index b752c7f5..00000000 --- a/jupyter/comparison-to-datasketch/single-sketch-accuracy.ipynb +++ /dev/null @@ -1,762 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "b0bac2b9-77d1-435d-bd66-93c986ccddb6", - "metadata": {}, - "source": [ - "# Single Sketch Error: ASF DataSketches vs datasketch\n", - "\n", - "We compare implementations of the HyperLogLog algorithm from the [Apache Software Foundation DataSketches](https://github.com/apache/datasketches-cpp/tree/master/python) library and the open-source python [datasketch](https://github.com/ekzhu/datasketch). Both libraries present python implementations or bindings for common \"sketching\" algorithms.\n", - "In the writing we abbreviate the two implementations as `ASF:HLL` for the ASF DataSketches \n", - "and `datasketch:HLL` for the other implementation.\n", - "\n", - "This notebook needs easily available libraries that are available on PyPi." - ] - }, - { - "cell_type": "code", - "execution_count": 35, - "id": "66bf431c-04bd-412b-8930-3741560ba0a7", - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "import matplotlib.pyplot as plt\n", - "%matplotlib inline\n", - "import numpy as np\n", - "import datasketches as asf\n", - "import datasketch as ds\n", - "import mmh3" - ] - }, - { - "cell_type": "code", - "execution_count": 36, - "id": "3d43ab6d-1774-4a37-a91b-817fb498c5a0", - "metadata": {}, - "outputs": [], - "source": [ - "# Plotting parameters\n", - "method_plot_params = {\n", - " \"asf\" : {\"color\": \"C0\", \"marker\": '.'},\n", - " \"datasketch\" : {\"color\": \"C1\", \"marker\": \"^\"}\n", - "}\n", - "asf_color = method_plot_params[\"asf\"][\"color\"]\n", - "ds__color = method_plot_params[\"datasketch\"][\"color\"]\n", - "q90_ls = \"--\"\n", - "\n", - "params = {'legend.fontsize': 'x-large',\n", - " 'axes.labelsize': 'x-large',\n", - " 'axes.titlesize':'x-large',\n", - " 'xtick.labelsize':'x-large',\n", - " 'ytick.labelsize':'x-large',\n", - " \"lines.linewidth\": 2.5}\n", - "plt.rcParams.update(params)" - ] - }, - { - "cell_type": "markdown", - "id": "a1f86685-363c-44f9-888a-6f3d4a6459cf", - "metadata": {}, - "source": [ - "### 1. Error vs Cardinality \n", - "We study the error behaviour as the input cardinality increases. We provide an initial comparison to highlight the differences in the estimators.\n", - "These plots are crucial to understanding error distributions of sketches.\n", - "\n", - "To generate the synthetic data, we use \"Fibonacci Hashing\" as a cheap way to generate a pseudorandom sequence. This process starts with an initial selection of a $64$-bit integer. Then, for every new item that must be generated, we add the full $64$ bit range scaled by the integer golden ratio so that every other update _intentionally_ overflows and maps once more back into the $64$ bit range.\n", - "\n", - "#### 1a. Single sketch estimation\n", - "\n", - "From the same directory as this notebook, run\n", - "\n", - "```./cardinality_error_experiment.py -lgk 14 -lgt 7 -lgN 20``` \n", - "\n", - "which generates $8$ \"plot points\" between every power of $2$ not exceeding $N = 2^{21}$. We fix `-lgt 7` for $128$ trials and use a sketch size of with $2^{14}$. For every trial, a fresh sketch is initialised. The results are saved in a directory `hll_accuracy_profile_yyymmdd/...`\n", - "\n", - "The two sketches we compare are HyperLogLog sketches with $2^{14}$ buckets:\n", - "\n", - "*ASF DataSketches Sketch Setup*\n", - "- `hll = asf.hll_sketch(14)`\n", - "\n", - "*datasketch sketch setup*\n", - "- `h = ds.HyperLogLogPlusPlus(p=14, hashfunc=lambda x: mmh3.hash64(x, signed=False)[0])`\n" - ] - }, - { - "cell_type": "code", - "execution_count": 40, - "id": "433f73f7-7844-448c-b7fd-16122a3a8b4c", - "metadata": {}, - "outputs": [], - "source": [ - "asf_errors = pd.read_csv(\"hll_accuracy_profile_20230504/DataSketches_hll_1516lgK_14_lgT_8trials_256.csv\", index_col=0)\n", - "ds__errors = pd.read_csv(\"hll_accuracy_profile_20230504/datasketch_hll_1516lgK_14_lgT_8trials_256.csv\", index_col=0)\n", - "\n", - "lgk = 14" - ] - }, - { - "cell_type": "code", - "execution_count": 41, - "id": "6e8fb853-1e79-4d2a-93a2-5e98c9e3c1b3", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Text(0.5, 0, 'Input cardinality $n$')" - ] - }, - "execution_count": 41, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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+OCDbB1LmTJl2LlzJ/369eO7775j8eLFdO3alYoVK5KcnMyFCxfYs2cPSUlJumE1omho3bo1kydPZs6cOdSpU4eBAwdia2vL2rVr8fT0NDuF3VtvvcX48eNp2LAhAwYMwNbWlqCgIM6fP0/v3r1Zv369yTqdO3fmzz//pHfv3jRq1AhbW1vatWtHu3btmDBhAoGBgbz44osMHDiQ8uXLc/bsWbZs2cJLL73E8uXLjba1dOlS5s2bR5s2bahatSqenp6EhISwfv167O3tmTJlisXjtba2ZvHixTg4OLBgwQL69+/PypUrsbe355NPPuHUqVP88ssvrF+/nk6dOlGhQgUiIiK4fPkyQUFBzJgxQzftpYuLiy4p49ChQ/H398fa2po+ffpQr149unXrxn/+8x+++OILatasSb9+/fDx8SE8PJwDBw7QokULFi1a9ER/P22vFCWbPb0ePXpEmTJldLk9rKysCAoK4tChQ9SsWZMVK1aYJKt8+eWXWb16NStXrqRhw4b07t2byMhIli9fTlpaGr/++mum0yS/8cYbODo68vXXxlPhDh06lGnTpvH6669z5MgRQkJC2L17N//3f/+Xae8GLSsrK1asWMGwYcNYu3YtVapUoXPnztSsWVOXX2TXrl3cu3ePd999N1vvjyhccnN9elKtWrXi7bffZtasWdSrV4+BAweSnJzM8uXLiYqKYs6cOfj6+hqtM3fuXKZPn87UqVONpvLt378/x48fp2rVqqSnp5ud5tdwaMiDBw/o3LkzUVFRdO7cmUOHDnHokOlU65amFs9OkkpQh8OtX7+etm3b4uPjg729PRcvXmTLli2kpaUxZswYi8NihchzBR0JEUJItFdRFGXIkCEKoAQEBGRZt2vXrgqgrF69WlEURdm/f7/y0UcfKa1bt1Z8fHwUOzs7xcnJSfH391dGjx6tnD592mQb2e0RkZsnaJcuXVL69++veHt7K3Z2doqHh4fSoUMH5ffff1fS09MtrhcZGam88cYbSsWKFRVbW1ulbNmyymuvvabcuHEj0/298847ipeXl3L37l2zr//9999K7dq1FVtbW6VKlSrKr7/+mu1j0UpKSlIWLFig9OzZUylbtqxia2uruLi4KHXq1FEmT55s8h5Lj4iiIT09XZkzZ45So0YNxc7OTilXrpwyYcIEJTo62uKT+MDAQKV+/fqK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tyIjI62mTZta999/v3XixInyPwEJCF034i1dM+ItXTNSGrpuxFu6ZioPZUSIiIiIiIiISLlRjQgRERERERERKTcKRIiIiIiIiIhIuVEgQkRERERERETKjQIRIiIiIiIiIlJuFIgQERERERERkXKjQISIiIiIiIiIlBsFIkRERERERESk3CgQISIiIiIiIiLlRoEIERERERERESk3CkSIiIiIiIiISLlRIEJEREREREREyo0CESIiIiIiIiJSbhSIEBEREfFQ8+bNad68ucuyXbt2YbPZmDhxYrn2pajjBqo/IiIinlIgQkREpBKx2WzYbLZAd6NE+jBcsej/Q0REKpKIQHdAREREpDJr1KgRmzdvJj4+PtBdASpef0RERApSIEJERESkDCIjI2nXrl2gu5GvovVHRESkIA3NEBERqcScU+537drF+PHjqV27NjExMfTs2ZPvvvuu2G22bNnCmDFjSEhIoGrVqpx//vnMnTu30DaLFi3CZrPx1FNPue2Hc+2Ep556ihYtWgDwwQcf5A8nsdlsvP/++x6f28qVKxk3bhyNGjUiOjqaBg0aMGLECL788kuX9d5//32uvPJKWrZsSZUqVYiLi2PAgAF8/PHHxZ57UlIS48aNo27duoSFhbFo0SIALMvi9ddfp2PHjsTExNCoUSPuueceUlJS3PbT3bCH0vy/eHsuRSnYn5L+P7Zs2YLNZmPo0KFF7rNz585ERkZy8ODBEo8/b948bDYbjz32GBs2bODaa6+lXr16VKtWjf79+7NixQqPz0VERIKTMiJERESCwO7du+nduzctW7bk+uuv58SJE3zxxRdcfvnl/Pjjj24/ZO7cuZN+/frRuXNnbr/9dg4ePMgXX3zBxRdfzKeffsq4ceNK1ZchQ4Zw6tQp/vWvf3HeeecxZsyY/Ne6du3q0T7eeecd7rzzTsLDwxk9ejRt2rThyJEjrF69mjfffJOrr746f90777yTjh07MmjQIBo0aMDx48eZNWsW119/PVu3buXZZ58ttP8dO3bQp08f2rZty4QJEzh79ixxcXEAPPDAA7z22ms0aNCA2267jcjISGbMmMGKFSvIysoiKirK45+Ft/8vpTmXkpT0/9GuXTuGDh3KwoULSUpKom3bti7bL1u2jA0bNnDllVfSoEGDEo/322+/AZCUlESvXr0YPnw4N954Ixs3bmTW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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "fig, ax = plt.subplots(figsize=(12,8))\n", - "\n", - "methods = [\"ASF\", \"datasketch\"]\n", - "\n", - "for i, (method, colour, df) in enumerate(zip(methods, [asf_color, ds__color], [asf_errors, ds__errors])):\n", - " xn = df.index \n", - " median = df.median(axis=1)\n", - " q95 = df.quantile(q=0.977725, axis=1)\n", - " q05 = df.quantile(q=0.022275, axis=1) # df.mean(axis=1) - df.std(axis=1)\n", - " ax.plot(xn, median,\n", - " color=colour, label=method+\": median\")\n", - " ax.plot(xn, q95,\n", - " color=colour, linestyle=q90_ls)\n", - " ax.plot(xn, q05,\n", - " color=colour, linestyle=q90_ls, label=method+\": 90% CI\")\n", - "\n", - "ax.plot(xn, 2.04/np.sqrt(1<\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
addressyeardaylengthweightcountloopedneighborsincomelabel
0111K8kZAEnJg245r2cM6y9zgJGHZtJPy6201711180.008333102100050000.0princetonCerber
11123pJv8jzeFQaCV4w644pzQJzVWay2zcA2016132440.000244101100000000.0princetonLocky
2112536im7hy6wtKbpH1qYDWtTyMRAcA2p7201624601.000000102200000000.0princetonCerber
31126eDRw2wqSkWosjTCre8cjjQW8sSeWH72016322720.00390610271200000.0princetonCerber
41129TSjKtx65E35GiUo4AYVeyo48twbrGX20162381440.07284845601200000000.0princetonLocky
\n", - "
" - ], - "text/plain": [ - " address year day length weight count \\\n", - "0 111K8kZAEnJg245r2cM6y9zgJGHZtJPy6 2017 11 18 0.008333 1 \n", - "1 1123pJv8jzeFQaCV4w644pzQJzVWay2zcA 2016 132 44 0.000244 1 \n", - "2 112536im7hy6wtKbpH1qYDWtTyMRAcA2p7 2016 246 0 1.000000 1 \n", - "3 1126eDRw2wqSkWosjTCre8cjjQW8sSeWH7 2016 322 72 0.003906 1 \n", - "4 1129TSjKtx65E35GiUo4AYVeyo48twbrGX 2016 238 144 0.072848 456 \n", - "\n", - " looped neighbors income label \n", - "0 0 2 100050000.0 princetonCerber \n", - "1 0 1 100000000.0 princetonLocky \n", - "2 0 2 200000000.0 princetonCerber \n", - "3 0 2 71200000.0 princetonCerber \n", - "4 0 1 200000000.0 princetonLocky " - ] - }, - "execution_count": 44, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "bitcoin_df = pd.read_csv(\"BitcoinHeistData.csv\", header=0)\n", - "bitcoin_df.head()" - ] - }, - { - "cell_type": "markdown", - "id": "ba7fc55f-7214-4b20-a6c7-822207bb5922", - "metadata": {}, - "source": [ - "Let's focus on the simple task of counting how many unique addresses are present in the dataset.\n", - "With native pandas functionality, we see that there are about $2.6$ million unique addresses.\n", - "We will use HLL sketches to estimate this count." - ] - }, - { - "cell_type": "code", - "execution_count": 45, - "id": "52a71365-d54d-4295-b714-4ce6201be6c6", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 811 ms, sys: 33.8 ms, total: 845 ms\n", - "Wall time: 846 ms\n" - ] - } - ], - "source": [ - "%%time\n", - "true_count = bitcoin_df[\"address\"].nunique()" - ] - }, - { - "cell_type": "code", - "execution_count": 46, - "id": "07041390-365d-4dff-91cd-7f20bc50273c", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "There are 2631095 unique addresses\n" - ] - } - ], - "source": [ - "print(f\"There are {true_count} unique addresses\")" - ] - }, - { - "cell_type": "markdown", - "id": "8cded8f4-1d0c-4dcc-b4cd-73015394a925", - "metadata": {}, - "source": [ - "Now define equivalent sketches from both libraries.\n", - "We use $2^{14}$ buckets and $8$-bit HyperLogLog sketches for each implementation. The `datsketch:HLL` uses the MurmurHash library so that we have equivalent sketches for comparison. " - ] - }, - { - "cell_type": "code", - "execution_count": 47, - "id": "2bd9ab89-a705-4040-b14a-014a18fff9bb", - "metadata": {}, - "outputs": [], - "source": [ - "asf_hll = asf.hll_sketch(14, asf.HLL_8)\n", - "ds_hll = ds.HyperLogLogPlusPlus(p=14, hashfunc=lambda x: mmh3.hash64(x, signed=False)[0])" - ] - }, - { - "cell_type": "code", - "execution_count": 48, - "id": "356e152b-47f1-48d9-ae2f-bc5bd17ad244", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 2.08 s, sys: 8.87 ms, total: 2.08 s\n", - "Wall time: 2.09 s\n" - ] - } - ], - "source": [ - "%%time\n", - "for ad in bitcoin_df[\"address\"]:\n", - " asf_hll.update(ad)" - ] - }, - { - "cell_type": "code", - "execution_count": 49, - "id": "3540529f-e8ed-4f20-98c3-1f5dabf8ef12", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 3.65 s, sys: 10.4 ms, total: 3.66 s\n", - "Wall time: 3.66 s\n" - ] - } - ], - "source": [ - "%%time\n", - "for ad in bitcoin_df[\"address\"]:\n", - " ds_hll.update(ad)" - ] - }, - { - "cell_type": "markdown", - "id": "c2d3e4f3-b878-4945-a3dd-5fe513a86a6a", - "metadata": {}, - "source": [ - "On this simple example we see that the datasketches implementation takes about $2$ seconds compared to almost $4$ for `datasketch`. Note that these times are longer than for the native Pandas call to nunique; this is not a problem because, unlike `pd.nunique(.)` the sketches are designed for large datasets not entirely held in memory. The figures quoted are on a $2023$ Apple Macbook Pro with Apple M1 Pro and absolute numbers may differ slightly.\n", - "\n", - "For estimation accuracy, we have the following behaviour for the single sketches. Since we have the true count, we can also evaluate the error." - ] - }, - { - "cell_type": "code", - "execution_count": 50, - "id": "d529da07-3752-4685-8203-7dce6dbfa892", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "ASF estimate: 2650083.4660\n", - "ASF error: 0.7217 %\n" - ] - } - ], - "source": [ - "# DataSketches\n", - "print(f\"ASF estimate: {asf_hll.get_estimate():.4f}\")\n", - "print(f\"ASF error: {100*(asf_hll.get_estimate()-true_count)/true_count:.4f} %\")" - ] - }, - { - "cell_type": "code", - "execution_count": 51, - "id": "71531fc9-8191-4f0d-83a3-e2ccee38d56c", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "datasketch estimate: 2646133.7361\n", - "datasketch error: 0.5716 %\n" - ] - } - ], - "source": [ - "# Datasketch\n", - "print(f\"datasketch estimate: {ds_hll.count():.4f}\")\n", - "print(f\"datasketch error: {100*(ds_hll.count() - true_count)/true_count:.4f} %\")" - ] - }, - { - "cell_type": "markdown", - "id": "c2b08dd1-00c1-4f15-93bb-51ba60f23a69", - "metadata": {}, - "source": [ - "On this example, the datasketch implementation has a lower error than the ASF method. However, this was a single sketch so we cannot draw any strong conclusions. Rather, we would have to study the error distribution as previously done in [Section 1](error_vs_cardinality). \n", - "\n", - "We run $25$ independent trials of each algorithm, each trial with a fresh sketch.\n", - "Since HLL is deterministic given the hash seed, with no change to the input we would obtain the same output every time. To avoid this, we prepend the trial number to every incoming string so that the number of unique items remains the same but the streams are superficially different." - ] - }, - { - "cell_type": "code", - "execution_count": 52, - "id": "1c5a7c42-cdf7-4632-a96d-c23a7bccc95e", - "metadata": {}, - "outputs": [], - "source": [ - "lgk = 14\n", - "num_trials = 25\n", - "\n", - "all_asf_hll = [asf.hll_sketch(14, asf.HLL_8) for _ in range(num_trials)]\n", - "all_ds_hll = [ds.HyperLogLogPlusPlus(p=14, hashfunc=lambda x: mmh3.hash64(x, signed=False)[0]) for _ in range(num_trials)]\n", - "\n", - "asf_hll_estimates = np.zeros((num_trials,), dtype=float)\n", - "asf_hll_errors = np.zeros_like(asf_hll_estimates)\n", - "ds__hll_estimates = np.zeros_like(asf_hll_estimates)\n", - "ds__hll_errors = np.zeros_like(asf_hll_estimates)" - ] - }, - { - "cell_type": "code", - "execution_count": 53, - "id": "e51ee247-6f96-4418-a732-3f2f7d77dc87", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 57.9 s, sys: 131 ms, total: 58 s\n", - "Wall time: 58.2 s\n" - ] - } - ], - "source": [ - "%%time\n", - "for trial in range(num_trials):\n", - " for ad in bitcoin_df[\"address\"]:\n", - " all_asf_hll[trial].update(str(trial) + ad)\n", - " asf_hll_estimates[trial] = all_asf_hll[trial].get_estimate()" - ] - }, - { - "cell_type": "code", - "execution_count": 54, - "id": "768248dc-43d9-41d6-a379-7c9a7b60eb6d", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 1min 41s, sys: 266 ms, total: 1min 41s\n", - "Wall time: 1min 41s\n" - ] - } - ], - "source": [ - "%%time\n", - "for trial in range(num_trials):\n", - " for i, ad in enumerate(bitcoin_df[\"address\"]):\n", - " all_ds_hll[trial].update(str(trial) + ad)\n", - " ds__hll_estimates[trial] = all_ds_hll[trial].count()" - ] - }, - { - "cell_type": "markdown", - "id": "c1303e34-cc8f-4975-ade1-4f68b0e006d7", - "metadata": {}, - "source": [ - "The ASF HLL runs in about half of the time as the datasketch implementation.\n", - "However, we are also interested in the distribution of errors for each sketch implementation.\n", - "Since we have fewer trials than in Section 1, we plot a box and whisker diagram which is still useful in understanding the error distribution, despite being less informative about the full error distribution than the pitchfork plots from Section 1. The plot can be interpreted as a cross-section of the pitchfork plot at the vertical line $n = 2631095$." - ] - }, - { - "cell_type": "code", - "execution_count": 55, - "id": "33a089c7-f8b5-4320-a58e-17f6e590b1a8", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "asf_hll_errors = (asf_hll_estimates - true_count) / true_count\n", - "datasketch_hll_errors = (ds__hll_estimates - true_count) / true_count\n", - "\n", - "for arr in [asf_hll_errors, datasketch_hll_errors]:\n", - " arr.sort()\n", - "\n", - "fig, ax = plt.subplots()\n", - "error_data = {\"ASF\": asf_hll_errors, \"datasketch\": datasketch_hll_errors}\n", - "\n", - "#\n", - "box_plot = ax.boxplot(list(error_data.values()), vert=True)\n", - "for median in box_plot['medians']:\n", - " median.set_color('black')\n", - " \n", - "\n", - "\n", - "ax.scatter(np.ones_like(asf_hll_errors), asf_hll_errors, marker=\".\")\n", - "ax.scatter(2*np.ones_like(datasketch_hll_errors), datasketch_hll_errors, marker=\"x\")\n", - "ax.set_xticks([1,2], list(error_data.keys()))\n", - "ax.set_ylabel(r\"Relative Error: $ \\frac{n - \\hat{n}}{n}$\")\n", - "ax.grid()" - ] - }, - { - "cell_type": "markdown", - "id": "6611561e-75ce-4a2e-a6a1-00b8cdef81f5", - "metadata": {}, - "source": [ - "The error statistics from the experiment are as follows." - ] - }, - { - "cell_type": "code", - "execution_count": 62, - "id": "350a4171-0505-48e1-ac2c-98afa05387b6", - "metadata": {}, - "outputs": [], - "source": [ - "experiment_error_statistics = {\n", - " \"ASF\": {\"median\" : None, \"IQR\" : None}, \n", - " \"datasketch\": {\"median\" : None, \"IQR\" : None}\n", - "}\n", - "key_list = list(experiment_error_statistics.keys())\n", - "\n", - "for i, m in enumerate(box_plot[\"medians\"]):\n", - " method_median = m.get_data()[1][0]\n", - " experiment_error_statistics[key_list[i]][\"median\"] = method_median\n", - "\n", - "for i, line in enumerate(box_plot[\"boxes\"]):\n", - " liney = line.get_ydata()\n", - " iqr = liney.max() - liney.min()\n", - " experiment_error_statistics[key_list[i]][\"IQR\"] = iqr" - ] - }, - { - "cell_type": "code", - "execution_count": 61, - "id": "09f7c6eb-ff32-4679-ac0e-2d81bcd95cf1", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'ASF': {'median': 0.0015215127060363715, 'IQR': 0.009980189698406661},\n", - " 'datasketch': {'median': 0.0025901816561035075, 'IQR': 0.015456189289630978}}" - ] - }, - "execution_count": 61, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "experiment_error_statistics" - ] - }, - { - "cell_type": "code", - "execution_count": 70, - "id": "c3cf31cb-9769-4e2b-9645-10a502ad5d6b", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Library Median Error IQR\n", - "----------------------------------------\n", - "ASF 0.0015 0.0100\n", - "datasketch 0.0026 0.0155\n", - "\n", - "\n", - "\n", - "ErrorxChange Median Error IQR\n", - "----------------------------------------\n", - " 0.5874 0.6457\n" - ] - } - ], - "source": [ - "print(\"{:<12}{:>14}{:>14}\".format(\"Library\", \"Median Error\", \"IQR\"))\n", - "print(\"-\"*40)\n", - "for k,vd in experiment_error_statistics.items():\n", - " print(\"{:<12}{:>14.4f}{:>14.4f}\".format(k, vd[\"median\"], vd[\"IQR\"]))\n", - " \n", - "print(\"\\n\"*2)\n", - "print(\"{:<12}{:>14}{:>14}\".format(\"ErrorxChange\", \"Median Error\", \"IQR\"))\n", - "print(\"-\"*40)\n", - "median_factor = experiment_error_statistics[\"ASF\"][\"median\"] / experiment_error_statistics[\"datasketch\"][\"median\"]\n", - "iqr_factor = experiment_error_statistics[\"ASF\"][\"IQR\"] / experiment_error_statistics[\"datasketch\"][\"IQR\"]\n", - "print(\"{:<12}{:>14.4f}{:>14.4f}\".format(\"\", median_factor, iqr_factor))" - ] - }, - { - "cell_type": "markdown", - "id": "cbb58e63-cbba-43ac-a015-05b9471b6212", - "metadata": {}, - "source": [ - "The columns in the second table above are found by taking the ratio of the smaller ASF results and the larger datasketch results. \n", - "They indicate that the median error in using the ASF library is about $58\\%$ of that incurred when using the datasketch library and the interquartile range is tighter, being about $65\\%$ as large as that from the `datasketch` implementation." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.11.4" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/jupyter/comparison-to-datasketch/space-comparison.ipynb b/jupyter/comparison-to-datasketch/space-comparison.ipynb deleted file mode 100644 index 7ee29940..00000000 --- a/jupyter/comparison-to-datasketch/space-comparison.ipynb +++ /dev/null @@ -1,560 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "472743a8-4868-4329-af35-50ab12b95662", - "metadata": {}, - "source": [ - "# Space Comparison \n", - "\n", - "We compare the space usage between the $4, 6, 8$ bit versions of the Apache DataSketches (ASF) HyperLogLog implementation alongside the `datasketch` HyperLogLogPlusPlus implementation. We show that the `datasketch` version has approximately the same size as the ASF $8$ bit implementation when the latter is in full estimation mode. However, smaller sketches can be made without compromising on the accuracy if $6$ or $4$ bits per bucket are used which use $75\\%$ and $50\\%$ of the space consumed by either of the $8$ bit variants." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "71570575-d16b-4b9b-a066-f921b58eb179", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "from datetime import datetime\n", - "import pandas as pd\n", - "import numpy as np\n", - "from utils import distinct_number_sequence\n", - "import datasketches as ds\n", - "import datasketch as d\n", - "import mmh3\n", - "import matplotlib.pyplot as plt\n", - "from timeit import default_timer\n", - "%matplotlib inline" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "82fac9dc-d5f2-4d19-9f18-8edc96d7c045", - "metadata": {}, - "outputs": [], - "source": [ - "class SpaceProfile:\n", - " \"\"\"Generates an experiment evaluating the update time for different cardinality inputs\"\"\"\n", - " def __init__(self, sketch_lgk:int, lg_trials:int, max_lgN:int):\n", - " self.sketch_lgk = sketch_lgk\n", - " self.num_trials = 2**lg_trials\n", - " self.max_lgN = max_lgN\n", - " self.max_num_distincts = np.uint64(2 ** self.max_lgN)\n", - " self.directory_name = \"hll_space_profile_\"\n", - " if not os.path.exists(self.directory_name):\n", - " os.mkdir(self.directory_name)\n", - " self.file_extension = \"_\" + datetime.today().strftime('%H%M') + f\"lgK_{self.sketch_lgk}_lgT_{lg_trials}\"\n", - "\n", - " # Need to remove repeated items for the program logic in self.run()\n", - " self.plot_points = self._generate_plot_points()\n", - " self.plot_points.extend(self._generate_plot_points())\n", - " self.plot_points = list(set(self.plot_points))\n", - " self.plot_points.sort()\n", - " print(f\"Testing {len(self.plot_points)} points with {self.num_trials} trials for average update times:\")\n", - " print(self.plot_points)\n", - "\n", - " # Initialise the data structures for results; one for each method tested 8, 6, datasketch\n", - " # np.ndarrays\n", - " self.DataSketches_results_arr = np.zeros((len(self.plot_points), self.num_trials), dtype=float)\n", - " self.DataSketches_results_arr_6 = np.zeros_like(self.DataSketches_results_arr)\n", - " self.DataSketches_results_arr_4 = np.zeros_like(self.DataSketches_results_arr)\n", - " self.datasketch_results_arr = np.zeros_like(self.DataSketches_results_arr)\n", - "\n", - " # pd.DataFrames\n", - " self.DataSketches_results_df = pd.DataFrame(index=self.plot_points, columns=None)\n", - " self.DataSketches_results_df_6 = pd.DataFrame(index=self.plot_points, columns=None)\n", - " self.DataSketches_results_df_4 = pd.DataFrame(index=self.plot_points, columns=None)\n", - " self.datasketch_results_df = pd.DataFrame(index=self.plot_points, columns=None)\n", - " \n", - " def _generate_plot_points(self) -> list:\n", - " \"\"\"\n", - " Generates the standard sequence defining the input cardinalites for the experiment\n", - " This is just two points at each power of 2\n", - " \"\"\"\n", - " all_plot_points = []\n", - " for lgk in range(1, self.max_lgN+1):\n", - " points = np.unique(np.logspace(start=lgk, stop=lgk+1, num=4, endpoint=False, base=2, dtype=np.uint64))\n", - " all_plot_points.extend(points)\n", - " all_plot_points.sort()\n", - " return all_plot_points\n", - "\n", - " def _is_power_of_two(self, a:np.uint64) -> bool:\n", - " \"\"\"Bitwise operations to check value a is a power of two\"\"\"\n", - " return (a & (a-1) == 0) and a != 0\n", - "\n", - " def run(self) -> None:\n", - " \"\"\"Runs the experiment and writes the files every power of two trials.\"\"\"\n", - " seq_start = np.uint64(2345234)\n", - " distinct_number = np.uint64(3462)\n", - " previous_log_trial_index = 0\n", - " ds_all_results = np.zeros((self.num_trials, len(self.plot_points)))\n", - " ds_all_results_6 = np.zeros_like(ds_all_results)\n", - " ds_all_results_4 = np.zeros_like(ds_all_results)\n", - " d_all_results = np.zeros_like(ds_all_results)\n", - "\n", - " for trial in range(1, self.num_trials+1):\n", - "\n", - " # Initialise the sketches\n", - " hll = ds.hll_sketch(self.sketch_lgk, ds.HLL_8)\n", - " hll6 = ds.hll_sketch(self.sketch_lgk, ds.HLL_6)\n", - " hll4 = ds.hll_sketch(self.sketch_lgk, ds.HLL_4)\n", - " h = d.HyperLogLogPlusPlus(p=self.sketch_lgk, hashfunc=lambda x: mmh3.hash64(x, signed=False)[0])\n", - " plot_point_index = 0 # Return to the start of the plot points list to generate the data\n", - " plot_point_value = self.plot_points[plot_point_index]\n", - " total_updates = 0\n", - " seq_start += distinct_number # Start a new input sequence\n", - "\n", - " # Temporary result data structure\n", - " ds_results = np.zeros((len(self.plot_points),))\n", - " ds_results_6 = np.zeros_like(ds_results)\n", - " ds_results_4 = np.zeros_like(ds_results)\n", - " d_results = np.zeros_like(ds_results)\n", - "\n", - "\n", - " for new_number in distinct_number_sequence(seq_start):\n", - " d_input = new_number.tobytes()\n", - " \n", - " hll.update(d_input)\n", - " hll6.update(d_input)\n", - " hll4.update(d_input)\n", - " h.update(d_input)\n", - " total_updates += 1\n", - "\n", - " if total_updates == plot_point_value:\n", - " ds_results[plot_point_index] = hll.get_compact_serialization_bytes()\n", - " ds_results_6[plot_point_index] = hll6.get_compact_serialization_bytes()\n", - " ds_results_4[plot_point_index] = hll4.get_compact_serialization_bytes()\n", - " d_results[plot_point_index] = h.bytesize()\n", - " plot_point_index += 1\n", - "\n", - " if plot_point_index < len(self.plot_points):\n", - " plot_point_value = self.plot_points[plot_point_index]\n", - " else:\n", - " break\n", - "\n", - " # After the break statement, control returns here. Now need to decide whether to write or continue.\n", - " # subtract 1 as we use 1-based indexing for the trial count.\n", - " ds_all_results[trial-1, :] = ds_results \n", - " ds_all_results_6[trial-1, :] = ds_results_6 \n", - " ds_all_results_4[trial-1, :] = ds_results_4\n", - " d_all_results[trial - 1, :] = d_results \n", - " if self._is_power_of_two(trial) and trial > 1:\n", - " # write the array only a logarithmic number of times\n", - " temporary_ds_results = ds_all_results[0:trial, : ]\n", - " temporary_ds_results_6 = ds_all_results_6[0:trial, : ]\n", - " temporary_ds_results_4 = ds_all_results_4[0:trial, : ]\n", - " temporary_d_results = d_all_results[0:trial, :]\n", - " print(f\"#################### PARTIAL RESULTS FOR {trial} TRIALS: DATASKETCHES ####################\")\n", - " previous_log_trial_index = trial\n", - "\n", - " # Write 8 bit results\n", - " self.DataSketches_results_df = pd.DataFrame(temporary_ds_results.T, \n", - " index=self.DataSketches_results_df.index, \n", - " columns=np.arange(trial).tolist())\n", - " self.DataSketches_results_df.to_csv(\n", - " self.directory_name + \"/DataSketches_hll\" + self.file_extension + f\"trials_{trial}_8_bit.csv\",\n", - " index_label=\"n\")\n", - "\n", - " # Write 6 bit results\n", - " self.DataSketches_results_df_6 = pd.DataFrame(temporary_ds_results_6.T, \n", - " index=self.DataSketches_results_df_6.index, \n", - " columns=np.arange(trial).tolist())\n", - " self.DataSketches_results_df_6.to_csv(\n", - " self.directory_name + \"/DataSketches_hll\" + self.file_extension + f\"trials_{trial}_6_bit.csv\",\n", - " index_label=\"n\")\n", - "\n", - " # Write 4 bit results\n", - " self.DataSketches_results_df_4 = pd.DataFrame(temporary_ds_results_4.T, \n", - " index=self.DataSketches_results_df_4.index, \n", - " columns=np.arange(trial).tolist())\n", - " self.DataSketches_results_df_4.to_csv(\n", - " self.directory_name + \"/DataSketches_hll\" + self.file_extension + f\"trials_{trial}_4_bit.csv\",\n", - " index_label=\"n\")\n", - "\n", - " # Write datasketch results\n", - " self.datasketch_results_df = pd.DataFrame(temporary_d_results.T,\n", - " index=self.datasketch_results_df.index,\n", - " columns=np.arange(trial).tolist())\n", - " self.datasketch_results_df.to_csv(\n", - " self.directory_name + \"/datasketch_hll\" + self.file_extension + f\"trials_{trial}.csv\",\n", - " index_label=\"n\"\n", - " )\n", - " print(self.DataSketches_results_df)" - ] - }, - { - "cell_type": "markdown", - "id": "01003378-cb60-45d0-9b19-a74b028dd4a1", - "metadata": {}, - "source": [ - "The experiment updates each of the four sketches with a number of distinct values determined by the input parameters `MAX_LG_N`. A single pass is taken for each trial and all four methods are updated in that pass. The number of bytes required to write the sketch to memory is evaluated and written to a results file.\n", - "\n", - "There is essentially no variation in the sketch sizes over these trials so only a small number of trials are performed. We set the default experimental parameters below. \n", - "\n", - "```SKETCH_LGK = 12, LG_TRIALS = 2, MAX_LG_N = 21``` " - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "45e22a9a-4b30-4a2b-9a49-0336e4d27bd8", - "metadata": {}, - "outputs": [], - "source": [ - "SKETCH_LGK = 12\n", - "LG_TRIALS = 3\n", - "MAX_LG_N = 21" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "b748aead-1563-485f-adb5-378b1655bf38", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Testing 81 points with 8 trials for average update times:\n", - "[2, 3, 4, 5, 6, 8, 9, 11, 13, 16, 19, 22, 26, 32, 38, 45, 53, 64, 76, 90, 107, 128, 152, 181, 215, 256, 304, 362, 430, 512, 608, 724, 861, 1024, 1217, 1448, 1722, 2048, 2435, 2896, 3444, 4096, 4870, 5792, 6888, 8192, 9741, 11585, 13777, 16384, 19483, 23170, 27554, 32768, 38967, 46340, 55108, 65536, 77935, 92681, 110217, 131072, 155871, 185363, 220435, 262144, 311743, 370727, 440871, 524288, 623487, 741455, 881743, 1048576, 1246974, 1482910, 1763487, 2097152, 2493948, 2965820, 3526975]\n" - ] - } - ], - "source": [ - "space_experiment = SpaceProfile(SKETCH_LGK, LG_TRIALS, MAX_LG_N)" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "cc7b9b3b-7976-4fb9-adc7-d7691134df93", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "#################### PARTIAL RESULTS FOR 2 TRIALS: DATASKETCHES ####################\n", - " 0 1\n", - "2 16.0 16.0\n", - "3 20.0 20.0\n", - "4 24.0 24.0\n", - "5 28.0 28.0\n", - "6 32.0 32.0\n", - "... ... ...\n", - "1763487 4136.0 4136.0\n", - "2097152 4136.0 4136.0\n", - "2493948 4136.0 4136.0\n", - "2965820 4136.0 4136.0\n", - "3526975 4136.0 4136.0\n", - "\n", - "[81 rows x 2 columns]\n", - "#################### PARTIAL RESULTS FOR 4 TRIALS: DATASKETCHES ####################\n", - " 0 1 2 3\n", - "2 16.0 16.0 16.0 16.0\n", - "3 20.0 20.0 20.0 20.0\n", - "4 24.0 24.0 24.0 24.0\n", - "5 28.0 28.0 28.0 28.0\n", - "6 32.0 32.0 32.0 32.0\n", - "... ... ... ... ...\n", - "1763487 4136.0 4136.0 4136.0 4136.0\n", - "2097152 4136.0 4136.0 4136.0 4136.0\n", - "2493948 4136.0 4136.0 4136.0 4136.0\n", - "2965820 4136.0 4136.0 4136.0 4136.0\n", - "3526975 4136.0 4136.0 4136.0 4136.0\n", - "\n", - "[81 rows x 4 columns]\n", - "#################### PARTIAL RESULTS FOR 8 TRIALS: DATASKETCHES ####################\n", - " 0 1 2 3 4 5 6 7\n", - "2 16.0 16.0 16.0 16.0 16.0 16.0 16.0 16.0\n", - "3 20.0 20.0 20.0 20.0 20.0 20.0 20.0 20.0\n", - "4 24.0 24.0 24.0 24.0 24.0 24.0 24.0 24.0\n", - "5 28.0 28.0 28.0 28.0 28.0 28.0 28.0 28.0\n", - "6 32.0 32.0 32.0 32.0 32.0 32.0 32.0 32.0\n", - "... ... ... ... ... ... ... ... ...\n", - "1763487 4136.0 4136.0 4136.0 4136.0 4136.0 4136.0 4136.0 4136.0\n", - "2097152 4136.0 4136.0 4136.0 4136.0 4136.0 4136.0 4136.0 4136.0\n", - "2493948 4136.0 4136.0 4136.0 4136.0 4136.0 4136.0 4136.0 4136.0\n", - "2965820 4136.0 4136.0 4136.0 4136.0 4136.0 4136.0 4136.0 4136.0\n", - "3526975 4136.0 4136.0 4136.0 4136.0 4136.0 4136.0 4136.0 4136.0\n", - "\n", - "[81 rows x 8 columns]\n", - "CPU times: user 2min 9s, sys: 229 ms, total: 2min 9s\n", - "Wall time: 2min 9s\n" - ] - } - ], - "source": [ - "%%time\n", - "space_experiment.run()" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "8afd8986-9641-4cc9-ac4d-5ead4c359367", - "metadata": {}, - "outputs": [], - "source": [ - "asf8 = pd.read_csv(f\"hll_space_profile_/DataSketches_hll{space_experiment.file_extension}trials_{1<" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "fig, ax = plt.subplots(figsize=(12,4))\n", - "\n", - "methods = [\"ASF8\", \"ASF6\", \"ASF4\", \"datasketch\"]\n", - "\n", - "for i, (method, colour, df) in enumerate(zip(methods, [asf8_color, asf6_color, asf4_color, ds_color], [asf8, asf6, asf4, dsk])):\n", - " xn = df.index \n", - " median = df.median(axis=1)\n", - " ax.plot(xn, median / 1024,\n", - " color=colour, label=method+\": median\", alpha=0.5)\n", - "\n", - "ax.set_xscale('log', base=10)\n", - "ax.legend(loc='upper center', bbox_to_anchor=(0.5, 1.25),\n", - " ncol=2, fancybox=True)\n", - "ax.grid()\n", - "ax.set_ylabel(\"Space (kilobytes)\")\n", - "ax.set_xlabel(r\"Input cardinality $n$\")\n", - "# ax.set_ylim(0.6E-6, 1.6E-6)" - ] - }, - { - "cell_type": "markdown", - "id": "46851818-f89e-4f02-9968-beb0b3594909", - "metadata": {}, - "source": [ - "Each of the ASF methods go through some resizing and growth stages until a maximum size is reached. At this point the sketches grow no further. As expected, the $4$ bit version is half the size of the $8$ bit version and the $6$ bit version is $3/4$ the size of the $8$ bit version. Once the $8$ bit ASF HLL enters its final stage, it is the same size as the datasketch HLL, but can be much smaller prior to this stage." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.11.4" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/jupyter/comparison-to-datasketch/update-time-comparison.ipynb b/jupyter/comparison-to-datasketch/update-time-comparison.ipynb deleted file mode 100644 index 63ef9857..00000000 --- a/jupyter/comparison-to-datasketch/update-time-comparison.ipynb +++ /dev/null @@ -1,456 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "0bea40e1-297c-4ccd-a24d-4d2ac631683c", - "metadata": {}, - "source": [ - "# Update Time Comparison\n", - "\n", - "We compare the update time between the Apache DataSketches (ASF) HyperLogLog implementations alongside the `datasketch` HyperLogLogPlusPlus implementation. The same hash function is used for both libraries. We compare $4, 6, 8$ bit versions of the ASF implementations, showing that they have roughly equivalent update times which are all faster than the `datasketch` algorithm (which only provides support for $8$ bit HyperLogLog).\n", - "\n", - "Experiment: for a given number $T$ trials, we fix a datasets of size $n$ for a few test input sizes $n' \\le n$ and time how long it takes to update the sketch with all $n'$ items for each chosen value of $n'$." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "e5091679-86a1-48ae-a5d5-3a0be9dc2d84", - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "import numpy as np\n", - "import datasketches as ds\n", - "import datasketch as d\n", - "import mmh3\n", - "import matplotlib.pyplot as plt\n", - "from timeit import default_timer\n", - "from typing import List\n", - "%matplotlib inline" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "b2a1f2df-3410-4b3f-8c47-09fb562e851f", - "metadata": {}, - "outputs": [], - "source": [ - "class UpdateTimeProfile:\n", - "\n", - " def __init__(self, sketch_lgk:int, num_trials:int, max_log10N:int, numpy_seed:int):\n", - " np.random.seed(numpy_seed)\n", - " self.sketch_lgk = sketch_lgk\n", - " self.num_trials = num_trials\n", - " self.max_log10N = min([max_log10N, 9])\n", - " self.max_N = 10**self.max_log10N\n", - " self.log10_test_points = np.arange(2, self.max_log10N+1, dtype=int)\n", - "\n", - " def make_data(self) -> None:\n", - " \"\"\"\n", - " Generates an independent dataset for each of the number of trials and converts to byte type. \n", - " \n", - " NB. There is a nontrivial cost to instantiating default_timer() for each sketch.\n", - " This makes the update time appear artificially slow for the first sketch that is tested.\n", - " To avoid this startup cost manifesting in the measurements, we run the timer on the \n", - " data generation as a dummy operation.\n", - " \"\"\"\n", - " data_start = default_timer()\n", - " data = np.random.randint(low=0, high=1<<31-1, size=(self.max_N, self.num_trials))\n", - " self.data_bytes = [None for _ in range(self.num_trials)]\n", - " for trial_num, trial_data in enumerate(data.T):\n", - " trial_all_bytes = [item.tobytes() for item in trial_data]\n", - " self.data_bytes[trial_num] = trial_all_bytes\n", - " data_end = default_timer()\n", - "\n", - " def _make_sketches(self, sketch_name:str) -> List[ds.hll_sketch] | List[d.HyperLogLogPlusPlus]:\n", - " if sketch_name == \"ASF8\":\n", - " return [ds.hll_sketch(self.sketch_lgk, ds.HLL_8)] * self.num_trials\n", - " elif sketch_name == \"ASF6\" : \n", - " return [ds.hll_sketch(self.sketch_lgk, ds.HLL_6)] * self.num_trials\n", - " elif sketch_name == \"ASF4\" : \n", - " return [ds.hll_sketch(self.sketch_lgk, ds.HLL_4)] * self.num_trials\n", - " elif sketch_name == \"datasketch\":\n", - " return [d.HyperLogLogPlusPlus(p=self.sketch_lgk, hashfunc=lambda x: mmh3.hash64(x, signed=False)[0])] * self.num_trials\n", - " else:\n", - " raise NotImplementedError(\"Only ASf, ASF6, ASF4 and datasketch methods are implemented.\")\n", - "\n", - " def _run_trials_for_n(self, _n:int, sketches:List[ds.hll_sketch] | List[d.HyperLogLogPlusPlus]) -> float:\n", - " \"\"\"\n", - " This is the function whose execution we time.\n", - " \n", - " _n : int --> The number of items to read from self.data_bytes, not the largest possible input\n", - " We index into the original data to avoid expensive calls to the random number generator for \n", - " the data generation.\n", - " \"\"\"\n", - " start_time = default_timer()\n", - " for trial in range(self.num_trials):\n", - " update_data = self.data_bytes[trial][:_n]\n", - " sketch = sketches[trial]\n", - " for item in update_data:\n", - " sketch.update(item)\n", - " end_time = default_timer()\n", - " return (end_time - start_time)\n", - "\n", - " def run(self, sketch_name:str) -> dict:\n", - " \"\"\"\n", - " sketch_name is a flag used to determine which sketch to test.\n", - " It should be one of [\"ASF8\", \"datasketch\"]\n", - " \"\"\"\n", - " results = {}\n", - " print(\"\\n\\n\")\n", - " print(\"{:>10}\\t{:>12}\".format(\"Sketch\", sketch_name))\n", - " print(\"{:>10}\\t{:>12}\".format(\"n\", \"Time\"))\n", - " print(\"-\"*26)\n", - " for log10_N in self.log10_test_points:\n", - " n = 10**log10_N\n", - " sketches = self._make_sketches(sketch_name)\n", - " cum_update_time = self._run_trials_for_n(n, sketches)\n", - " mean_update_time = cum_update_time / (n * self.num_trials)\n", - " print(\"{:>10d}\\t{:>12.4e}\".format(n, mean_update_time))\n", - " results[10**log10_N] = mean_update_time\n", - " return results" - ] - }, - { - "cell_type": "markdown", - "id": "5d73dd57-a3e1-4b21-ae8a-a44954c13b01", - "metadata": {}, - "source": [ - "This experiment evaluates the mean update time to process $n$ updates for various values of $n$.\n", - "\n", - "We set the default experimental parameters below. \n", - "\n", - "```SKETCH_LGK = 12, NUM_TRIALS = 100, MAX_LOG10N = 6``` \n", - "\n", - "takes about $6$ minutes to run on a 2023 MacBook Pro with an Apple M1 Pro chip running Ventura 13.5.2. Absolute timings may vary slightly on different hardware. " - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "c29c0832-3e2b-45c5-a6a8-38297301bb82", - "metadata": {}, - "outputs": [], - "source": [ - "SKETCH_LGK = 12\n", - "NUM_TRIALS = 100\n", - "MAX_LOG10N = 6\n", - "SEED = 2345234212" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "c0680a7e-e6de-4d8c-a759-63a66bae2299", - "metadata": {}, - "outputs": [], - "source": [ - "update_time_profile = UpdateTimeProfile(SKETCH_LGK, NUM_TRIALS, MAX_LOG10N, SEED)\n", - "update_time_profile.make_data()" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "5639522e-a2aa-483b-bf7f-05ff20fa79cc", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "\n", - "\n", - " Sketch\t ASF4\n", - " n\t Time\n", - "--------------------------\n", - " 100\t 6.9647e-07\n", - " 1000\t 6.5744e-07\n", - " 10000\t 6.3613e-07\n", - " 100000\t 6.4327e-07\n", - " 1000000\t 6.4708e-07\n", - "\n", - "\n", - "\n", - " Sketch\t ASF6\n", - " n\t Time\n", - "--------------------------\n", - " 100\t 6.7160e-07\n", - " 1000\t 6.2717e-07\n", - " 10000\t 6.5201e-07\n", - " 100000\t 6.5442e-07\n", - " 1000000\t 6.4222e-07\n", - "\n", - "\n", - "\n", - " Sketch\t ASF8\n", - " n\t Time\n", - "--------------------------\n", - " 100\t 6.7165e-07\n", - " 1000\t 6.5349e-07\n", - " 10000\t 6.3519e-07\n", - " 100000\t 6.3853e-07\n", - " 1000000\t 6.3897e-07\n", - "\n", - "\n", - "\n", - " Sketch\t datasketch\n", - " n\t Time\n", - "--------------------------\n", - " 100\t 1.2232e-06\n", - " 1000\t 1.1805e-06\n", - " 10000\t 1.1880e-06\n", - " 100000\t 1.1795e-06\n", - " 1000000\t 1.1845e-06\n", - "CPU times: user 5min 43s, sys: 1.45 s, total: 5min 45s\n", - "Wall time: 5min 45s\n" - ] - } - ], - "source": [ - "%%time \n", - "asf4 = update_time_profile.run(\"ASF4\")\n", - "asf6 = update_time_profile.run(\"ASF6\")\n", - "asf8 = update_time_profile.run(\"ASF8\")\n", - "datasketch = update_time_profile.run(\"datasketch\")" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "d976fec2-fa10-4b70-9e5a-e9723e54dd21", - "metadata": {}, - "outputs": [], - "source": [ - "df = pd.DataFrame([asf8, asf6, asf4, datasketch], index=[\"ASF8\", \"ASF6\", \"ASF4\", \"datasketch\"]).T" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "463d501c-d58e-4b74-9c9a-cb83251a77ad", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
ASF8ASF6ASF4datasketch
1006.716542e-076.716041e-076.964667e-070.000001
10006.534854e-076.271654e-076.574412e-070.000001
100006.351856e-076.520148e-076.361261e-070.000001
1000006.385290e-076.544232e-076.432748e-070.000001
10000006.389657e-076.422185e-076.470817e-070.000001
\n", - "
" - ], - "text/plain": [ - " ASF8 ASF6 ASF4 datasketch\n", - "100 6.716542e-07 6.716041e-07 6.964667e-07 0.000001\n", - "1000 6.534854e-07 6.271654e-07 6.574412e-07 0.000001\n", - "10000 6.351856e-07 6.520148e-07 6.361261e-07 0.000001\n", - "100000 6.385290e-07 6.544232e-07 6.432748e-07 0.000001\n", - "1000000 6.389657e-07 6.422185e-07 6.470817e-07 0.000001" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "db5fb983-1e70-4738-8abd-263b446889aa", - "metadata": {}, - "outputs": [], - "source": [ - "# Plotting parameters\n", - "method_plot_params = {\n", - " \"asf8\" : {\"color\": \"C0\", \"marker\": '.'},\n", - " \"asf6\" : {\"color\": \"C1\", \"marker\": '+'},\n", - " \"asf4\" : {\"color\": \"C2\", \"marker\": 'd'},\n", - " \"datasketch\" : {\"color\": \"C1\", \"marker\": \"^\"}\n", - "}\n", - "asf8_color = method_plot_params[\"asf8\"][\"color\"]\n", - "asf6_color = method_plot_params[\"asf6\"][\"color\"]\n", - "asf4_color = method_plot_params[\"asf4\"][\"color\"]\n", - "ds_color = method_plot_params[\"datasketch\"][\"color\"]\n", - "q90_ls = \"--\"\n", - "\n", - "params = {'legend.fontsize': 'x-large',\n", - " 'axes.labelsize': 'x-large',\n", - " 'axes.titlesize':'x-large',\n", - " 'xtick.labelsize':'x-large',\n", - " 'ytick.labelsize':'x-large',\n", - " \"lines.linewidth\": 2.5}\n", - "plt.rcParams.update(params)" - ] - }, - { - "cell_type": "markdown", - "id": "617d9a18-7a50-40fb-ba83-8f41ed91c3a9", - "metadata": {}, - "source": [ - "We plot on the $y$-axis the median update time (in seconds) and $x$-axis the input cardinality.\n", - "The times vary from about $0.7 - 1.2$ microseconds per update.\n", - "As expected, for both libraries, we see that the update time for a single item is essentially constant as $n$ increases." - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "5ff014ec-7062-4a79-a968-4fb24f2f4178", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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X19f2NraYuzYsQgPDy9wRv7GjRtYuXIl3n//fTRp0gQXL17kgntEREREREREGlSoe/BDQkIwYcIE+Pn54eeff8bPP/8MXV1duLm5wdbWFpaWlnjx4gVSUlJw9epVPHr0CEIIWFtbY968eZg6dSpkMpmmz4WIiIiIiIjonVXoRfaaN2+OsLAwXLt2DWvXrsXRo0dx4cIF/Pnnnyr9qlatit69e6NPnz7o06cP9PX1SzxoIiIiIiIiIlJV5FX0nZ2dsXDhQgBAZmYmkpKSkJKSAkNDQ1hbW8PW1rbEgyQiIiIiIiKighVrmzwjIyM4OzvD2dm5pOIhIiIiIiIiIjUUapE9IiIiIiIiItJuLPCJiIiIiIiIKgAW+EREREREREQVAAt8IiIiIiIiogqABT4RERERERFRBcACn4iIiIiIiKgCYIFPREREREREVAHoFefJ2dnZOHr0KK5cuYJnz55h5syZAIAXL14gPT0dVlZW0NHhdwhEREREREREmqZ29R0aGoqaNWuiW7dumDZtGgICApRtFy5cgK2tLbZt21YSMRIRERERERHRW6hV4MfGxqJnz56QJAnBwcEYOHCgSnurVq1Qq1Yt7N69u0SCJCIiIiIiIqKCqVXgz5kzB0ZGRoiNjcWkSZPg7Oycp0/z5s1x8eLFYgdIRERERERERG+nVoEfFRWFnj17wsbG5o19HBwc8M8//6gdGBEREREREREVnloF/rNnz2BlZVVgn8zMTMjlcrWCIiIiIiIiIqKiUavAt7e3x19//VVgnwsXLqB27dpqBUVERERERERERaNWgd+1a1ccPnwYJ0+ezLf90KFDOHXqFD7++ONiBUdEREREREREhaNWgT9jxgxYWFjAy8sLX331FS5fvgwAOHDgAL766it88sknsLW1ha+vb4kGS0RERERERET501PnSfb29ggLC0O/fv3w/fffK4/36NEDQgg4OTlh165db71Pn4iIiIiIiIhKhloFPgA0adIEV69exYEDBxAdHY2UlBSYm5ujVatW8Pb2hp6e2kMTERERERERUREVqwrX1dVFjx490KNHj5KKh4iIiIiIiIjUoNY9+ERERERERESkXYo1g3/p0iVcvHgRd+/eRXZ2dp52SZIwc+ZMtca+e/cuZs2ahdDQUKSkpMDW1hY9e/aEv78/LC0tCz3OyZMn8f333+PixYu4f/8+rK2t8d5772HSpEn48MMP1YqNiIiIiIiISNuoVeA/fvwYn332GUJDQwEAQoh8+6lb4CcmJsLDwwPJycnw9vaGq6srzpw5g8WLFyM0NBRRUVGoUqXKW8dZuXIlxo0bB2NjY/Tq1QvVq1fH3bt3sWvXLhw6dAhz586Fn59fkeMjIiIiIiIi0jZqFfhTpkzBoUOH0LlzZwwePBj29vYluqjeuHHjkJycjCVLlmDixInK476+vggODoafnx9WrVpV4BjZ2dmYMWMGDAwMcO7cOdStW1fZ9vXXX8Pd3R3z5s3DF198AZlMVmKxExEREREREZUFtary/fv3w8PDA2FhYSUdDxITExEWFoaaNWti/PjxKm2BgYH4+eefsXHjRgQFBcHY2PiN4zx+/BhpaWlo2LChSnEPAG5ubnBxccGff/6JZ8+escAnIiIiIiKick+tRfZyc3Ph4eFR0rEAAMLDwwEAXl5e0NFRDc/U1BStW7dGZmYmYmJiChzH2toaVatWRUJCAq5du6bSpjjWuHHjQl3qT0RERERERKTt1JrBb9KkCW7cuFHSsQAArl69CgBwcXHJt93Z2RlhYWFISEhAp06d3jiOJElYvnw5Bg8ejKZNm6JXr16ws7NDUlISdu/ejfr162Pr1q0FxpKVlYWsrCzl4/T0dACvLv/Pb1FBKnmKn7Mmf965GryCg3lChcE8p3cB85zeBcxzehcwz0tfUWKWxJtWyCvAsWPH8NFHH+H3339HmzZtivr0Ao0ePRqrV6/G6tWrMXLkyDztfn5+mD9/PubPn48ZM2a8dbyoqCh8+umn+Pvvv5XHqlWrhpkzZ2Ls2LF5rhJ4XUBAAAIDA/Mc37JlC4yMjAp5RkRERERERETqyczMxMCBA5GWlgYzM7MC+6o1g9+xY0ds3boVvXr1wscff4wmTZrA3Nw8375DhgxR5yVKxKZNmzBq1Cj07t0bM2fORI0aNXD79m3MmTMHEyZMQGRkJH799dc3Pn/GjBnw9fVVPk5PT4eDgwO8vLze+oOlkpGdnY0jR46gS5cu0NfX18hrXG3WXCPjAkDd2LMaG5sqDuY5vQuY5/QuYJ7Tu4B5XvoUV5IXhloF/suXL7F3716kpqYiJCQEISEhkCRJpY8QApIkFbnAV3xRkJaWlm+74riFhUWB4yQkJGD48OFo2LAhNm7cqJypd3V1xcaNG3H16lVs374dERERaN++fb5jyGSyfBfg09fX11gyU/40+TPXfe02jJLGPKGiYJ7Tu4B5Tu8C5jm9C5jnpacoMatV4M+YMQMhISGoV68e+vfvDzs7uxLbJk+x4n1CQkK+7YoF8950j75CWFgYsrOz4enpmecyfB0dHbRr1w7nzp3DuXPn3ljgExEREREREZUXalXlW7duRYMGDXD27FlUqlSpRAPq0KEDgFcFulwuVynOnz59iqioKBgZGaFVq1YFjqNYHO/hw4f5tiuOl3T8RERERERERGVBrW3ynjx5Ai8vL40Ux05OTvDy8sKtW7ewfPlylTZ/f39kZGTgs88+g7GxsfJ4fHw84uPjVfq2bdsWALBjxw5cunRJpe3ChQvYsWMHJElCx44dS/wciIiIiIiIiEqbWjP4bm5u+Oeff0o6FqUVK1bAw8MDkyZNwtGjR+Hm5obTp08jPDwcLi4umDdvXp54gFf3/Su0aNECw4YNw7p169C8eXP06tULNWrUwK1bt7Bnzx68fPkSU6ZMQf369TV2HkRERERERESlRa0Cf9q0aRg1ahQSEhLeei+8OpycnBAbG4tZs2YhNDQUBw8ehK2tLSZPngx/f39YWloWapy1a9eiXbt2WL9+PQ4fPoynT5/CzMwMbdq0wahRozBgwIASj52IiIiIiIioLKhV4Nvb2+PDDz9Ey5YtMXnyZDRt2vSN2+S1a9dOrcAcHBywbt26QvV9feb+dZIkYejQoRg6dKhaMRARERERERGVF2oV+O3bt4ckSRBCYPbs2Xm2yHtdbm6u2sERERERERERUeGoVeDPmjWrwKKeiIiIiIiIiEqXWgV+QEBACYdBRERERERERMWh1jZ5RERERERERKRdWOATERERERERVQCFukS/Y8eOkCQJISEhqF69Ojp27FiowSVJwtGjR4sVIBERERERERG9XaEK/IiICABAZmamyuO34UJ8RERERERERKWjUAW+XC4v8DERERERERERla1C34PfsWNHbNiwQZOxEBEREREREZGaCl3gR0RE4NatWxoMhYiIiIiIiIjUxVX0iYiIiIiIiCoAFvhEREREREREFQALfCIiIiIiIqIKoFCr6CsUdns8BUmSMHPmzCI9h4iIiIiIiIiKrkgFfmRkZKGKfEmSIIRggU9ERERERERUSopU4Ht6esLT01NTsRARERERERGR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JAk9e/YscoxERERERERE2katbfLeplKlSvjoo4+wbdu2Ij+3Q4cOAICwsDDI5XKVlfSfPn2KqKgoGBkZoVWrVgWOM2TIEGRmZuY5fu3aNRw/fhyNGzdG06ZN4e7uXuQYiYiIiIiIiLSNRgp8AKhSpQqePXtW5Oc5OTnBy8sLYWFhWL58OSZOnKhs8/f3R0ZGBj7//HMYGxsrj8fHxwMAXF1dlceWLFmS7/jr16/H8ePH0a1bt7cuskdERERERERUXmiswL9//77yfvqiWrFiBTw8PDBp0iQcPXoUbm5uOH36NMLDw+Hi4oJ58+ap9HdzcwMAFHJDACIiIiIiIqIKp8TvwQdeLYS3b98+NG7cWK3nOzk5ITY2FkOHDsXp06cRFBSExMRETJ48GTExMahSpUrJBkxERERERERUzpXoDH5KSgqio6Mxa9YsPHr0CEOHDlV7LAcHB6xbt65QfYsycz906NBixUVERERERESkjQpd4BdlP3shBD799FMMHDhQraCIiIiIiIiIqGgKXeC/bZZckiSYm5ujUaNGGDp0KHx8fIodHBEREREREREVTqELfLlcrsk4iIiIiIiIiKgYNLLIHhERERERERGVLhb4RERERERERBUAC3wiIiIiIiKiCoAFPhEREREREVEFwAKfiIiIiIiIqAJggU9ERERERERUAbDAJyIiIiIiIqoAWOATERERERERVQB6xR0gMzMTqampyM3Nzbfd0dGxuC9BRERERERERG+hdoG/ceNGfPvtt7hy5cob+0iShJycHHVfgoiIiIiIiIgKSa0Cf/369Rg+fDh0dXXRtm1bODg4QE+v2BcDEBEREREREZGa1KrKf/jhB1haWuLkyZNwc3Mr6ZiIiIiIiIiIqIjUWmTv+vXr+OSTT1jcExEREREREWkJtQr8ypUrQyaTlXQsRERERERERKQmtQr8jz/+GBERERBClHQ8RERERERERKQGtQr8BQsWICsrC2PGjMGzZ89KOiYiIiIiIiIiKiK1Ftn75JNPYGRkhDVr1mDLli1wdnaGhYVFnn6SJOHo0aPFjZGIiIiIiIiI3kKtAj8iIkL53xkZGbhw4UK+/SRJUmd4IiIiIiIiIioitQp8uVxe0nEQERERERERUTGodQ8+EREREREREWkXFvhEREREREREFYBal+i/7u7du0hKSkJWVla+7e3atSvuSxARERERERHRW6hd4IeFhWHq1KmIj48vsF9ubq66L0FEREREREREhaTWJfoxMTH4+OOP8eTJE0yYMAFCCLRr1w6jRo2Cq6srhBDo3r07Zs2aVdLxEhEREREREVE+1CrwFyxYAAMDA5w9exaLFy8GAHTo0AGrVq1CXFwcvvnmG/z+++/o27dviQZLRERERERERPlTq8CPjo5Gjx49YGdnpzym2DpPkiTMnj0bbm5u8Pf3L5koiYiIiIiIiKhAahX4aWlpcHR0VD6uVKkSMjIyVPq0bt0ax48fL150RERERERERFQoahX41tbWSE1NVXmcmJio0ic7OxvPnz8vXnREREREREREVChqFfguLi4qBX2rVq1w5MgRJCQkAADu37+PnTt3wtnZuWSiJCIiIiIiIqICqVXgf/jhh4iMjMTjx48BAJMnT8bz58/h7u6O5s2bw9XVFQ8fPsSUKVNKMlYiIiIiIiIiegO1CvzPP/8cx48fh76+PoBX99tv374dtWrVQlxcHGxtbbFy5UoMGTJE7cDu3r2L4cOHw87ODjKZDDVr1sSUKVNUbg0oSEZGBjZv3oyBAwfC1dUVxsbGMDU1RbNmzRAUFISXL1+qHRsRERERERGRttFT50lmZmZo2bKlyrFevXqhV69eJRJUYmIiPDw8kJycDG9vb7i6uuLMmTNYvHgxQkNDERUVhSpVqhQ4xokTJzB48GBUrlwZHTp0QM+ePZGamop9+/bhiy++wK5du3D06FEYGBiUSMxEREREREREZUmtAl/Txo0bh+TkZCxZsgQTJ05UHvf19UVwcDD8/PywatWqAsewsbHBpk2b8Mknn6BSpUrK4z/88APat2+PU6dOYfny5Zg2bZrGzoOIiIiIiIiotKh1ib7Cw4cPsWrVKkyePBkjR45UOX7mzBm1VtFPTExEWFgYatasifHjx6u0BQYGwtjYGBs3bsyzLd9/NW7cGIMGDVIp7gHA1NRUWdRHREQUOT4iIiIiIiIibaR2gb927VplEb506VKsW7dO2fbgwQO8//772LJlS5HHDQ8PBwB4eXlBR0c1PFNTU7Ru3RqZmZmIiYlRN3Tl2gF6elp5AQMRERERERFRkalV4R45cgSjR49Gw4YNERgYiMOHD6tcMv/ee++hfv362LNnD0aMGFGksa9evQrg1VZ8+XF2dkZYWBgSEhLQqVMndcLHL7/8AuDVbgAFycrKQlZWlvJxeno6ACA7OxvZ2dlqvXZZkukKjY2draOZtQwU41ZCpbf0VF+uTFdjY5fHPCnvmOf5Y55XLMzz/DHPKxbmef6Y5xUL8zx/zHNVRYlZEkIUOas6d+6M+Ph4XL58GWZmZggMDMTs2bORm5ur7DN48GBER0cjMTGxSGOPHj0aq1evxurVq1Uu+1fw8/PD/PnzMX/+fMyYMaOooWPZsmWYOHEiGjdujDNnzihn8/MTEBCAwMDAPMe3bNkCIyOjIr82ERERERERUVFkZmZi4MCBSEtLg5mZWYF91ZrBj42NxYABAwocvHr16rh//746w2vMrl27MGXKFNjY2GDnzp0FFvcAMGPGDPj6+iofp6enw8HBAV5eXm/9wWqj9wIOa2zsOFnRrtQorGwdAxxpsATfPvkWL6GZrQ3X/5ijkXEBoG7sWY2NTfljnuePeV6xMM/zxzyvWJjn+WOeVyzM8/wxz1UpriQvDLUK/JcvX8LY2LjAPk+ePIGubtEvrTA3NwcApKWl5duuOG5hYVGkcffs2YMBAwbA2toa4eHhqF279lufI5PJIJPJ8hzX19d/65cD2igrV9LY2PryFxobGwBe4iWykPX2jmrQzdLcG0h5zJPyjnmeP+Z5xcI8zx/zvGJhnuePeV6xMM/zxzxXVZSY1Vpkr2bNmjh37lyBfU6fPo26desWeWzFcxISEvJtv3btGoA336Ofn+3bt+OTTz5BtWrVEBkZqVZcRERERERERNpMrQLf29sbJ06cwPbt2/NtX7duHS5duoQ+ffoUeewOHToAAMLCwiCXy1Xanj59iqioKBgZGaFVq1aFGm/z5s349NNPYWdnh8jISDg7Oxc5JiIiIiIiIiJtp1aB/7///Q+Ojo749NNP0b9/f0RHRwN4tYBd//79MXr0aDg7O2PixIlFHtvJyQleXl64desWli9frtLm7++PjIwMfPbZZyq3CMTHxyM+Pj7PWCEhIRgyZAgcHR1x/PjxQl2WT0RERERERFQeqXUPvqWlJSIjIzFkyBCVWfxJkyYBANq2bYstW7a89T79N1mxYgU8PDwwadIkHD16FG5ubjh9+jTCw8Ph4uKCefPmqfR3c3MDALy+IUB4eDiGDx8OuVyODh06YN26dXlex8LCAlOmTFErRiIiIiIiIiJtolaBDwCOjo6IiIjApUuXEB0djZSUFJibm6NVq1Zo2rRpsYJycnJCbGwsZs2ahdDQUBw8eBC2traYPHky/P39YWlp+dYxbt++rbzEX7Hv/X/VqFGDBT4RERERERFVCGoX+AoNGzZEw4YNSyIWFQ4ODvnOuufn9Zl7haFDh2Lo0KElHBURERERERGRdlLrHnwiIiIiIiIi0i6FnsHfsGGDWi8wZMgQtZ5HRERERERERIVX6AJ/6NChkCSp0AMLISBJEgt8IiIiIiIiolJQpHvw9fT00L17d+Wq9URERERERESkHQpd4Ht6eiIyMhK7d+/GgwcPMGrUKPTr1w8GBgaajI+IiIiIiIiICqHQi+yFh4cjISEBX3zxBa5du4Zhw4bB1tYWEydOxKVLlzQZIxERERERERG9RZFW0a9Tpw6+/fZb3L17F7/++itatmyJlStXwt3dHS1atMDatWuRkZGhqViJiIiIiIiI6A3U2iZPT08Pffr0QWhoKBITE/H111/jn3/+wejRo2FnZ4fo6OiSjpOIiIiIiIiICqBWgf+6GjVqYM6cOfjpp59gb2+PZ8+e4eHDhyURGxEREREREREVUpFW0f+ve/fu4ZdffsEvv/yC27dvw8DAAIMHD0aTJk1KKj4iIiIiIiIiKoQiF/hyuRz79+/HmjVrEBoaipycHDRo0ACLFy/GZ599BnNzc03ESUREREREREQFKHSBf/PmTaxduxbr1q3DP//8A2NjY/j4+GDUqFFo0aKFJmMkIiIiIiIiorcodIFfp04dAECzZs0QGBiITz/9FMbGxhoLjIiIiIiIiIgKr9AFvhAC+vr6+OeffzB79mzMnj37rc+RJAm3b98uVoBERERERERE9HZFugc/Ozsbd+/e1VQsRERERERERKSmQhf4crlck3EQERERERERUTHolHUARERERERERFR8LPCJiIiIiIiIKgAW+EREREREREQVAAt8IiIiIiIiogqABT4RERERERFRBcACn4iIiIiIiKgCYIFPREREREREVAGwwCciIiIiIiKqAFjgExEREREREVUALPCJiIiIiIiIKgAW+EREREREREQVAAt8IiIiIiIiogqABT4RERERERFRBcACn4iIiIiIiKgCYIFPREREREREVAGwwCciIiIiIiKqAFjgExEREREREVUAWlvg3717F8OHD4ednR1kMhlq1qyJKVOmIDU1tUjjPH78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RXFxMXl5eYSEhLg7JJEabd68mddff522bduSkJDAggULOHfuHLNnz75rkl9WVkZ6ejqbNm0iKysLgGbNmtGvXz9SUlLo3r27m1sl95sSfBERERFpVC5dusT8+fOZPn26kntpEG7dusXkyZPZvHkzOTk5DBgwgB07dhAbG8uFCxeIj493SfLtf9rl5eVRVlZGmzZtaNu2Lb6+vm5skTwoSvBFREREpNGx2WxOi42JPOqOHDmC1WplxowZwJ1nODs7m5iYmGqTfJPJhMlk0h73jYwSfBERERERkQbgv//9L15eXo7PFRUVfPHFF0ybNo3z5887Jfl2//nPf2jdurUS/UZCq+iLiIiIiIg0AFWTe7iz7eOQIUNYuXIlAQEBJCUlsWjRImw2GwCpqamEh4eTm5ur5L6RUA++iIiIiIhIA2bvyY+JieHixYvEx8cTGBjIwoULuXLlCvn5+XTr1s3dYcpDoARfRERERESkgfvxxx85cOAAv/vd7/j+++8pLy/Hx8eHffv20bNnT3eHJw+JhuiLiIiIiIg0YJWVlXh7exMWFkZERARlZWX4+flhtVqV3DcyWjpURERERESkAbNvh7d27Vo2btyIr68v+/bto0ePHm6OTB42DdEXERERERFp4KxWK1FRURQXF5OXl0dISIi7QxI30BB9ERERERGRBq5r164MHz5cyX0jpx58ERERERERD2Cz2bBYNAu7MVOCLyIiIiIiIuIBNERfRERERERExAMowRcRERERERHxAErwRURERERERDyAEnwRERERERERD6AEX0RERERERMQDKMEXERERERER8QBK8EVEREREREQ8gBJ8EREREREREQ+gBF9ERERERETEAyjBFxERkUdCx44d6dixo1PZmTNnMJlMvPbaaw81lrt9r7viERERqQ0l+CIiIv/PZDJhMpncHUaNlGQ+WnQ/RETkUWFxdwAiIiIidxMYGMjx48fx9fV1dyjAoxePiIhIVUrwRURE5JHl5eVFcHCwu8NweNTiERERqUpD9EVERO6i6tDrM2fOMH78eFq1akXTpk3p378/27Ztu+c5J06cYNSoUbRs2ZKf/exnPPPMM+zatcvlnJycHEwmE/Pnz682jqpz0+fPn0+nTp0AWLdunWNagclkYu3atbVu29dff01kZCSBgYE89thjtGvXjmHDhpGZmel03Nq1axkz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evTowYoVK4iJiSE0NJRXXnmFrl27UlJSwqFDh/Dx8SE7Oxu40+OclpbGuHHjGDt2LAEBARQUFLBjxw5effVVMjIy6vSbDBo0iBkzZvDRRx/Rs2dPxo4di5eXF1u2bMHf379W+8DX1/1uS1W1vR8mk4mYmBhmz54N3JmXX1u3b9/mm2++oXfv3nh7e7vU2xN89eCLiDRu6sEXERF5ADp16sSBAwfw9/cnOTmZzMxM+vbtS1ZWFpGRkS7HJyYm8t5779G0aVNWrVpFVlYWY8aMYefOnXh5ebkcv379el566SV27NhBYmIib7/9tmOOdk2mTJmC1WplxIgR5OTksHTpUrZu3Urr1q2JjY11HNe7d2+ys7MZOHAgn3/+OStXruT69ev8/e9/JyYmpl6/y4cffshHH32Er68vKSkppKen8+KLL7Jnz55qE9f75UG0para3o/XXnuNJk2a0LRpU6Kjo2t9/YKCAmw2W7XD8+FOgt+iRQuCgoLq3QYREWn4TIZhGO4OQkRExFOcOXOGTp06ER0dzdq1a90djjxicnJyGDx4ML/97W9Zv369u8MREREPox58ERERkYdkyZIlAEyfPt3NkYiIiCfSHHwRERGRB+jo0aNs27aNw4cPs337dkaMGMGAAQPcHZaIiHggJfgiIiIiD9Dhw4eZM2cOPj4+jBs3jhUrVrg7JBER8VCagy8iIiIiIiLiATQHX0RERERERMQDKMEXERERERER8QBK8EVEREREREQ8gBJ8EREREREREQ+gBF9ERERERETEAyjBFxEREREREfEASvBFREREREREPIASfBEREREREREPoARfRERERERExAMowRcRERERERHxAP8HoxwbqipoU+0AAAAASUVORK5CYII=", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "fig, ax = plt.subplots(figsize=(12,4))\n", - "df.plot(kind=\"bar\", ax=ax)\n", - "ax.set_xlabel(r\"Input cardinality $n$\")\n", - "ax.set_ylabel(\"Mean Update Time (secs.)\")\n", - "ax.grid()\n", - "ax.legend(loc='upper center', bbox_to_anchor=(0.5, 1.15),ncol=4, fancybox=True)\n", - "plt.xticks(rotation=45)\n", - "bar_tick_labels = [label.get_text() for label in plt.gca().get_xticklabels()]" - ] - }, - { - "cell_type": "markdown", - "id": "f0b6cfb6-8040-4ec3-8db7-601de6e5fd94", - "metadata": {}, - "source": [ - "We evaluate the factor speedup per update. This is defined as the ratio of the total time per update required in using the datasketch library compared to the ASF implementation. We see that the datasketch library takes almost twice as much time per update compared to the ASF implementations." - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "1e515034-aca9-4ade-ae39-e57d07ac117f", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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l6C2SktLcenSJXTp0gUmJiZVzlcUCDiCgIiodeMIAiIiIgPk6+uLY8eOwd7eHt9//z0iIyMRHByM7du3IywsrEr/999/Hx999BHMzMywcuVKbN++HVOnTsWuXbugUCiq9P/ll18wbtw47Ny5E++//z7ee+89zRz1R3nxxRdx5MgRjB8/HgcPHsRnn32GLVu2wNnZGS+//LKmX5cuXXDgwAH0798ff/zxB7777jvk5eXh999/x9y5c+v1dfnyyy/x1VdfwdbWFitWrMC6deswatQo7N27V+cbX31pjHuprLbfj1mzZkEqlcLMzAwzZ86s9fUvXrwIlUqlc3oBIBYIrKysEBAQUO97ICIi4ycRBEFo7iCIiIhIdO3aNfj6+mLmzJlYvXp1c4dDBubgwYMYOnQonn76afzyyy/NHQ4REbUwHEFAREREZCQ+/fRTAMArr7zSzJEQEVFLxDUIiIiIiAzYhQsXsG3bNpw5cwY7duzA+PHj0adPn+YOi4iIWiAWCIiIiIgM2JkzZ/DOO+/AxsYG06ZNw7ffftvcIRERUQvFNQiIiIiIiIiIiGsQEBERERERERELBEREREREREQEFgiIiIiIiIiICCwQEBERERERERFYICAiIiIiIiIisEBARERERERERGCBgIiIiIiIiIjAAgERERERERERgQUCIiIiIiIiIgILBEREREREREQEFgiIiIiIiIiICMD/A2fmRdMxm+GkAAAAAElFTkSuQmCC", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "fig, ax = plt.subplots(figsize=(12,4)) \n", - "\n", - "methods = [\"ASF8\", \"ASF6\", \"ASF4\"]\n", - "\n", - "xn = df.index \n", - "for i, (method, colour) in enumerate(zip(methods, [asf8_color, asf6_color, asf4_color])):\n", - " ax.plot(xn, df[\"datasketch\"] / df[method],\n", - " color=colour, label=method) \n", - "\n", - "ax.set_xticks(xn) \n", - "ax.set_xticklabels(bar_tick_labels) \n", - "ax.set_xscale(\"log\", base=10) \n", - "ax.set_xlabel(r\"Input cardinality $n$\") \n", - "ax.set_ylabel(r\"$\\times$ Speedup\") \n", - "ax.grid() \n", - "ax.legend(loc='upper center', bbox_to_anchor=(0.5, 1.15),ncol=4, fancybox=True)\n", - "plt.xticks(rotation=45) ; # suppresses text output" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.11.4" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/jupyter/comparison-to-datasketch/utils.py b/jupyter/comparison-to-datasketch/utils.py deleted file mode 100644 index d69e892e..00000000 --- a/jupyter/comparison-to-datasketch/utils.py +++ /dev/null @@ -1,37 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -import numpy as np - -def distinct_number_sequence(start:np.uint64=0) -> np.uint64: - """Generator function to make 64-bit numbers that are distinct.""" - assert isinstance(start, np.uint64) - num = start - golden_ratio = np.uint64(0x9e3779b97f4a7c13) - while True: - yield num - num += np.uint64(golden_ratio) - -if __name__ == '__main__': - start = np.uint64(2345234635) - ndistincts = np.uint64(10) - count = 0 - for i in distinct_number_sequence(start): - print(i, end="\n") - count += 1 - if count == ndistincts: - break diff --git a/jupyter/density_sketch/1-introduction-kde-coreset.ipynb b/jupyter/density_sketch/1-introduction-kde-coreset.ipynb deleted file mode 100644 index cb7f5f51..00000000 --- a/jupyter/density_sketch/1-introduction-kde-coreset.ipynb +++ /dev/null @@ -1,1630 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "eced4a42", - "metadata": {}, - "source": [ - "# Introduction to Kernel Density Estimation (KDE)\n", - "\n", - "\n", - "**Objectives:** \n", - "- To understand exactly what a kernel density estimate is approximating.\n", - "- To understand the parameters that affecct the performance of a KDE.\n", - "\n", - "\n", - "## 1. Problem Setup.\n", - "We need the following notation:\n", - "- $f$ is an underlying probability distribution function (pdf) for a probability distribution $\\mathcal{D}$.\n", - "- Samples $x_i$ are drawn independently and identically from the distribution $\\mathcal{D}$.\n", - "\n", - "The high-level aim of KDE is to use a smoothing function, known as the _kernel function_, $K$, to estimate the function $f$.\n", - "\n", - "The _kernel density estimator_ is the function $\\hat{f}$. It is evaluated at a test (or query) point $x^*$ and satisfies the following relationship:\n", - "\\begin{align}\n", - "f(x^*) \\star K(x^*) &= \\int_{\\text{domain}(f)} K(x^* - x) f(x) dx \\\\\n", - "&= \\mathbf{E}_{f(x)} \\left[ K(x^* - x) \\right] \\\\ \n", - "&\\approx \\frac1n \\sum_{i=1}^n K(x^* - x_i) \\\\ \n", - "&= \\hat{f}(x^*).\n", - "\\end{align}\n", - "\n", - "In words, the KDE at $x^*$ is approximately equal to the convolution of the density at $x^*$ with the kernel at $x^*$.\n", - "\n", - "Notably, this _does not_ mean that the KDE $\\hat{f}$ is necessarily a good estimator for the probability density function, despite that being the motivation for the estimation problem.\n", - "\n", - "## 2. Initial Comparison\n", - "\n", - "We will investigate this estimation of $\\hat{f}(x^*) \\approx f(x^*) \\star K(x^*)$." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "1d1be136", - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "from scipy import stats\n", - "import matplotlib.pyplot as plt\n", - "from sklearn.metrics.pairwise import rbf_kernel\n", - "import pandas as pd\n", - "import scipy.integrate as integrate\n", - "from scipy.spatial.distance import cdist\n", - "%matplotlib inline" - ] - }, - { - "cell_type": "code", - "execution_count": 41, - "id": "a27e06b4-e5a6-4f29-931a-c1108f470368", - "metadata": {}, - "outputs": [], - "source": [ - "import warnings\n", - "warnings.filterwarnings('ignore')" - ] - }, - { - "cell_type": "markdown", - "id": "213d42b3", - "metadata": {}, - "source": [ - "First, we will consider the case when the distribution of study is the standard normal distribution $N(0,1)$. We also obtain a _sample_ of points from $N(0,1)$." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "58a54fab", - "metadata": {}, - "outputs": [], - "source": [ - "n_sample = 10000\n", - "Z = stats.norm(0, 1)\n", - "X_train = Z.rvs(size=n_sample)[:, np.newaxis]" - ] - }, - { - "cell_type": "markdown", - "id": "082a089f", - "metadata": {}, - "source": [ - "The distribution is plotted below along with the samples. " - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "1991a6d6", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "fig, ax = plt.subplots(figsize=(6, 4))\n", - "_x = np.linspace(-5, 5)\n", - "ax.plot(_x, Z.pdf(_x), label=r\"$N(0,1)$\", color='red', lw=3.)\n", - "ax.scatter(X_train, \n", - " 0.01*np.random.uniform(size=X_train.shape[0])-0.05, \n", - " marker='.',\n", - " s=1.,\n", - " alpha=0.5, label=\"Samples: $x_i$\")\n", - "ax.set_ylabel(\"Density\")\n", - "ax.set_xlabel(r\"$x$\")\n", - "ax.legend()" - ] - }, - { - "cell_type": "markdown", - "id": "795ac4cd", - "metadata": {}, - "source": [ - "Next, we define a kernel function for single variable inputs which takes a free parameter $\\gamma > 0$ that we may choose.\n", - "\n", - "\\begin{align}\n", - "K(u) = \\exp(-\\gamma u^2).\n", - "\\end{align}\n", - "\n", - "For multivariable inputs we use\n", - "\\begin{align}\n", - "K(u) = \\exp(-\\gamma ||u||^2).\n", - "\\end{align}\n", - "\n", - "If we choose the constant $\\gamma = 1 / 2 h^2$ for some $h$, then $K$ represents a Gaussian kernel provided that \n", - "we return the following rescaled answer for the kernel density estimate:\n", - "\n", - "\\begin{align}\n", - "\\hat{f}(x^*) = \\frac{1}{h \\sqrt{2\\pi} }\\frac1n \\sum_{i=1}^n K(x^* - x_i).\n", - "\\end{align}" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "28043f3f", - "metadata": {}, - "outputs": [], - "source": [ - "def kernel_density(Xtrain, Xtest, bandwidth=1.):\n", - " \"\"\"\n", - " Returns the kernel density estimate between Xtrain and Xtest.\n", - " returns:\n", - " (1/n)*(1/bandwidth*sqrt(2pi))^d*sum_{i=1}^n K( (x* - x_i) / bandwidth )\n", - " The bandwidth in scipy is in the numerator so we use 1./bandwidth\n", - " The mean function picks up the 1/n factor.\n", - " \"\"\"\n", - " for x in [Xtrain, Xtest]:\n", - " if x.ndim == 1:\n", - " x.reshape(-1, 1)\n", - " g = (1./bandwidth)**2\n", - " K = np.exp(-cdist(Xtrain, Xtest, metric='sqeuclidean')*g/2)\n", - " K *= 1./(bandwidth*np.sqrt(2*np.pi))**Xtrain.shape[1]\n", - " return np.mean(K, axis=0)\n" - ] - }, - { - "cell_type": "markdown", - "id": "6d4be102", - "metadata": {}, - "source": [ - "Recall that we want to compare $\\hat{f}$ to the convolution below at a test point $x^*$. \n", - "Assumign that $h=1$ we have:\n", - "\n", - "\\begin{align}\n", - "f(x^*) \\star K(x^*) &= \\frac{1}{\\sqrt{2\\pi}}\\int_{\\text{domain}(f)} K(x^* - x) f(x) dx \\\\ \n", - "&= \\frac{1}{\\sqrt{2\\pi}} \\int_{\\text{domain}(f)} \\exp\\left(-\\|x^* - x\\|^2\\right) f(x) dx\n", - "\\end{align}\n", - "\n", - "The convolution can be estimated through the following code." - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "a45dd5c1", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Target: 0.3969525474770118\n" - ] - } - ], - "source": [ - "x_test = 0.1\n", - "x_test_arr = np.array([x_test])[:, np.newaxis] # needed for some of the vectorised functions\n", - "pdf_x_test = Z.pdf(x_test)\n", - "print(f\"Target: {pdf_x_test}\")" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "7caaf141", - "metadata": {}, - "outputs": [], - "source": [ - "def convolution_at_q(x, q, h):\n", - " return Z.pdf(x)*(np.exp(-0.5*np.linalg.norm((1./h)*(x - q))**2) / (h*np.sqrt(2*np.pi)))\n", - "\n", - "# This function evaluates the convolution (f \\star K) at x*\n", - "conv_estimate = integrate.quad(convolution_at_q, \n", - " -np.inf, np.inf,\n", - " args=(x_test_arr, 1.))[0]" - ] - }, - { - "cell_type": "markdown", - "id": "5525515b", - "metadata": {}, - "source": [ - "Let's do a quick check on the two quantities that we are comparing." - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "330bb223", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Convolution: 0.281\n", - "KDE : 0.280\n" - ] - } - ], - "source": [ - "print(f\"Convolution: {conv_estimate:.3f}\")\n", - "print(f\"KDE : {kernel_density(X_train, x_test_arr)[0]:.3f}\")" - ] - }, - { - "cell_type": "markdown", - "id": "52e23e0b", - "metadata": {}, - "source": [ - "They are comparable, which is good news. Now we will begin to experiment with this and check that the KDE method approaches the KDE value.\n", - "\n", - "**Experimental Setup.**\n", - "We fix a number of trials: `num_trials` and choose a test point `query`.\n", - "We generate an independent sample/training set for every trial and obtain the two: one for convolution, one for using the KDE.\n", - "\n", - "We will then plot the two error curves.\n", - "\n", - "If this experiment is too slow then try varying the number of trials or using \n", - "```\n", - "nn = np.linspace(100, 1000000, dtype=np.int64)\n", - "```" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "99b87e87", - "metadata": {}, - "outputs": [], - "source": [ - "num_trials = 25\n", - "query = np.array([1.])[:, np.newaxis]\n", - "nn = np.logspace(2, 7, endpoint=False, dtype=np.int64, num=20) \n", - "\n", - "kernel_estimates = {i:np.zeros((len(nn),), dtype=float) for i in range(num_trials)}\n", - "\n", - "conv_estimates = {i:np.zeros((len(nn),), dtype=float) for i in range(num_trials)}\n", - "\n", - "for i,n in enumerate(nn):\n", - " for t in range(num_trials):\n", - " Xtrain = stats.norm(0, 1).rvs(size=n)[:, np.newaxis]\n", - " estimate = kernel_density(Xtrain, query)[0]\n", - " kernel_estimates[t][i] = estimate\n", - " conv_estimates[t][i] = integrate.quad(convolution_at_q, -100., 100., args=(query,1.))[0]" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "21a08001", - "metadata": {}, - "outputs": [], - "source": [ - "kernel_df = pd.DataFrame.from_dict(kernel_estimates)\n", - "conv_df = pd.DataFrame.from_dict(conv_estimates)\n", - "error_df = kernel_df - conv_df\n", - "abs_error_df = error_df.abs()" - ] - }, - { - "cell_type": "markdown", - "id": "1ca5edb9", - "metadata": {}, - "source": [ - "First, we plot the error $\\hat{f}(x^*) - f(x^*) \\star K(x^*)$ versus the sample size, showing that as the sample size increases, the error decreases. We plot the median and a $90\\%$ confidence interval." - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "ed624e78", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAABEQAAAGHCAYAAAC5wYeeAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/SrBM8AAAACXBIWXMAAA9hAAAPYQGoP6dpAACk00lEQVR4nOzdeXxTVfrH8U+S7vsGZYcKqIjsIiCCLIKKiiiL6LihMzIirowK+nNwxhkRd1xQUEcHHRRFUXBgZFMHZKcsiiOgFAqyt3Tf0uT+/igJSZu2aZuQFr7v1ysvbu6959znlrRwn57zHJNhGAYiIiIiIiIiImcRc6ADEBERERERERE53ZQQEREREREREZGzjhIiIiIiIiIiInLWUUJERERERERERM46SoiIiIiIiIiIyFlHCREREREREREROesoISIiIiIiIiIiZx0lRERERERERETkrKOEiIiIiIiIiIicdZQQqcSnn37KgAEDiI+PJzIyki5duvDcc89htVpr1d/mzZsZPXo0ycnJhIWFkZKSwn333cfRo0erbHfkyBEmTpxISkoKoaGhJCcnM3r0aFJTUytt89///pdnnnmGkSNH0qZNG0wmEyaTidWrV1cbp91uZ9asWfTq1Yvo6Giio6Pp1asXs2fPxjCMGt+3iIiIiIiISH1kMvSUW8GDDz7IjBkzCAoKYtCgQURFRbFy5UqysrK49NJLWbp0KeHh4V73N3/+fG666SZKS0vp2bMnKSkpbNq0iT179pCcnMzq1atp165dhXa7du2iX79+HD16lHPOOYeLLrqItLQ0Nm7cSFBQEJ988gnXX399hXZdu3Zl27ZtFfavWrWKSy+9tNI4bTYbY8aM4fPPPyciIoLBgwcDsHz5cgoLCxk9ejQff/wxZrPyaCIiIiIiItKw6cm2nC+++IIZM2YQFRXF+vXr+frrr/nss8/YvXs3nTp1YvXq1Tz55JNe93fw4EFuv/12SktLmTVrFhs2bGDevHns2rWLW265hSNHjnDzzTdXGH1hGAZjx47l6NGj3HrrrezatYt58+axYcMGZs2aRWlpKbfddhuHDx+ucM0hQ4bw1FNPsXDhQg4cOEDr1q29ivW1117j888/p3nz5vz4448sXLiQhQsXsmPHDpo1a8ann37KzJkzvb53ERERERERkfpKI0TKufjii9m4cSN/+9vfeOKJJ9yOrV69mn79+hEaGsqRI0eIjY2ttr9HH32U559/nssvv5xly5a5HcvLy6NFixZkZ2fzn//8hyuuuMJ5bPHixVx99dXExcWxf/9+oqKi3NpefvnlrFixgsmTJzNt2rQqY2jTpg379u2rcoSI3W6nefPmHD58mA8//JDf/e53bsc//PBDbr31Vpo1a8b+/fs1SkREREREREQaND3Vuvjtt9/YuHEjADfffHOF45deeiktW7akuLiYxYsXe9XnggULKu0vKiqK4cOHA/D55597bDd8+PAKyRDX/sq3q621a9dy+PBhQkNDGTlyZIXjI0eOJCQkhIMHD7J+/XqfXFNEREREREQkUJQQcbFlyxYAEhISSElJ8XjORRdd5HZuVXJzc/nll1/c2nnbn+N9de12795Nfn5+tbFUx3G9jh07EhYWVuF4eHg4HTt29BiriIiIiIiISEOjhIiLtLQ0AFq1alXpOS1btnQ7typ79+51blfWZ2X9VReLo51hGG7XqS1f37uIiIiIiIhIfRYU6ADqk9zcXAAiIyMrPccxfSUnJ8fr/qrqs7L+qovFdRqNN7FUx1f3XlxcTHFxsfO93W4nMzOTxMRETCZTneMUERERERERqYphGOTm5tKsWbMq618qISI+NW3aNP7yl78EOgwRERERERE5y+3fv58WLVpUelwJERfR0dEAVdbkyMvLAyAmJsbr/hx9elqVprL+oqOjyczMrDQWRztvY/E21rre+5QpU3j44Yed77Ozs2nVqhVpaWluX4/6JviFUzVjrH9K493Ve3n92z2M6NqUTs1jePrfO7m0XSIXt4nnpeW/cHmHRjw/slMAI5aGwmq18s033zBw4ECCg4MDHY6cIfS5En/Q50r8RZ8t8Qd9rqQqubm5pKSkVPsMqoSIizZt2gBlWaTKOI45zq1K69atndvp6el06lTxAbqy/tq0aUNmZibp6elVxmEymdyuU1uO61d2vapidRUaGkpoaGiF/QkJCT5J3PhNqMt0nsREomOzMIdGEBIRjTUoAnNoBE0bJdKlXVPMqw5yIN9EYmJi4OKVBsNqtRIREUFiYqL+sRaf0edK/EGfK/EXfbbEH/S5kqo4PhPVlW1QUVUX3bp1AyAjI6PSwqGbNm0CoHv37tX2FxMTQ7t27dzaeduf43117dq3b+9xWd6aclxvx44dFBUVVTheWFjI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TpzInj17SElJYeXKlW7JEICgoCAmTZrEjBkzAPjTn/7Ezz//7Dzu2P/www87kyEAwcHBvPrqqzRr1ozvv/+eFStWnIa78Q8lREQ8cF1219MKMw7OlWaO5fo9JhEREREREW/s2bOHjz/+GIAXXniBuLi4Ss+dMGECXbp0wWq18vzzzwOQk5PDrl27ALj88ssrtAkPD6dv374AzJ8/38fRnz4a4y/igeuyuwlVJETaNY5iQ1qmVpoREREREZF6Y9GiRdjtduLi4hg+fHiV55pMJm699Va2bdvGwoULMQyDvLxTzzeJiYke2yUlJQGwefPmSvt+6aWX+OWXXzCZTLRq1YohQ4bQvXv3WtyRfyghIuKBaw2RKhMijbT0roiIiIhIfWIYBoVWW6DDqJXwYAumcvUMa8ORpOjWrRtBQdU/9vfs2ROA48ePs2/fPpo0aYLFYsFms7Fnzx46dOhQoc2ePXsASEtLq7TfSZMmub2fPHkyV155Je+//z7Jycle34+/KCEi4oHrKjPVjRABJUREREREROqLQquNC/78daDDqJWf/noFESF1f0w/duwYgNdJB9fzjh07Rps2bbjkkktYtWoVb7/9NldffbXb+bt372blypVA2fSa8m6++WbGjBlD165dSU5OZv/+/SxdupSpU6fyn//8hyFDhrBhwwbCwsJqe4s+oRoiIh6YvRwh0j65LCGyL6MAq83u97hERERERER8zTAM57bNVja65s9//jMmk4kvv/ySP/7xj+zevZucnByWLVvGVVdd5TzfbK6YVvjXv/7FddddR+vWrQkLC6N9+/bce++9bNy4kdjYWH744Qfeeust/99YNTRCRMQDb2uINIkJIyo0iLziUvZl5NOucfTpCE9ERERERCoRHmzhp79eEegwaiU8uOLqlrXhqO9x5MgRr84/evSoc7tRo0ZAWTHVt99+m4kTJzJr1ixmzZrlPKdly5Y8/fTTTJ48mYSEBK/jSklJYdy4cbzyyissWrSIBx980Ou2/qCEiIgHbiNEIipPiJhMJto1jmLr/ix2HMxRQkREREREJMBMJpNPpp00ZD169ODDDz8kNTWV0tLSauuIbNiwAYDY2FhSUlKc+++66y6uvvpq5s+fz//+9z9MJhPdunXjxhtvZO7cuQB06tSpRrE56pEcOHCgRu384ez+lIhUwtsRIgBdW8axdX8WW/dncV3X5v4OTUREREREpErXXnstkyZNIjs7my+//JKRI0dWeq5hGHzwwQcAXHfddRWmwDRp0oSJEydWaLdq1SoAhgwZUqPYMjIyAIiODvwvk1VDRMQD11Vm4r1IiABs3Z/lx4hERERERES807ZtW8aMGQPAI488QlZWVqXnzpw5k+3btxMSEsKjjz7qVf979+7ls88+IyoqijvuuMPruOx2O5988gkAF198sdft/EUJEREPXJOiiV4mRHYczKGkVIVVRUREREQk8N544w3atGlDWloagwYNYseOHW7HS0tLeemll3jggQcAmD17Nh07dnQeLykpYcuWLRX6/fnnn7n66qspLCzkxRdfJDEx0e34v/71L3bu3Fmh3dGjR/nd737H1q1bCQ4O5r777vPFbdaJpsyIeGCuwQiR1okRxEcEc6LAyv8O5dDlZIJEREREREQkUBISEli1ahUjRoxg8+bNdOrUiYsuuoi2bdtSUFDA2rVrOXbsGDExMTz//PPcfvvtbu0LCgro3r0755xzDueddx5xcXHs3buXDRs2YLfb+etf/8rdd99d4bqffvopt9xyC+3bt+eCCy4gMjKS9PR0tm7dSl5eHhEREbz//vvOWiKBpISIiAdRYUFYzCYiQyzEhFX9bWIymejSMo5vdx5jS/oJJURERERERKReaNGiBRs2bGDevHnMmzePjRs3snXrVqxWKwARERGkpqbStm3bCm0jIiJ44IEHWLVqFevWrSM/P5/GjRszduxY7r///kqnvNx+++1ER0ezdetWvv/+e7KysggPD6ddu3YMHjyYe++9161wayApISLiQUxYMO/cfhExYUGYXEaLVKbryYSI6oiIiIiIiEh9Yjabuemmm7jpppuc+7Kzsxk4cCBbtmxhwoQJLFy4kNDQULd2ISEhvPLKKzW+3vXXX8/1119f17BPC9UQEanEwPMa06O1d2tqq7CqiIiIiIg0FLGxsXz99dd06NCBpUuXcuONN1JaWhrosE47jRAR8QFHQmRvRgEn8kuqrTsiIiIiIiISSI0aNWL58uW8/fbbGIbB5s2b6dWrV6DDOq2UEBHxgbiIEM5JimTP8Xy2Hshi4HmNAx2SiIiIiIhIlZo1a8bUqVMDHUbAaMqMiI84p82kZwU0DhEREREREameEiIiPtK1VRygOiIiIiIiIiINgRIiIj7iGCGy7UAWhmEENhgRERERERGpkhIiIj5yfpMYQoLMZBVY2ZtREOhwREREREREpApKiIj4SEiQmQubxQCwdf+JAEcjIiIiIiIiVVFCRMSHuraMB1RYVUREREREpL5TQkTEh1RYVUREREREpGEI8mfnR44cYcWKFaSmpnLkyBFOnDhBfHw8ycnJ9OjRg0GDBpGcnOzPEEROq24nC6v+dCiHIquNsGBLYAMSERERERERj3yeELFarcybN4833niDDRs2AHhcccNkMgHQq1cv7r33XsaMGUNwcLCvwxE5rVrEh5MYGUJGfgk/Hcqhe6v4QIckIiIiIiIiHvg0IfLBBx8wZcoUDh06hGEYNGrUiD59+tCxY0cSExOJiYkhOzubjIwMfvzxR9auXcu6detYv349kydPZtq0adxyyy2+DEnktDKZTHRtGceKn4+yJT1LCREREREREZF6ymcJkT59+rBhwwaSkpK4//77ueOOO+jSpUu17bZu3cp7773HRx99xO23387MmTNZs2aNr8ISOe0cCRHVEREREREREam/fFZUdffu3Tz33HOkp6fz8ssve5UMAejatSszZsxg//79PPvss+zatctXIYkExKnCqlp6V0REREREpL7yWUJkz549TJo0idDQ0Fq1Dw0N5ZFHHmHPnj2+CkkkILq0jMNkgv2ZhWTkFQc6HBEREREROYsZhsG8efO44YYbaNmyJWFhYcTHx9O1a1ceffRR0tPTPbbbu3cvJpOpytfkyZMrvW5JSQnTp0+nS5cuREZGEh8fz4ABA5g/f76/brXGfDZlJiYmpl71IxIoMWHBtG0UxS9H89i6P4vBHbSSkoiIiIiInH4HDx7k+uuvZ8OGDZhMJnr06EHfvn0pKChg7dq1PP/887z66qu8+OKL3HvvvR77iIyMZNSoUR6P9ejRw+P+goIChgwZwpo1a4iLi+PKK68kLy+PlStX8t133zFp0iReeOEFn91nbfl12V2Rs1XXlnFKiIiIiIiISMCcOHGCfv36sWfPHrp168YHH3xAx44dncdLS0uZMWMGjz32GBMnTsRms3H//fdX6CcpKYn333+/Rtd+/PHHWbNmDZ06dWLlypUkJSUBsHnzZgYMGMCLL77IgAEDuOaaa+p0j3XlsykzInJK15ZxACqsKiIiIiIiATFx4kT27NlDSkoKK1eudEuGAAQFBTFp0iRm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li1bRmJior8u4RcPPvggM2bMICgoiEGDBhEVFcXKlSt57LHHWLRoEUuXLiU8PNzr/ubPn89NN91EaWkpPXv2JCUlhU2bNvH666/z6aefsnr1atq1a1eh3a5du+jXrx9Hjx7lnHPOYcSIEaSlpTF//ny++OILPvnkE66//voK7QoKChgyZAhr1qwhLi6OK6+8kry8PFauXMl3333HpEmTeOGFFyqNt2/fvh7jAbBYLF7ft5ziWGlm+4FsbHYDi9kU2IBEREREROSs16hRI5YvX87bb7+NYRhs3ryZXr16BTqs08pvCZGtW7fSv39/VqxYQZMmVU8TsFqtBAcH+ysUr33xxRfMmDGDqKgovvvuO+f6ycePH2fQoEGsXr2aJ598ssqEgquDBw9y++23U1payqxZs7j77rsBsNls3HHHHXz44YfcfPPNrF+/HpPp1EOyYRiMHTuWo0ePcuutt/Lee+85kxGzZ89m/Pjx3HbbbezevbvC1/bxxx9nzZo1dOrUiZUrVzoL3GzevJkBAwbw4osvMmDAgEoL2Pz+97/njjvuqNHXTap2bnI0ESEW8opL+fVYHucmR1ffSERERERExM+aNWvG1KlTAx1GwPhtysyjjz7K//73P/r160d6enql582bN4/zzz/fX2HUyDPPPAPA5MmTnckQgKSkJGbOnAnA66+/7vV0oFdeeYWCggIuv/xyZzIEykZavPnmm8TGxrJx40aWLl3q1m7JkiVs2bKFuLg4Zs6c6TYy4+6772bw4MHk5eUxY8YMt3YnTpzgzTffBODNN990q/bbo0cPHnvsMQD+/ve/exW/+IbFbKJT81gAtqZnBTYYERERERERAfyYEHn22Wf5+9//zq+//kq/fv3YvXu32/F169ZxySWXcPPNN7N3715/heG13377jY0bNwJw8803Vzh+6aWX0rJlS4qLi1m8eLFXfS5YsKDS/qKiohg+fDgAn3/+ucd2w4cPJyoqqkJbR3/l2y1evJiSkhJatWpF3759K223bt06Dh486NU9iG846ohsUR0RERERERGResFvCRGAKVOm8MYbb3DgwAH69+/PDz/8wN69e7nxxhvp27cv69ato1WrVvzzn//0Zxhe2bJlC1C2VnNKSorHcy666CK3c6uSm5vLL7/84tbO2/4c76trt3v3bvLz871ud84555CQkACUTWny5JtvvmHSpEncfffdTJkyhQULFlBcXOzxXPFet5N1RFRYVUREREREpH7w+7K799xzDzExMYwbN45+/fpRXFxMcXExCQkJPP7440ycOJGQkBB/h1GttLQ0AFq1alXpOS1btnQ7tyquo14q67Oy/qqLxdHOMAz27t1Lx44dvWoHZetQZ2ZmVnoPc+bMqbCvadOm/OMf/+DKK6+stF+pWteW8QDsPJxDQUkpESFa8VpERERERCSQ/P5UZrfbyc/PJzo6mhMnTmAymRg7dqyzhkZ9kZubC0BkZGSl5zimr+Tk5HjdX1V9VtZfdbG4TqNxbVuXe+jSpQszZsxg8ODBtGrVisLCQrZt28ZTTz3FmjVrGD58OEuXLmXAgAGV9g04E17l47NarbVetvh0cC3p6484EyMsJMeEciSnmC37Mri4TYLPryH1k+PzVJ8//9Lw6HMl/qDPlfiLPlvia1arFcMwgLJfEtvt9gBHJKeD3W7HMAysVmu1K6B6+/PGrwmRBQsW8MQTT7Bz504Mw+CSSy5h7dq1LF++nLS0NLp27erPy0sNPPTQQ27vo6OjGTJkCJdffjnXX389X375JQ8++GClU20cpk2bxl/+8pcK+5cuXUpERIQvQ/ap61y2va0RU1PJQWaOYGbesvUcb2745RpSfy1btizQIcgZSJ8r8Qd9rsRf9NkSXwkKCnKutun6i2g5s5WUlFBYWMh///tfSktLqzy3oKDAqz79lhC55JJLWL9+PYZh0L17d1588UUuu+wy3nvvPe6++24GDRrEokWLPBb/DITo6LKlUF1rcpSXl5cHQExMjNf9Ofr0NBqmsv6io6PJzMysNBZHu/JtfX0PACaTib/85S98+eWXbNu2jf379zun7HgyZcoUHn74Yef7nJwcWrZsydChQ72+ZkC4lHEZNmyYXy5xIDqN7Ut3UxTVlGHDuvrlGlL/WK1Wli1bxpAhQ+rF8uJyZtDnSvxBnyvxF322xNeKioqcK5lGR0djMpkCHJGcDkVFRYSHh9O/f3/CwsKqPNebWR3gx4TIunXraNGiBX//+9+59dZbnfvHjRtHVFQUt9xyC1dccQULFixgyJAh/grDa23atAFg//79lZ7jOOY4tyqtW7d2bqenp9OpUyev+2vTpg2ZmZmVLlfsaGcymdyu4+inqmWODxw44PU9OHTo0MGtfVUJkdDQUEJDQyvsDw4ObjD/APorzh5tEoHdbD+Q02C+FuI7Del7QBoOfa7EH/S5En/RZ0t8xWazOZMgJpMJs9mva4VIPWE2mzGZTF79LPH2Z43fPjlPP/00u3btckuGOIwePZoFCxZgt9sZPny4c5nZQOrWrRsAGRkZlRYc3bRpEwDdu3evtr+YmBjatWvn1s7b/hzvq2vXvn17t3oi1bXbs2cPmZmZwKn79UZGRoZz23Xki9RMp+axmE1wOKeIw9lFgQ5HRERERETkrOa3hMgTTzxR5TCWYcOGsWTJEoKDgxk7dqy/wvBaixYt6NmzJwBz586tcHz16tXs37+f0NBQr6dUXH/99ZX2l5eXx6JFiwC44YYbPLZbuHChx+kvjv7Ktxs2bBghISGkp6fz/fffV9qud+/eNGvWzKt7APj444+BsiTPeeed53U7cRcZGsR5TcqmDW3dfyLA0YiIiIiIiJzdAjq26LLLLmP58uX1ZtTB448/DsCzzz5Lamqqc39GRgYTJkwAYOLEiW71QBYsWMD555/P4MGDK/T34IMPEhERwfLly3n77bed+202GxMmTCArK4uePXsydOhQt3ZXXXUV3bp1IysriwkTJmCz2ZzHZs+ezYoVK4iKiuKBBx5waxcfH88999wDwIQJE9xGdqSmpjJ9+nSgLFnlauvWrSxcuLBCYRq73c67777r/Lrcf//9GuZYR11bxgGwZX9WQOMQERERERE52wV8stXFF1/Mt99+G+gwABgxYgT3338/eXl59O7dm6uuuopRo0bRrl07fvjhB/r27cvTTz/t1iY7O5udO3fy66+/VuivWbNmvP/++1gsFu6++2569+7N2LFjOffcc/nggw9ITk5m7ty5FYoAmUwmPvroIxo1asScOXM499xzGTt2LL169WL8+PEEBQUxZ84cZ2VlV8888wx9+vRh+/bttG/fnlGjRnHVVVfRu3dv8vLyePjhh7nmmmvc2uzdu5frrruOxo0bc/nll/O73/2Oq6++mpSUFH7/+99TVFTETTfdxNSpU33wVT67dTuZENmanhXQOERERERE5OxgGAbz5s3jhhtuoGXLloSFhREfH0/Xrl159NFHq6xBCXDkyBEmTpxISkoKoaGhJCcnM3r0aLdBBOW1adMGk8lU6at3796+vs1a8VlC5IEHHnAbkVATF154IQDHjh3j/vvv91VItTJjxgzmzZtHnz59WLNmDYsXL6ZFixY8++yzrFy5kvDw8Br1N3r0aNavX88NN9zAnj17WLBgATabjXvvvZdt27Y564yUd95557F9+3buvfdebDYbCxYsIC0tjRtuuIH169c7p9WUFxERwbfffsu0adNo3rw5ixcvZu3atfTp04dPPvmEF198sUKbLl268OCDD9KxY0d+/vlnPv/8c1asWAHAqFGj+Pe//83cuXMJCvLrKs1nhW6t4gDYtO8E/95+KLDBiIiIiIjIGe3gwYPOX8x/8cUXNGnShBEjRtCvXz9+++03nn/+ec4991zeeOMNj+137dpF586deeONNzCbzYwYMYLWrVszf/58evXqVW090JEjR3L77bdXeF199dX+uN0aMxmGYfiio6CgICIiIrj33nu58847ad++vddtd+7cyTvvvMOsWbMoLCzEarX6IiSpB3JycoiNjSU7O7t+L7v7lMuyyE9l+/VSkz7ZxmepBzCb4IXRXbihewu/Xk8Cy2q1snjxYoYNG6YpZ+Iz+lyJP+hzJf6iz5b4WlFREXv27CEpKYmkpCStMlOJEydOcNFFF7Fnzx66devGBx98QMeOHZ3HS0tLmTFjBo899hg2m40ZM2a4DVAwDIMePXqwZcsWbr31Vt577z0sFgtQVsph/PjxREVFsXv37gqzF9q0acO+fftIS0ur0QqnVSkqKiItLY2UlBSvlt315jnUZ5+cjRs30rlzZ6ZPn87555/PpZdeytSpU/nPf/7Dvn37yMvLA8qKie7bt48lS5bw5z//mT59+nDBBRfw4osv0qVLFzZu3OirkETqpedGdebGi1piN2DSp9uYu77qIWoiIiIiIiI1NXHiRPbs2UNKSgorV650S4ZA2aCGSZMmMWPGDAD+9Kc/8fPPPzuPL1myhC1bthAXF8fMmTOdyRCAu+++m8GDB5OXl+ds3xD5bA5Et27dWL16NfPnz+fll19mzZo1rF27tso2jsEpl1xyCQ899BAjR470VTgi9ZbFbGLaDZ0ICzbzz7X7eHzBDxRZbdx5aUqgQxMRERERkTPAnj17nKuFvvDCC8TFxVV67oQJE3j77bfZtm0bzz//PO+++y6AczrM8OHDiYqKqtDu5ptvZsWKFXz++edMmzbN9zdxGvi8KMSoUaMYNWoUW7du5YsvvmDlypVs2bLFbfnYyMhIunfvzsCBAxkx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GDBggC9C9zuf1RBp164dN910E88//zwrV64kJyeHefPm0bJlS5YtW0Z+fj7jx4/n66+/VjJEpBYuaBbDvLt70zg6lJ8P53LjrLUczi4KdFgiIiIiItLAxMbG8vXXX9OhQweWLl3KjTfe6NXyvGcan40Q2bNnD2lpaXzyySfOfSkpKc6ldEaNGsW0adMICvLboBQR36gnRVU9aZ8czSfj+/C7d9bz67F8xsxay9w/9KJFfESgQxMRERERkQakUaNGLF++nLfffhvDMNi8eTO9evUKdFinlc+yE5988gmbN29m8+bNpKamkpmZyZ49e5zHP/vsMz777DNat25N9+7d6dGjB927d6d79+40atTIV2GInPHaJEUyb3xvbn57PemZBYx5ay1z/9CbNkmRgQ5NREREREQakGbNmjF16tRAhxEwPkuIjBo1ilGjRjnf79u3z5kgcSRJjh8/zt69e9m7dy8LFixwntu8eXPS09N9FYpIHdXfESIOLeIjTo4UWcevx/IZPWstc+68mA5NYwIdmoiIiIiISIPgt/krrVu3pnXr1txwww3Offv373dLkGzevJmjR4/y22+/+SsMkTNWk9gw5o3vwy3vrOfnw7lc+9pqxvVtw32D22tZXhERERERkWqc1oIeLVu2pGXLlowYMcK577fffmPz5s2nMwyRqtXjGiLlJUWF8vHdvfnTp9tY/r+jvL0qjQVbfuPRK89nVPcWmM2mQIcoIiIiIiJSL/lslZnaat68OcOHDw90GCIuGk5CBCAuIoR3bu/J++N6ck6jSI7nlfDo/O1c/+YatqSfCHR4IiIiIiIidWb44RfXAU+IiNQ7hj3QEdTKgPMa858H+vPEsA5EhQaxbX8W189cw6RPtnE0V8vzioiIiMiZwWwue4y12xvm/9uldmw2G3Dq798XlBARKa8BTZkpLyTIzB/6n8PKP13G6B4tAPgs9QCDXviO2f/9lZJS/aMhIiIiIg1bcHAwZrOZkpKSQIcip1Fubi7BwcEEB/uuXqISIiLlNdARIq4aR4fx/OguLJhwCV1axpFXXMozi3/mylf+yzc7jwY6PBERERGRWjOZTERERJCbm+scNSBntsLCQnJycoiOjsZk8l2dxNNaVFWkYWi4I0TK69YqngX3XMJnqQeY/p+d7Dmez7j3NjL4/MY8ec0FtEmKDHSIIiIiIiI1lpiY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E0+4HV+9ejX79+8nNDSUYcOGedXn9ddfz/PPP8/cuXMZN26c27G8vDwWLVoEwA033FCh3TvvvMPChQvdltV1mDt3rsd2w4YNIyQkhPT0dL7//nv69u3rsV3v3r2dS+76694bNKvLkruOB+SYU18vLhwJ184oGzYvgRGRUPZqUW6JacOAvKMVkyQZZdNxsBXD8V1lr/KCI08mSdqWG1nSruxaZ0qyxFpUefKiKKuaBEcOdR9jaoKwmCqSF3FVJzeCG1btGBERERGpv/yeELHb7eTn5xMdHc2JEycwmUyMHTuWN998s94ty/v4449z/fXX8+yzz3LVVVc5R0NkZGQwYcIEACZOnOgW94IFC5gyZQrNmzdnxQr330Y/+OCDvPHGGyxfvpy3336bP/zhD0DZKiYTJkwgKyuLnj17MnToULd2V111Fd26dWPLli1MmDCBf/zjH1gsZb/VnD17NitWrCAqKooHHnjArV18fDz33HMPM2bMYMKECaxcudK5yk9qairTp08HqJDwqO29n7EctQYsLlN/LrgO9nwL514JPe44cx6OzzQmE0Qnl73auCcEsdsg5zf3JIkjcXJiH1jLirviobgrYXEVp984Rpec7sSY3V5WR6OmozMc723FVXTupaAwD8kKL0drhMaULSEtIiIiIhJgfk2ILFiwgCeeeIKdO3diGAaXXHIJa9euZfny5aSlpdG1a1d/Xr7GRowYwf3338+rr75K7969GTx4MJGRkaxYsYKsrCz69u1bYXpPdnY2O3fupKio4lDwZs2a8f7773PTTTdx99138+6779KmTRs2btzInj17SE5OZu7cuZjKPVybTCY++ugj+vXrx5w5c1i9ejU9e/YkLS2NDRs2EBQUxJw5czyu3vPMM8+wYcMG1q5dS/v27Rk0aBD5+fmsWLECq9XKww8/zDXXXOOTez9jOUeIuIxcimkGN88LTDziG2ZLWQ2RuFbQdpD7sdISyEovN7LkZN2SnANlCYXfNpe9yotKrpgkSWwH8SmVj2awFnqRwMjycPxkLQ2fjNLwXCej2tEaYbEapSEiIiIiZwS/JUQuueQS1q9fj2EYdO/enRdffJHLLruM9957j7vvvptBgwaxaNGiCtM6Am3GjBn07duXN954gzVr1mC1Wmnbti2TJ0/moYceqvH0ntGjR3POOefwzDPPsGrVKrZs2ULT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jUaI1EpGYQZ/WPYHdp/Y7fG4xWRxH5kRUslIDdekR0gM4UHhmEym03w3IiIiIiJypjptCZG77rqL3bt3U1pa+6HvIqeVaojU2PHC4/z+69/za/avJIUn8VCPh0gKS3JLckQFRymxISIiIiIiAXdap8wYhnE6LydSN1plpkaOFhzlrq/vYm/OXhpHNObdoe/SJrZNoMMSERERERHxSDVERCqj2hNeO5x/mLu+vov03HSaRDbhH0P/QcuYloEOS0REREREpFJKiIh4YrKARd8e3jiYd5A7v76T3/J+o3lUc94Z+g4tolsEOiwREREREZEq6YlPxBMVVPXK/tz9/P7r33Mw/yAto1vy7tB3aRrVNNBhiYiIiIiIVEsJERFPrPmBjqDeS89J586v7+RIwRFax7Tm3aHvkhyZHOiwREREREREvGIOdAAi9VLyhYGOoF5Ly05j3H/GcaTgCCmxKbx3xXtKhoiIiIiISIOiESIi5f1+JUTr4b4yv2b9yl1f30VGUQbt4trx9tC3SQpPCnRYIiIiIiIiNaKEiEh5LXoEOoJ6a9eJXfxh6R/ILMrk3PhzeXvo2ySEJQQ6LBERERERkRpTQkREvPJz5s/8YekfyCrOokNCB2YPmU1cWFygwxIREREREakV1RARkWrtyNjBXV/fRVZxFhcmXsjbQ99WMkRERERERBo0JUREpErbj23nD1//gZySHLo06sLsobOJDY0NdFgiIiIiIiJ1oikzIlKprUe38sflfyTfmk/3xt2ZeflMIoMjAx2WiIiIiIhInZ22hMi1117LoUOHTtflRKSONh/ZzITlEygoLaBnk568Puh1IoIjAh2WiIiIiIiIT5y2hMhzzz13ui4lInW04dAGJq6cSGFpIb2b9ubVQa8SHhQe6LBERERERER8RjVERMTNmoNrmLBiAoWlhfRt3pfXBr2mZIiIiIiIiJxxlBAREadVB1Zx34r7KLYV079Ff2YMnEFYUFigwxIREREREfE5JUREBIBv93/LA988QIm9hEEtB/HKgFcItYQGOiwRERERERG/UEJERFixbwUPffsQVruVIa2H8MKAFwi2BAc6LBEREREREb9RQkTkLPf13q+Z9N0kSu2lXNXmKp7r/xzBZiVDRERERETkzKaEiMhZbPGexTz238ewGTauOecanun3DEHm07b4lIiIiIiISMAoISJyllr06yKmrJ6CzbAxot0I/tb3b0qGiIiIiIjIWcOvTz9HjhxhxYoVpKamcuTIEU6cOEF8fDzJycn06NGDQYMGkZyc7M8QRMSDBbsXMHXNVAwMRp07iid7P4nZpPyoiIiIiIicPXyeELFarcybN4833niDDRs2AGAYRoXzTCYTAL169eLee+9lzJgxBAerboGIv32y8xOeXvc0ADeedyOP93pcyRARERERETnr+DQh8sEHHzBlyhQOHTqEYRg0atSIPn360LFjRxITE4mJiSE7O5uMjAx+/PFH1q5dy7p161i/fj2TJ09m2rRp3HLLLb4MSURcfPTzRzyz/hkAbulwC4/2fNSZnBQRERERETmb+Cwh0qdPHzZs2EBSUhL3338/d9xxB126dKm23datW3nvvff46KOPuP3225k5cyZr1qzxVVgictIHP33AcxufA2Bcx3E81OMhJUNEREREROSs5bNx8rt37+a5554jPT2dl19+2atkCEDXrl2ZMWMG+/fv59lnn2XXrl2+CklETnrvx/ecyZA/dPqDkiEiIiIiInLW89kIkT179hATE1Pr9qGhoTzyyCOMHz/eVyGJ1EuH8g5Rai+lZUzL03K92dtn89qW1wC4p8s93NPlHiVDRERERETkrOezhEhdkiH+6Eekvsm35jMjdQYf//wxBgbt49szpPUQrmh9BefEnePz6xmGwVvb3mLmtpkATOw6kfFdlHAUEREREREBPy+7KyJlvtv/HU+ve5ojBUcAsJgs7D6xm90ndjNz60zaxrZlSJshDG09lHZx7eo8gsMwDF7b8hpv//A2AA/1eIg7L7yzzvchIiIiIiJyplBCRMSPjhceZ/qG6fxn738AaB7VnKl9pnJB4gV8s/8blu1bxpqDa/g1+1d+3fYrb217izYxbRjaZihDWw/l3Phza5wcMQyDl1Nf5r0f3wPgkYse4baOt/n83kRERERERBoyJURE/MAwDL745Qte2PQCOSU5mE1mbr/gdu7peg/hQeEAjGg3ghHtRpBTksN3+79j6b6lfP/b9+zN2cvs7bOZvX02raJbMbTNUIa0HkKHhA7VJkcMw+D5Tc/zwU8fADD54sn8rsPv/H6/IiIiIiIiDY0SIiI+tj9nP39Z9xfWH1oPQIeEDjx1yVNckHiBx/NjQmK4tu21XNv2WvJK8vjuwHcs27eM1b+tJj03nXd+eId3fniHFlEtnNNqOiZ2rJAcMQyDaRum8dHPHwHwZO8nGXPeGP/erIiIiIiISANVp4TI0aNHiY6OJjw8nMLCQnJzc2ncuLGvYhNpUErtpcz5aQ4zt86k2FZMqCWUe7vey60X3EqQ2btvtaiQKK4+52quPudq8q35rDqwiqX7lrLqwCoO5B3gvR/f470f36NZZDOGtB7CkDZD6JzUGQODv637G5/u+hQTJp665CluaH+Dn+9YRERERESk4TLXpfHcuXN54YUXAHjxxRf56KOPfBJUIOXm5vL4449z3nnnER4eTlJSEldffTUrV66sdZ92u51Zs2bRq1cvoqOjiY6OplevXsyePRvDMKpsu3z5coYNG0ZSUhLh4eGcf/75PPHEE+Tl5VXZ7pdffuGOO+6gRYsWhIaG0qJFC+644w727NlTaRuTyVTla+zYsbW6/7PBTxk/cfO/b+blzS9TbCumV9NeLBi+gHEXjvM6GVJeZHAkV6ZcyUsDXuK7G7/jxcte5Io2VxAeFM7B/IP886d/csviWxj62VB+v/T3zmTI032fVjJERERERESkGnUaIXLffffRv39/Ro4cyZIlS1i1apWv4gqIo0eP0q9fP3bt2kXTpk259tprOXLkCEuWLGHJkiXMmDGD++67r0Z92mw2xowZw+eff05ERASDBw8GyhId48ePZ/ny5Xz88ceYzRVzUy+//DIPP/wwJpOJfv36kZyczKpVq3jmmWf47LPPWL16NUlJSRXaff/99wwdOpSCggI6duzIpZdeyo8//sg///lP5s+fz/Lly+ndu3elMd9+++0e9/fq1atG9362WLB7AU+tfQq7YScmJIZHej7CdW2vq/NKMa4igiPKCq22GUphaSFrflvD1/u+5rv933E4/zCH8w9jNpl55tJnuPqcq312XRERERERkTNVrRMic+bMAaBTp07079+f0aNH8+GHHwJw220Nc0WLu+++m127djF48GAWLlxIREQEAIsXL2b48OE8+OCDXHbZZXTu3NnrPl977TU+//xzmjdvzqpVq0hJSQEgLS2NSy+9lE8//ZT+/fszceJEt3Zbtmxh0qRJWCwWFi1axFVXXQVAQUEBw4cPZ8WKFfzxj39k/vz5bu0KCgoYM2YMBQUFTJkyhWeeecZ57PHHH2fatGmMGTOGnTt3Eh4e7jHm999/3+v7E/jH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5qeffmL58uW0bduWfv36cfToUb777jsMw2DGjBl07ty5Qrv09HR27tzJ8ePHKxy77777+O9//8uCBQu48MILufzyywFYvnw5BQUFjBo1igkTJlRo1717d1588UUefvhhhg0bxmWXXUbjxo1ZtWoVhw4d4rzzzuOtt96q0C4iIoJPPvmEoUOH8swzz7Bw4UIuvPBCfvzxR3788UciIyP59NNPCQ8Pd2v36aefcsstt9C+fXsuuOACIiMjSU9PZ+vWreTl5REREcH777/vrCUikFOSQ4m9BChbdldEREREREQaDr+NEIGykQ9vvPEGBw4coH///vzwww/s3buXG2+8kb59+7Ju3TpatWrFP//5T3+G4bXGjRuzadMmJk+eTFRUFF9++SXbt2/niiuuYPny5dx///017tNisTB//nzeeustLrjgAlasWMGKFSvo2LEjb731Fp988kmF0SEODz30EMuWLeOKK65g+/btfPnll0RFRTFlyhQ2btxIUpLnh/C+ffuybds2brvtNjIzM/nss8/IzMzktttuY9u2bfTu3btCm9tvv51bbrmF0NBQvv/+ez755BO2bdtGu3btmDRpEj/++COjR4+u8f2fyRzTZeJD4wmxhAQ4GhEREREREakJvy+7e8899xATE8O4cePo168fxcXFFBcXk5CQwOOPP87EiRMJCak/D5MxMTFMmzaNadOmed3m22+/rfK42Wxm/PjxjB8/vsbxXH755c5RJTXRrl27GiWarr/++gr1SKRqjukyjSJUP0RERERERKSh8XtCxG63k5+fT3R0NCdOnMBkMjF27FjefPPN07Ysr4g/HC08WVBVCREREREREZEGx69TZhx1M+655x5OnDjBJZdcApTVz3AtMCrSEDkLqoaroKqIiIiIiEhD47eEyCWXXMKoUaP4+eef6datG9988w2rV6/mnXfe4cSJEwwaNIjvv//eX5cX8TvnkrsaISIiIiIiItLg+C0hsm7dOpo3b84///lPNm3axGWXXQbAuHHjmDt3Lvn5+VxxxRUsW7bMXyGI+NWxQo0QERERERERaaj8lhB5+umn2bVrF7feemuFY6NHj2bBggXY7XaGDx/OggUL/BWGiN+oqKqIiIiIiEjD5beEyBNPPEFYWFilx4cNG8aSJUsIDg5m7Nix/gpDxG8cRVUbR2iEiIiIiIiISEPj16Kq1bnssstYvnw50dHRgQxDpMbshp3jBccBaBSuESIiIiIiIiINTUATIgAXX3wx3377baDDEKmRE0UnKDVKMWEiMTwx0OGIiIiIiIhIDQU8IQJw4YUXBjoEkRpxFFRNDE8kyBwU4GhERERERESkpnyWEHnggQfIyMioUx/Hjh3j/vvv91FEIv7jXHJX02VEREREREQaJJ8lRF5//XVSUlKYMmUKu3fvrlHbnTt38sgjj9C2bVvefPNNX4Uk4jeOhIgKqoqIiIiIiDRMPhvrv3nzZiZOnMj06dN57rnn6NOnD4MHD6ZPnz506NCBxMREoqKiyMvLIyMjg59++om1a9eybNkyNmzYgGEY9O3bl9dee81XIYn4jZbcFRERERERadh8lhD56KOPmD59OocOHeLll19mzZo1rFmzBpPJVGkbwzAAuOSSS3jooYcYOXKkr8IR8SvnkrvhGiEiIiIiIiLSEPksIfL8889z/Phx3n33XUaNGsWmTZv46quvWLlyJVu2bCE/P995bmRkJN27d2fgwIGMGDGCrl27+ioMkdNCI0REREREREQaNp8lRCwWCzabzfm+V69eTJgwgf/+978AFBQUkJ2dTVxcHOHh4b66rEhAqIaIiIiIiIhIw+azhEhCQgIHDhxwvjcMw21USEREBBEREb66nEhAOZbd1SozIiIiIiIiDVOtVpkpKiriwQcfdNvXvXt3vvvuO2bNmkVxcbEvYhOpl0rtpWQUli0xrSkzIiIiIiIiDVONEyKrV6+mc+fOzJ8/323/o48+CsCECROIj4/HZDKxefNm3nnnHVJTU7Farb6JWCTAMgozMDCwmCwkhCUEOhwRERERERGphRolRB566CEGDBhASkoKW7ZscTs2cOBAVq5cyeDBg521RH744QfGjx9Pz549iY6O5qKLLmL8+PHMnj2bzZs3K0kiDZJjukxSeBJmU60GWYmIiIiIiEiA1aiGyIwZM7jiiitYsmSJx+P9+vVj6dKlFBYWEhkZycUXX8xFF13Epk2b2L59O6mpqaSmpvLOO+8AEBwcTMeOHenRowezZ8+u+92InAYqqCoiIiIiItLw1ejX28OGDePrr7/mj3/8Y5V1QhyryFxwwQW8/vrrrFu3jtzcXLZu3cq7777LPffcQ8+ePTGbzWzZsoV33323bnchcho5l9xVQVUREREREZEGq0YjRL766iv++c9/8vDDD7N+/foK02Zc/frrrxQUFDjfWywWOnfuTOfOnRk3bhwANpuNHTt2sHnz5lqGL3L6HS0sGyGigqoiIiIiIiINV40LINx+++38+OOPtGrVqsrzUlJS6NixY5XnOJIkjgSJSEPgGCGiKTMiIiIiIiINV60qQjZt2pQvv/zS17GINAjOESKaMiMiIiIiItJgaYkMkRrSCBEREREREZGGTwkRkRpyFlVVDREREREREZEGSwkRkRoosZVwovgEAI3DNUJERERERESkoVJCRKQGjhceByDYHExsaGyAoxEREREREZHaUkJEpAaOFpQVVG0c0RiTyRTgaERERERERKS2lBARqYFjhSfrh2iFGRERERERkQZNCRGRGnCMEFFBVRERERERkYZNCRGRGtCSuyIiIiIiImcGJUREakBTZkRERERERM4MSoiI1IBrUVURERERERFpuJQQEakBx5QZ1RARERERERFp2JQQEamBo4UnR4iEa4SIiIiIiIhIQ6aEiIiXCksLyS3JBTRlRkREREREpKFTQkTES8cLjgMQHhROZHBkgKMRERERERGRulBCRMRLzukyEY0xmUwBjkZERERERETqQgkRES85C6pqyV0REREREZEGTwkRES85ltzVCjMiIiIiIiINnxIiIl46Vlg2QkQrzIiIiIiIiDR8SoiIeEkjRERERERERM4cSoiIeMk5QkRL7oqIiIiIiDR4SoiIeElFVUVERERERM4cSoiIeMkxZUYjRERERERERBo+JUREvJBvzaegtACApPCkAEcjIiIiIiIidaWEiIgXHKNDooOjiQiOCHA0IiIiIiIiUldKiIh4wVk/RCvMiIiIiIiInBGUEBHxwtFCLbkrIiIiIiJyJlFCRMQLJ4pOAJAQmhDgSERERERERMQXlBAR8UJuSS4AMaExAY5EREREREREfEEJEREv5JTkABAdEh3gSERERERERMQXlBAR8YJzhEiIRoiIiIiIiIicCZQQEfFCTrFGiIiIiIiIiJxJlBAR8YJjyoxGiIiIiIiIiJwZlBAR8YJqiIiIiIiIiJxZlBAR8YJWmRERERERETmzKCEi4gXnlJlgJURERERERETOBEqIiFTDardSWFoIaISIiIiIiIjImUIJkXJyc3N5/PHHOe+88wgPDycpKYmrr76alStX1rpPu93OrFmz6NWrF9HR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lMTgwYNJS0vD19eXevXqPf7FAz4+Pnh4eHDr1i3eeecd0tLSzG2LFi0iLCwMe3t7Ro0a9UTO97yxtbVlypQpWZb7iDwu3VvyNOi+kqdB95U8Lbq35GnQfSVPgsl41D40Rci1a9do3bo1UVFRuLi40KZNG65du8bOnTsxDAN/f39GjhyZZZy3tzc7d+5kypQpTJ06NVNbWloar732GsHBwZQqVYoOHToAsH37dpKSkujVqxerV6/OkhAB+PzzzxkzZgwmk4m2bdtSoUIFdu/ezeXLl3F3d2fPnj2UL591R5QePXpw+fJl4EHtk5MnT2Jra8sLL7xg7jNkyBCGDBmSadzp06dp06YN169fp2bNmjRv3pzo6Gj279+PtbU1a9aseWJPpIiIiIiIiIhYkhIifxAfH8/MmTNZt24d586dw87OjhYtWjBu3Djat2+f7ZjcEiLwYKeVf/3rXyxevJiTJ08C0KBBAwYPHszQoUNz3X1l+/btzJ07l/3793Pnzh2qVatGr169mDRpUrbFVuFBgdSzZ8/mep05xXrlyhWmT5/Opk2buHz5MmXKlKFNmzb84x//eGL1SkREREREREQsTQkRERERERERESlyVENERERERERERIocJUSkyFu7di3e3t6ULVsWOzs7mjRpwuzZs0lJSbF0aFIAnT59mq+++go/Pz8aN26MtbU1JpOJ6dOnWzo0KaBSUlIICwvj/fffp3nz5jg6OmJjY0OlSpXo1q0bmzdvtnSIUoB9//33DBgwgCZNmlChQgVsbGwoU6YMLVq0YObMmSQmJlo6RCkkxo8fj8lk0nui/Gl+fn7meyinr3v37lk6TClgrC0dgIgljR49Gn9/f6ytrWnXrh329vb85z//YcKECYSEhBAaGkrJkiUtHaYUIAsWLMDf39/SYUghsnPnTjp27AhApUqVaN26NXZ2dkRGRhISEkJISAhDhw5l4cKFudakEsnOggUL2Lt3L/Xr18fT05Ny5cpx9epVfv75Zw4cOMC3337Lzp07cXV1tXSoUoDt3buXuXPnYjKZ0Gp9eVxeXl7Url0727ZixYo942ikoFNCRIqsDRs24O/vj729PTt37jQXjb1x4wbt2rVjz549fPTRR8yZM8fCkUpB0qhRI8aNG4eHhweenp588sknfPfdd5YOSwowKysrfH19GTVqFG3atMnUtnr1avr1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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "fig, ax = plt.subplots(figsize=(12,4))\n", - "\n", - "ax.plot(nn, error_df.quantile(q=0.95, axis=1), label='Q95')\n", - "ax.plot(nn, error_df.quantile(q=0.5, axis=1), label=\"Q50\")\n", - "ax.plot(nn, error_df.quantile(q=0.05, axis=1), label='Q05')\n", - "ax.set_ylabel(r\"$\\hat{f}(x^*) - f(x^*) \\star K(x^*)$\")\n", - "ax.set_xlabel(r\"Sample size\")\n", - "ax.set_ylim(-0.001, 0.001)\n", - "ax.grid()\n", - "\n", - "ax.tick_params(axis='both', which='major', labelsize=16)\n", - "ax.xaxis.get_label().set_fontsize(16)\n", - "ax.yaxis.get_label().set_fontsize(16)\n", - "ax.legend(prop={'size': 16})" - ] - }, - { - "cell_type": "markdown", - "id": "a049da34", - "metadata": {}, - "source": [ - "Once $n$ is moderately large, we see that the median concetrates about $0$ and we appear to over and under estimate the quantity with roughly equal proportion. This suggests that the two quantities are close and $\\hat{f}(x^*)$ is an unbiased estimation of $f(x^*) \\star K(x^*)$. More trials would smooth out the curves.\n", - "\n", - "However, we also want to understand the rate of convergence so we measure the absolute error. The absolute error only tells us about the magnitude of the error, not the sign." - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "e0b271ac", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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dvHx8decuGbRokVER0ezc+dOsrOzad68Offffz9PPPGE1rCWCqM8FkegPBZHoDwWR6A8FrkxFRpERERERERExGY0R4OIiIiIiIiI2IwKDSIiIiIiIiJiMyo0iIiIiIiIiIjNqNAgIiIiIiIiIjajQoOIiIiIiIiI2IwKDSIiIiIiIiJiMyo0iIiIiIiIiIjNqNAgIiIiIiIiIjajQoOIiIiIiIiI2IwKDSIiItXQoUOHmDBhAm3btsXT05MaNWoQEBBAt27dmDBhAkuXLrV3iOXi448/xjAMRo8ebe9QComIiMAwDNavX2/vUERERMrE2d4BiIiISMX6z3/+w3333UdWVhb+/v6Eh4dTp04dzp8/z86dO4mOjuaLL77g7rvvtneoIiIiUgWp0CAiIlKNnD59mlGjRpGVlcVTTz3FK6+8Qo0aNQq02b59O0uWLLFThNXXJ598QkZGBkFBQfYORUREpExUaBAREalGvvnmG9LT02nYsCFvvfXWNdt06dKFLl26VHBkogKDiIg4Cs3RICIiUo2cPn0agDp16pT42H379vHyyy8THh5Oo0aNcHV1xd/fn5tvvplFixZd85j169djGAYRERFkZWUxdepUWrVqRY0aNQgKCuLZZ5/l8uXLAFy8eJFJkybRrFkzatSoQZMmTfj73//O1atXC/U7evRoDMPg448/5ueff+auu+6iTp06uLu70759e2bOnElOTk6Jr/HEiRM8+eSTtGnTBg8PD7y9venWrRuzZ8++ZhzXk5uby7/+9S/Cw8OpVasWLi4u1K1blw4dOjBx4kSOHj1aoP215mjIn1PiRq8/9nX16lXmzJlDREQEfn5+uLm50bRpU8aNG0diYmKJfy8iIiIloScaREREqpH8b8337NlDTEwMkZGRxT72H//4B3PnzqV169aEhoZSq1YtEhISWLduHTExMWzZsoV//OMf1zz2ypUrDBo0iLi4OCIiIggODuaHH35gxowZ7Nu3j/nz59OrVy/OnTtHnz59aNmyJRs2bGDq1KmcPn2a995775r9btu2jXHjxlG/fn0iIyM5f/4869ev5/HHH2fjxo0sWrQIwzCKdX0bNmzgzjvv5Pz58zRp0oQBAwaQlZXFtm3bmDhxIl9//TXffPMNLi4uxervoYceYt68edSoUYObbrqJOnXqcO7cOX799Vdmz55NZGQkTZo0uW4fLVq0YNSoUdfcd/z4cdasWQOAk5OTdXtaWhpDhgxh/fr1eHl50aVLF+rUqcPu3bt5//33Wbx4MatXr6ZTp07Fug4REZESM0VERKTaSEtLMxs1amQCpmEYZkREhDlt2jTz22+/Nc+cOXPdY9evX28eOXKk0PZffvnFDAgIMAFz69atBfatW7fOBEzADAsLM8+ePWvdd/ToUdPX19cEzNDQUPP22283L126ZN0fGxtrOjs7mxaLxTx27FiBfkeNGmXtd/z48WZ2drZ13549e8w6deqYgPn+++8XOG7evHkmYI4aNarA9pMnT5r+/v6mYRjmu+++a+bk5Fj3nT171uzfv78JmFOnTr3u7yjfsWPHTMAMCAgwT548WWj/vn37Cl1T3759TcBct27dDfs/f/68GRISYgLmpEmTCuy77777TMC87bbbzNOnTxfY989//tMEzJYtW5pXr14t1rWIiIiUlIZOiIiIVCNeXl7ExMTQvXt3TNNk/fr1TJkyhT/96U/UrVuXTp068f77719z2EHfvn1p1qxZoe3BwcFMmTIFoMhJJA3DYO7cufj7+1u3NW7cmAceeACA+Ph45syZg4eHh3V/165dufXWW8nNzS1yyccGDRrw9ttv4+z820OaISEhvPTSSwC8/fbbN/iN5Pl//+//kZKSQlRUFOPGjcNi+e2fSP7+/nzyySe4uLgwe/ZsTNO8YX/5Q1Q6d+5M/fr1C+1v06ZNqedkuHLlCkOHDmXv3r2MGDGCGTNmWPft37+fzz//nIYNG7JgwQLq1q1b4NjHH3+cwYMHc+jQIVasWFGq84uIiNyICg0iIiLVTHBwMFu2bGHr1q289NJLDBo0yDpnw86dOxk3bhy33HILV65cKXRseno6ixcv5vnnn+fhhx9m9OjRjB49mqVLlwJw4MCBa54zKCiIdu3aFdresmVLIG8Cyj9+KP79/hMnTlyz3+HDhxdaNQOwDjc4dOhQkcf+3rfffgvAiBEjrrm/UaNGtGzZkuTkZA4dOnTD/lq3bo23tzfLly/n1VdfJT4+/obHFIdpmowePZr169fTp08f5s+fX2BoyPLlyzFNk1tvvRVvb+9r9hEREQHA5s2bbRKTiIjIH2mOBhERkWoqLCyMsLAwIO8DbFxcHG+++SZffPEFa9asYebMmTz99NPW9l9//TVjxowhJSWlyD5TU1Ovub2ob++9vLyuuz//w3L+hJF/1LRp0yKP8/f3JyUlhaSkJBo2bFhkzAC//vorAL17975uO4Dk5GRatWp13Tbe3t7MmzePMWPG8OKLL/Liiy/SoEEDevTowS233MJ9991nvfaSmDx5Mp9//jlt27blyy+/xM3N7ZrXMXfuXObOnXvD6xARESkPKjSIiIgIhmHQuXNnPv/8czIyMvjqq6/48ssvrYWG48ePM2LECDIzM3nmmWf485//TJMmTfDy8sJisbBq1SoGDRpU5LCC3w9FKM3+sijOUIfc3FwAhg0bhqen53Xb/n74x/Xcfffd3HzzzXz11Vf88MMPbNq0iWXLlrFs2TJeeuklVq9eTWhoaLH6AnjvvfeYPn06DRo0YPny5fj6+hZ5HR07dqRDhw7X7a979+7FPreIiEhJqNAgIiIiBQwcOJCvvvqKs2fPWrd9/fXXZGZmMnToUKZPn17omOIMJygPRQ1JSEtLsz55ERAQcMN+AgMDOXToEM8++yxdu3a1WXw+Pj488MAD1rkoEhMTmThxIv/973+ZMGEC33//fbH6+frrr5k4cSLe3t58++23NG7cuMjrAAgPD2f27Nm2uQgREZES0hwNIiIi1Uhxvt1PSEgACn5AP3fuHMA1P+CapsmCBQtsFGHJLF68mKysrELb//3vfwN5y0M2atTohv3ceuutACxatMi2Af5BYGAgU6dOBfLmwyiO2NhYRo4ciWEYLF68+LrLUuZfx1dffVXkcBMREZHypkKDiIhINfLuu+8yatSoa04EaJom//nPf6zfhI8cOdK6r02bNkDeqhInT560bs/JyeGll16y28SCJ06cYNKkSQVWydi/fz//93//B8ATTzxRrH6efvppatWqxT/+8Q/efvvta06EGR8fz6efflqs/uLi4li4cCGZmZmF9n399dfAtYs2f/Trr79y2223kZGRwb/+9S8GDRp03fadOnXi7rvvJjExkbvuuoujR48WanPp0iU+++wz68oYIiIitqahEyIiItVIdnY2n3zyCZ988gl16tShU6dO1K5dmwsXLrBv3z7rB9P777+fsWPHWo+7/fbb6dKlC9u3b6dVq1b07dsXT09Ptm7dyokTJ3j22WevOaSivD3yyCPMmTOHb7/9lu7du3P+/HnWrVtnXQJy3LhxxeonICCA//73v9x9991MmjSJGTNm0K5dOxo0aMDFixfZv38/R44coXv37tx///037O/YsWOMHDkSd3d3OnfuTGBgIFevXmX37t0cOHAAV1fXAstSFuXVV1/lzJkz1KlTh++//77IoRZvvfUWtWvXBmDevHlcuHCBFStWEBwcTIcOHWjatCmmaXL06FF+/vlnrly5wv79+6lXr16xfj8iIiIloUKDiIhINTJ27FiaNm1KTEwMW7duZd++fZw+fRpnZ2caNmzIvffey1/+8hduueWWAsc5Ozuzfv16Xn/9dZYuXUpMTAw1a9akV69eLF26lLS0NLsUGrp3787DDz/Myy+/zOrVq0lPT6dly5aMHTuWiRMnFlj68Ub69OnD3r17mT17Nt9++y2xsbFkZWVRt25dgoKCuP/++7n77ruL1VePHj1444032LBhA/v37ycuLg5nZ2cCAgKIiopi4sSJBAcH37Cf/Cc1kpOTmT9/fpHt/v73v1sLDd7e3qxatYqFCxfy6aefsn37dnbu3EnNmjVp0KABf/7znxkyZAjNmzcv1rWIiIiUlGEWZ7CmiIiISCUyevRo5s+fz7x58xg9erS9wxEREZHf0RwNIiIiIiIiImIzKjSIiIiIiIiIiM2o0CAiIiIiIiIiNqM5GkRERERERETEZvREg4iIiIiIiIjYjAoNIiIiIiIiImIzKjSIiIiIiIiIiM2o0CAiIiIiIiIiNqNCg4iIiIiIiIjYjAoNIiIiIiIiImIzKjSIiIiIiIiIiM2o0CAiIiIiIiIiNqNCg4iIiIiIiIjYzP8HUzr6QFJDVeYAAAAASUVORK5CYII=", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "fig, ax = plt.subplots(figsize=(12,4))\n", - "\n", - "ax.plot(nn, abs_error_df.quantile(q=0.975,axis=1))\n", - "ax.plot(nn, abs_error_df.quantile(q=0.5, axis=1))\n", - "ax.plot(nn, abs_error_df.quantile(q=0.025,axis=1))\n", - "ax.plot(nn, (1/16)*(nn)**(-0.5), linestyle='--', color='black', linewidth=3.0, label=r\"$\\frac{1}{16}n^{-1/2}$\")\n", - "ax.set_ylabel(r\"$|\\hat{f}(x^*) - f(x^*) \\star K(x^*)|$\")\n", - "ax.set_xlabel(r\"Sample size\")\n", - "ax.set_yscale('log')\n", - "ax.set_xscale('log')\n", - "ax.legend()\n", - "ax.grid()\n", - "\n", - "ax.tick_params(axis='both', which='major', labelsize=16)\n", - "ax.xaxis.get_label().set_fontsize(16)\n", - "ax.yaxis.get_label().set_fontsize(16)\n", - "ax.legend(prop={'size': 16})" - ] - }, - { - "cell_type": "markdown", - "id": "f018a895", - "metadata": {}, - "source": [ - "This plots show that we get convergence of the KDE to the convolution at a rate of about $1/\\sqrt{n}$. \n", - "\n", - "### 2.1 Illustrating the KDE\n", - "\n", - "Now that we have a handle on _what_ the KDE is approximating, let's illustrate the returned curve.\n", - "Again, we sample points from the normal distribution but now we also plot the KDE over a uniform test grid on $[-3,3]$." - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "97df7763", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Text(0.5, 0, 'x')" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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b9V1GzrX984ZFRUVLf757dCVoP38/FAqlRQUFNi1FxQUoNPpmj1PoVDQs2dPABISEjh8+DALFixg7Nix5+wfHR2Nn58f6enpjB8/vsn7zs7OOIviTEG4OBZL06LemBi47TbHxNOdXHcdDBpknQp/xksvWf/uLqPtE+ot9Szev9ghn31f//tQK1v+d7106VKSkpJISUlh+/btzJ49m5EjR9o9jTiXXbt2ERAQwMcff8yUKVNQKpW299LT0/n2229ZuXKlrb26upqkpCTi4+PR6/XMnTuXmTNnkpqaikLR/EOc5557joULF+Lv788DDzzA3XffzdbTExOysrKIiopiw4YNzf7cXLNmDUOGDOH111/n008/xc3NjenTp/PPf/4Tl3MsZSHLMr/99htpaWm89tprAGRmZpKfn29X5qLVaklMTGT79u3ceuut5/276mgOTYCcnJwYPHgwycnJzJgxAwCLxUJycjKPPPJIi69jsVgwGAzNvn/q1ClKSkoICgq62JAFQWjOypXWWUwNzZtnne0knJ8kWROea64525aRAZ9+Cnff7bi4hGbFx8cz73TC36tXL/7zn/+QnJx8wQTI398fAC8vrya/6BuNRpYtW2brA3DDDTfY9VmyZAn+/v4cOnTovHU/r7zyCmPGjAHg6aefZtq0adTV1aHRaFCr1cTExOB6nhXZjx8/zpYtW9BoNKxatYri4mIeeughSkpK+Pjjj239KioqCAkJwWAwoFQq+b//+z/b38GZUpbWlrl0Fof/y5SUlMRdd93FkCFDGDZsGG+//TbV1dXMmTMHgFmzZhESEsKCBQsAa73OkCFD6NGjBwaDgZ9++olPP/2UDz74AAC9Xs+LL77IDTfcgE6nIyMjgyeffJKePXsyWWw2KAgdw2xuOvrTt691lpPQMldfDYmJkJJytu2ll+Avf7lsCshVChX39b/PYZ/dGvGN6raCgoKaXb6lpSIiIuySH4Bjx44xd+5cUlJSKC4uxnJ6najs7OzzJkAN4zvzy39hYSHh4eGEhIRw5MiR88ZisViQJInPP/8crVYLWGdt33jjjfzf//2fbRTIw8OD1NRU9Ho9ycnJJCUlER0d3ezIUlfi8ATolltuoaioiLlz55Kfn09CQgJr1661ZYzZ2dl2w3zV1dU89NBDnDp1ChcXF2JjY/nss8+45ZZbAGtB2L59+1i6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HjFiBGvWrOHuu+8mODiYjRs3cvToUf7973+36HM7kkMTID8/P5RKJQUFBXbtBQUF6HS6Zs9TKBT07NkTgISEBA4fPsyCBQsYO3as7byCggKCGgzfFxQUkJCQcM7rOTs74+zsfJF3IwjdVE0NfP65fdvdd0ODf5iFbkKSrKt2/+MfZ9u++Qbefdf6iExoN/Hx8cybNw+AXr168Z///Ifk5OQLJkD+/v4AeHl5Nfk5ZzQaWbZsma0PwA033GDXZ8mSJfj7+3Po0CH69evX7Oe88sorjBkzBoCnn36aadOmUVdXh0ajQa1WExMTg6ur6wXvMzQ0lKKiIurr65k/fz733nsvYB2IGD58OP/85z/p06cPgYGBLF++nO3bt9t+PgO899573H///YSGhqJSqVAoFCxevNhWtuJIDk2AnJycGDx4MMnJycyYMQMAi8VCcnIyjzzySIuvY7FYMJxeuTYqKgqdTkdycrIt4amsrCQlJYUHH3ywvW9BELq/r7+GioqzryXJmgAJ3dOsWfDMM2AyWV/X1VlX9370UcfG1QIKpcTgqZEO++zWiG+07EBQUFCzs5dbKiIiwi75ATh27Bhz584lJSWF4uJiLKcXuMzOzj5vAtQwvjODAYWFhYSHhxMSEsKRhqOE5/H777+j1+vZsWMHTz/9ND179uS20wtvfvrpp9x9992EhISgVCoZNGgQt912G7t377ad/95777Fjxw7WrFlDREQEmzdv5uGHHyY4ONiuVtcRHP4ILCkpibvuuoshQ4YwbNgw3n77baqrq5kzZw4As2bNIiQkhAULFgCwYMEChgwZQo8ePTAYDPz00098+umnfPDBBwBIksRjjz3Gyy+/TK9evYiKiuKFF14gODjYlmQJgtBA4+LnyZMhIsIxsQgXz98fZsywJrZnLF4MjzzS5fdzkySpVY+hHKnxzu6SJNmSk7Zya7ilyWnXXnstERERLF68mODgYCwWC/369btgkXTD+KTT/93bEl9UVBQA/fv3p6CggPnz59sSoB49erBp0yaqq6uprKwkKCiIW265hejoaABqa2t59tlnWbVqFdOmTQOsiVlqaipvvvmmSIBuueUWioqKmDt3Lvn5+SQkJLB27VoCAwMBa5bb8DlndXU1Dz30EKdOncLFxYXY2Fg+++wzbrnlFlufJ598kurqau6//37Ky8sZNWoUa9eu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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "x_test = np.linspace(-3., 3.)[:, np.newaxis]\n", - "nn = np.logspace(2, 4, endpoint=False, dtype=np.int64, num=5) \n", - "\n", - "kernel_estimates = {i:np.zeros((len(nn),), dtype=float) for i in range(num_trials)}\n", - "\n", - "conv_estimates = {i:np.zeros((len(nn),), dtype=float) for i in range(num_trials)}\n", - "\n", - "fig, ax = plt.subplots()\n", - "for i,n in enumerate(nn):\n", - " Xtrain = stats.norm(0, 1).rvs(size=n)[:, np.newaxis]\n", - " estimate = kernel_density(Xtrain, x_test)\n", - " ax.plot(x_test, estimate, alpha=0.5, color=\"C\"+str(i), label=f\"n_train: {n}\")\n", - "ax.plot(x_test, stats.norm(0,1).pdf(x_test), lw=3.0, color='red', label=\"PDF: N(0,1)\") \n", - "ax.legend()\n", - "ax.set_ylabel(\"Density\")\n", - "ax.set_xlabel(\"x\")" - ] - }, - { - "cell_type": "markdown", - "id": "2c55bd95", - "metadata": {}, - "source": [ - "The shape looks correct, as as expected from the preceding plots, we look to be converging to some curve similar to the distribution...*but didn't we want to estimate the underlying distribution function* itself?\n", - "Generally speaking, we only claim to estimate the density function over a sample, not the true underlying distribution.\n", - "However, if certain conditions are met then, as outlined in the next section, we also estimate the underlying distribution.\n", - "\n", - "\n", - "## 3. Bandwidth Selection\n", - "\n", - "One detail that we have thus far omitted is the `bandwidth` parameter, $h$. \n", - "This parameter $h$ controls the width of the kernels applied at every point. \n", - "In general, it might be difficult to choose a priori the correct bandwidth.\n", - "If the bandwidth is chosen too small, then the returned curve will be too spiky, and if the bandwidth is too large, then the curve will appear too flat.\n", - "\n", - "Suppose that we sample $(x_1, x_2, x_3) = (-2, 0.05, 0.15) $ from a standard normal distribution and fit a KDE model.\n", - "When we query a test point $x^*$, we are taking a sum over distances from $x^*$ to the points $x_1, x_2, x_3$.\n", - "Ignoring the constants, the KDE at $x^*$ is $\\hat{f}(x^*) = K(x^* - x_1) + K(x^* - x_2) + K(x^* - x_3)$.\n", - "When a query point $x^*$ comes at test time, its distance is compared to all $x_i$ and (an amount proportional to) $\\exp(-\\frac{1}{2h^2} |x_i - x^*|^2)$ is contributed to $\\hat{f}(x^*)$. The contribution should be ''large'' when the distance is small and ''small'' when the distance is large.\n", - "\n", - "In the plot below, the query point $x^*$ is close to the two points on the right hand side so picks up a non-trivial contribution from each. On the other hand, it is far from the point on the left hand side, so the the exponential function makes this contribute almost zero to the overall sum." - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "id": "621d01c9", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 38, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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5vJmvF4Ym5FAdrK+M5dHw9yxaQBsLJd9n0JEpYr16sciHX06e22t34oXL4VJhWTFB/BLaf5sMFmho9avoza1JX5tyd9IiqJgSkjw62pYuZKGJ1eQ9d3vMGXbVrK++x11yX3lSr+ex9/K7ccee4yenh6WLFnCe++9R0VFBatXr+b8889n0qRJ3HPPPQCce+65/OlPf+L9999n27ZtXH/99ZjNfbPdycnJ/OAHP+B73/sezz33HAcOHGDTpk08+uijPPfccyeM45prruHIkSM89dRTAwqNNK+88gpTpkwZcnxZWRmXXHIJd911F1/5ylf4+c9/zssvv8ymTZv8+n4YRZJPEXN8+z17k8Fg0WZZPytvxuMx/uxcIYRBOjuhuFi9tMKXjgZoPKDeHnOy7qca0ZI7gDVO7fcJfi29a7OsW+u24vGGV//hwara/ekDOhKlpaV88sknjB8/nquuuopx48Zx0UUXMWnSJD788EOSktT9sXfeeSdnn302l156KZdccgmXX345EyZMGPBcv/jFL7j77rt54IEHmDp1KhdeeCGrVq2ipKTkhHGkpqbypS99iaSkJC6//PLjPt/S0sKePXsGHdvY2MiFF17I5z//ee644w4AFixYwEUXXcRdd93l53fEGLLsLmLOpvJmIHjFRpppBSnEWU20dDk5WN/BxBxjN/kLIQzi9cLhw323oS/xy5oE8frfW0acfIK69F75qbr0PvMqXUMmpU8izhxHm6ONspYyxqeND/z1R9Fw7ZS0P9f//tEBfx5txcXFrFy50vfn5cuX8/DDD7N161ZOPfVUAFJSUvj73/8+YNz1118/4M+KonDbbbdx2223Dflaa9euHfJzlZWVfPWrXz1ujyjADTfcwA033DDouIyMDHbv3n3c/YHuGzWCzHyKmOLxePnMN/MZ3OTTajYxszANgE3SckmI6OJbcte/39Pj9bC1disAs3NmB/7avn2f63UPsZqszMiaAQRn6V0PPX08gzUD2t+9997L73//ez7++GM8HuNniZuamnjllVdYu3atb49ptJGZTxFT9te109btIsFmZkqeH/30RsmccWlsKGtkU3kTV53i/wZyIUSY0mY+x+hPPg+1HKLN2Ua8JZ5J6ZMCf23tNWt2gKMDbInDP77XrOxZfFrzKVvqtvDF0i8G/vqjwJ8G8sGaAe1v6dKlhr+GZs6c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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "x_vals = [-2, 0.05, 0.15]\n", - "query = -0.1\n", - "fig, ax = plt.subplots(figsize=(8,5))\n", - "ax.scatter(x_vals, np.zeros_like(x_vals), label=r\"$(x_1, x_2, x_3)$\")\n", - "\n", - "h = 0.25\n", - "window = np.linspace(-1., 1.) \n", - "for i, x in enumerate(x_vals):\n", - " ax.plot(x+window, np.exp(-0.5*(window/h)**2))\n", - "ax.vlines(query, 0, 1., color='red', linestyle=\"--\")\n", - "ax.plot(query, 0, label=r\"Query: $x^*$\", marker= 'x', markersize=10.)\n", - "ax.legend()" - ] - }, - { - "cell_type": "markdown", - "id": "1a9808a6", - "metadata": {}, - "source": [ - "### Small $h$\n", - "\n", - "When $h$ is too small, the kernels are extremely narrow (think of a Gaussian distribution with small variance). Then any test point can easily lie in the tails of many of the kernel functions about each of the datapoints. This means that the contribution is small from almost all of the sample data. However, when a test point lies close to a sample point, it gets essentially the entirety of its contribution to $\\hat{f}$ from that datapoint, so we see large spikes in the returned KDE." - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "6daf7fdf", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "x_vals = [-2, -0.15, -0.02, 0.05, 0.2, 2.5]\n", - "\n", - "fig, ax = plt.subplots(figsize=(8,5))\n", - "ax.scatter(x_vals, np.zeros_like(x_vals), label='Samples')\n", - "\n", - "h = 0.25\n", - "window = np.linspace(-1., 1.) \n", - "for i, x in enumerate(x_vals):\n", - " if i == 0:\n", - " ax.plot(x+window, np.exp(-0.5*(window/h)**2)/h, alpha=0.75, linestyle=\":\", color='grey', label=\"Kernels\")\n", - " else:\n", - " ax.plot(x+window, np.exp(-0.5*(window/h)**2)/h, alpha=0.75, linestyle=\":\", color='grey')\n", - " \n", - "test_points = np.linspace(-3, 3, 25)[:, np.newaxis]\n", - "kde = kernel_density(np.array(x_vals)[:, np.newaxis], test_points, 0.01)\n", - "ax.plot(test_points, kde, label=\"KDE\")\n", - "ax.scatter(test_points, -0.5*np.ones_like(test_points), label=\"Test points\")\n", - "ax.legend()" - ] - }, - { - "cell_type": "markdown", - "id": "6b817079", - "metadata": {}, - "source": [ - "### Large $h$\n", - "\n", - "On the other hand, when $h$ is too large, almost all of the points contribute to the kernel sum for $\\hat{f}$, so this flattens out the curve as it is more difficult to distinguish between groups of points with large and small distances." - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "c058ff01", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 15, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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33FiYuJPuv1kWloalEolSktLu203Ojr6ks+Ljo7Gb37zG3z44Yd48MEH8eabb151DUNFT+9rb7799lscP35cuEwtSr5hfbveTxQWFgadTofi4uJu+3vXkwZ/f38sXLgQb775JjZs2IAPPvgADQ0NADrC5MWDQC+l67HUZrMhPz9fOJampqYiLy/PZUDh7t274efnh6ioqKt6fQqFAgB6rI/HYM/BbgY0YLLjAxGhUUFvMPfY20sCIFzTMU1XX6uvr8dtt92GX/7ylxg5ciT8/Pxw8OBBPPvss7jpppuQmJgIq9WKl19+GXPnzsXu3buxdu3aPvv5u3fvxrPPPot58+Zhy5YteP/99/HFF1/0uO7tt9+O5557DjfddBP+/Oc/IyoqChcuXMCHH36Ihx56CFarFX//+99x4403QqfT4cyZMzh37hzuvPPOPqt3MIqOjsb27dsxffp05Obm4uGHH8att96KmJgY3HrrrZBKpTh69ChOnDiBp5566qp/jp+fH37/+9/jf//3f+FwODBp0iQYDAbs3r0b/v7+Qh/drh544AFcd911SE5ORmNjI7Zt28Y+eJfp4vd18+bNAID29nbo9XqXqblWr16NG264odvfSnNzM/R6vcsytVoNf3//AXsdly12AuCv6xjsdakjqb+uY70B8sQTT+C3v/0tNBoN5syZg/b2dhw8eBCNjY1YsWIFXnjhBURERGDUqFGQSqV4//33ER4eLgzujIuLw9atWzFx4kQolUoEBARc8me9+uqrSEpKQmpqKl588UU0Njbil7/8JQDg3nvvxZo1a3D//fdj+fLlOHPmDFatWoUVK1Zc9QlqaGgovL29sXnzZkRFRUGlUqGhoYHHYA/DllkaMDKpBKvmpgHoCK5ddX69am5av8w36+vri5ycHLz44ouYMmUK0tPT8eijj2LZsmV45ZVXkJGRgRdeeAHPPPMM0tPT8e677wpTx/SFBx98EAcPHsSoUaPw1FNP4YUXXkBubs/9E9VqNb777jvExMTglltuQWpqKu6++26YzWb4+/tDrVajoKAA8+fPR3JyMn7961/jvvvuw//8z//0Wb2DVVRUFLZv3466ujo8/fTT2LhxI77++muMHTsW48aNw4svvugyOOVqPfnkk3j00UexevVqpKamYs6cOfjiiy+6Xd7uZLfbcd999wnrJicnuww8pN51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iRbDLBERERGJFsMsEREREYkWwywRERERiRbDLBERERGJFsMsEREREYkWwywRERERiRbDLBERERGJFsMsEREREYkWwywRERERiRbDLBERERGJFsMsEREREYkWwywRERERiRbDLBERERGJFsMsEREREYkWwywRERERiRbDLBERERGJFsMsEREREYkWwywRERERiRbDLBERERGJFsMsEREREYkWwywRERERiRbDLBERERGJFsMsEREREYkWwywRERERiRbDLBERERGJFsMsEREREYkWwywRERERiRbDLBERERGJFsMsEREREYkWwywRERERiRbDLBERERGJFsMsEREREYkWwywRERERiRbDLBERERGJFsMsEREREYkWwywRERERiRbDLBERERGJFsMsEREREYkWwywRERERiRbDLBERERGJFsMsEREREYkWwywRERERiRbDLBERERGJFsMsEREREYkWwywRERERiRbDLBERERGJFsMsEREREYkWwywRERERiRbDLBERERGJFsMsEREREYkWwywRERERiRbDLBERERGJFsMsEREREYkWwywRERERiZbc3QUQDTV2hxP7zzegptmMUD8VsuMDIZNK3F0W9bHLeZ97WgfAZe0f3I+oP3H/IjEZkDD76quv4rnnnoNer0dGRgZefvllZGdnX3L9999/H48++ihKSkqQlJSEZ555Btdff73wfafTiVWrVuHNN99EU1MTJk6ciNdffx1JSUkD8XKIrtrmE1V44rNTqDKYhWURGhVWzU3DnPQIN1ZGfely3uee1tGqvQAATSbrJZ93udsnulrcv0hs+r2bwYYNG7BixQqsWrUKhw4dQkZGBnJzc1FTU9Pj+nv27MHixYtx99134/Dhw5g3bx7mzZuHEydOCOs8++yzeOmll7B27Vrs27cPPj4+yM3Nhdls7nGbRJ5g84kq3PPvQy4fEACgN5hxz78PYfOJKjdVRn3pct7nS63TZLK6BNmLn3e52ye6Wty/SIwkTqfT2Z8/ICcnB2PHjsUrr7wCAHA4HIiOjsb999+PRx55pNv6CxcuRGtrKz7//HNh2bhx45CZmYm1a9fC6XRCp9PhwQcfxO9//3sAgMFgQFhYGNatW4dFixb9aE1GoxEajQYGgwH+/v599EqJLs3ucGLSM992+4DoJAEQrlFh18MzeClPxC7nfQ7zVwKQ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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "x_vals = [-2, -0.15, -0.02, 0.05, 0.2, 2.5]\n", - "\n", - "fig, ax = plt.subplots(figsize=(8,5))\n", - "ax.scatter(x_vals, np.zeros_like(x_vals), label='Samples')\n", - "\n", - "h = 5.\n", - "window = np.linspace(-2., 2.) \n", - "for i, x in enumerate(x_vals):\n", - " if i == 0:\n", - " ax.plot(x+window, np.exp(-0.5*(window/h)**2)/h, alpha=0.75, linestyle=\":\", color='grey', label=\"Kernels\")\n", - " else:\n", - " ax.plot(x+window, np.exp(-0.5*(window/h)**2)/h, alpha=0.75, linestyle=\":\", color='grey')\n", - " \n", - "test_points = np.linspace(-3, 3, 25)[:, np.newaxis]\n", - "kde = kernel_density(np.array(x_vals)[:, np.newaxis], test_points, 3.0)\n", - "ax.plot(test_points, kde, label=\"KDE\")\n", - "ax.scatter(test_points, -0.05*np.ones_like(test_points), label=\"Test points\")\n", - "ax.legend(loc='upper center', ncol=4, bbox_to_anchor=(0.5, 1.1),)" - ] - }, - { - "cell_type": "markdown", - "id": "f0aa9475", - "metadata": {}, - "source": [ - "However, all is not lost as we can vary the bandwidth parameter to get closer to the target distribution." - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "886b5b3e", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "hh = [0.1, 0.2, 0.4, 0.8]\n", - "n_train = 10000\n", - "x_test = np.linspace(-3., 3.)[:, np.newaxis]\n", - "true_density = stats.norm(0,1).pdf(x_test)\n", - "Xtrain = stats.norm(0, 1).rvs(size=n_train)[:, np.newaxis]\n", - "all_estimates = {str(h): np.zeros((len(x_test),)) for h in hh}\n", - "\n", - "fig, ax = plt.subplots()\n", - "ax.plot(x_test, true_density, lw=3., color='red', label=\"True density\")\n", - "for i, h in enumerate(hh):\n", - " estimate = kernel_density(Xtrain, x_test, h)\n", - " ax.plot(x_test, estimate, alpha=0.5, color=\"C\"+str(i), label=f\"h:{h}\")\n", - "ax.legend()\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "842054e0", - "metadata": {}, - "source": [ - "It turns out that if we define the bandwidth as a function of $n$, say $h = h(n)$, then provided the sample \n", - "size $n$ grows more quickly than $h(n)$ decays, the kernel density estimate will converge\n", - "pointwise to the density function evaluated at that point.\n", - "A stronger form of convergence (known as uniform convergence) can be obtained if $n$ grows faster than the square of $h(n)$.\n", - "If the number of samples $n$ in the training set grows more \n", - "For example, if we guarantee that the band\n", - "$\\lim_{n \\rightarrow \\infty}n h_n = \\infty$, then uniform convergence to the distribution is obtained.\n", - "\n", - "\n", - "\n", - "We will now show that allowing the bandwidth to decay with $n$ causes the KDE to converge to the true distribution.\n", - "We use a uniform grid over $[-2, 2]$ as the test set." - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "id": "1d224351", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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eKYlyUgikUgkEolt9bxYtfehO0lJ8bNEIpFIJJ4/HvrcfqIRIc+LZKTf7wMkxc8SiUQikXge6vf75PP5x/z+82IAaxzHrKyskM1mkSTpGXvdXq/H1NQUi4uLL9iBsS/0Nibte/57obcxad/z3wu9jSezfUII+v0+4+PjW2ba/qLnRc+ILMtMTk6etNc/FQqrvdDbmLTv+e+F3sakfc9/L/Q2nqz2PV6PyEOSAayJRCKRSCS2VZKMJBKJRCKR2FandDJiGAYf/ehHMQxju0M5aV7obUza9/z3Qm9j0r7nvxd6G58L7XteDGBNJBKJRCLxwnVK94wkEolEIpHYfkkykkgkEolEYlslyUgikUgkEoltlSQjiUQikUgkttUplYwcPXqUd7/73czOzmJZFrt27eKjH/0ovu8/7n6u6/L+97+fcrlMJpPhjW98I+vr689S1Cfmv//3/85ll11GKpWiUCg8qX1+9Vd/FUmStjyuueaakxvo0/BU2iiE4Hd/93cZGxvDsiyuuuoqDh48eHIDfYparRZvf/vbyeVyFAoF3v3udzMYDB53nyuuuOK4a/gbv/Ebz1LET+xTn/oUMzMzmKbJJZdcwk9+8pPH3f76669n3759mKbJ2Wefzde//vVnKdKn5kTa97nPfe64a2Wa5rMY7Yn5/ve/z+te9zrGx8eRJIkbbrjhCfe5+eabueCCCzAMg927d/O5z33upMf5VJ1o+26++ebjrp8kSaytrT07AZ+gj33sY7zoRS8im81SrVa59tprOXDgwBPu92y/B0+pZOT+++8njmM+85nPcM899/CJT3yCT3/603zkIx953P3+w3/4D/zjP/4j119/Pd/73vdYWVnhDW94w7MU9YnxfZ83velNvO997zuh/a655hpWV1ePPb7whS+cpAifvqfSxj/8wz/kf//v/82nP/1pbrnlFtLpNFdffTWu657ESJ+at7/97dxzzz1861vf4mtf+xrf//73ee973/uE+73nPe/Zcg3/8A//8FmI9ol96Utf4kMf+hAf/ehHue222zj33HO5+uqrqdfrj7r9j370I972trfx7ne/m9tvv51rr72Wa6+9lrvvvvtZjvzJOdH2wWaly0deq/n5+Wcx4hMzHA4599xz+dSnPvWktp+bm+O1r30tV155JXfccQcf/OAH+bVf+zW++c1vnuRIn5oTbd9DDhw4sOUaVqvVkxTh0/O9732P97///fz4xz/mW9/6FkEQ8KpXvYrhcPiY+2zLe1Cc4v7wD/9QzM7OPub3O52O0DRNXH/99ceeu++++wQg9u/f/2yE+JR89rOfFfl8/klte91114nXv/71JzWek+HJtjGOYzE6Oir+6I/+6NhznU5HGIYhvvCFL5zECE/cvffeKwDx05/+9Nhz3/jGN4QkSWJ5efkx97v88svFb/3Wbz0LEZ64iy++WLz//e8/9u8oisT4+Lj42Mc+9qjbv/nNbxavfe1rtzx3ySWXiF//9V8/qXE+VSfavhN5bz7XAOIrX/nK427zn//zfxZnnnnmlufe8pa3iKuvvvokRvbMeDLt++53vysA0W63n5WYnmn1el0A4nvf+95jbrMd78FTqmfk0XS7XUql0mN+/9ZbbyUIAq666qpjz+3bt4/p6Wn279//bIT4rLj55pupVqucdtppvO9976PZbG53SM+Yubk51tbWtlzDfD7PJZdc8py7hvv376dQKHDRRRcde+6qq65ClmVuueWWx933b/7mb6hUKpx11ln8zu/8DrZtn+xwn5Dv+9x6661bzr0sy1x11VWPee7379+/ZXuAq6+++jl3reCptQ9gMBiwY8cOpqameP3rX88999zzbIT7rHg+Xb+n47zzzmNsbIxXvvKV/Mu//Mt2h/OkdbtdgMf93NuOa/i8WCjvZDl06BB/8id/wsc//vHH3GZtbQ1d148bm1Cr1Z6z9whP1DXXXMMb3vAGZmdnOXz4MB/5yEd49atfzf79+1EUZbvDe9oeuk61Wm3L88/Fa7i2tnZcd6+qqpRKpceN9d/8m3/Djh07GB8f58477+S//Jf/woEDB/jyl798skN+XI1GgyiKHvXc33///Y+6z9ra2vPiWsFTa99pp53GX/7lX3LOOefQ7Xb5+Mc/zmWXXcY999xzUhcEfbY81vXr9Xo4joNlWdsU2TNjbGyMT3/601x00UV4nsef//mfc8UVV3DLLbdwwQUXbHd4jyuOYz74wQ/ykpe8hLPOOusxt9uO9+ALomfkwx/+8KMOKHrk4xf/Y1heXuaaa67hTW96E+95z3u2KfIn56m070S89a1v5Zd/+Zc5++yzufbaa/na177GT3/6U26++eZnrhFP4GS3cbud7Pa9973v5eqrr+bss8/m7W9/O3/913/NV77y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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "num_trials = 10\n", - "query = np.linspace(-2., 2., num=20)[:, np.newaxis]\n", - "true_dist = stats.norm(0,1).pdf(query)\n", - "nn = np.logspace(2, 7, endpoint=False, dtype=np.int64, num=20) \n", - "\n", - "kernel_errors = {i:np.zeros((len(nn),), dtype=float) for i in range(num_trials)}\n", - "#conv_estimates = {i:np.zeros((len(nn),), dtype=float) for i in range(num_trials)}\n", - "\n", - "fig, ax = plt.subplots()\n", - "for i,n in enumerate(nn):\n", - " for t in range(num_trials):\n", - " Xtrain = stats.norm(0, 1).rvs(size=n)[:, np.newaxis]\n", - " estimate = kernel_density(Xtrain, query, 2./n**0.5)\n", - " error = np.linalg.norm(estimate.flatten() - true_dist.flatten())\n", - " kernel_errors[t][i] = error\n", - " ax.plot(query, estimate, alpha=0.2)\n", - " \n", - "ax.plot(query, true_dist, lw=3., color='red')" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "id": "c0c088c1", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 18, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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fB/zPQXFmr/hDAUNIiIiIiIiIqVU17suH/b+kK9u+opGfo3IyM/g7XVvc+esO1mRsMLe5VUIChpERERERERErlKHoA78NOAnxnQag5+LHwfTD/LEwid4cuGTxKbH2rs8u1LQICIiIiIiInINHMwO/K3x35hzxxweavYQjiZHlics547f7uCdde+Qnpdu7xLtQkGDiIiIiIiIyHXwdvbmn+3/yczbZtIzpCeFRiHfxXzHgJkD+HH3jxQWF9q7xHKloEFERERERETEBsJ8whjfdzyf3fAZDXwakJaXxhtr3+Cu2XexJmmNvcsrNwoaRERERERERGyoa52uTI+ezksdXsLb2Zv9aft59M9H+cfif3A447C9yytzChpEREREREREbMzJ7MR9Te9j7qC53NvkXhxMDiyJX8Ltv93OBxs+ICs/y94llhkFDSIiIiIiIiJlxNfVl5c7vsz0gdPpEtyFguICJu2cxK0zb2XG3hkUFRfZu0SbU9AgIiIiIiIiUsYa+jXksxs+Y3yf8dTzrkfqqVReW/0a9869lw1HN9i7PJtS0CAiIiIiIiJSDkwmEz3r9mRm9Eyea/ccXk5exKTG8Pyy58kvyrd3eTbjaO8CRERERERERKoTJwcnhkQOYWD4QMZvHk+bwDY4OzjbuyybUdAgIiIiIiIiYgf+rv682vlVe5dhcxo6UY6mT5/OoEGDCA0Nxd3dncjISN5//30KCgrsXZqIiIiIiIiITahHQzl67733CAsL491336VWrVqsWrWKV155hW3btjF58mR7lyciIiIiIiJy3RQ0lKPZs2cTEBBg/b53794YhsGYMWOs4YOIiIiIiIhIZaahE+Xo3JDhjLZt2wKQmJhY3uWIiIiIiIiI2FyVChr27NnDxx9/zNChQ2nRogWOjo6YTCbeeOONUl3/888/06tXL/z8/PDw8KBVq1a8++67ZTqHwrJly3B2diY8PLzM3kNERERERESkvFSpoROffvop48aNu6Zrn3rqKcaNG4ejoyN9+vTB09OTxYsX88ILLzB79mz+/PNP3NzcbFrvrl27GDduHMOHD8fb29um9xYRERERERGxhyrVo6F58+Y899xzfP/998TExPDggw+W6rpff/2VcePG4enpydq1a/njjz+YMWMG+/bto0WLFqxYsYIxY8aUuOabb77BZDJdcZs+ffpF3/PEiRPcfvvtNGzYkLfffvu6n11ERERERESkIqhSPRoeeeSREt+bzaXLUf7zn/8A8OKLLxIVFWXdX7NmTT755BO6d+/O+PHjGTNmDD4+PgAMGjSITp06XfHederUuWBfZmYmt9xyC/n5+SxduhQPD49S1SkiIiIiIiJS0VWpoOFaJCQksH79egDuu+++C45369aNunXrEh8fz7x587j33nsB8PHxsYYOVyMvL4/bbruNuLg4VqxYQXBw8PU9gIiIiIiIiEgFUu2Dhs2bNwPg7+9P/fr1L3pOu3btiI+PZ/Pmzdag4VoUFRVxzz33sH79ehYvXkzjxo1LdV1eXh55eXnW7zMyMgAoKCgo04kqr9eZ2ipyjSJXonYsVYHasVQFasdSFagdS2V2Ne222gcNsbGxAISGhl7ynLp165Y491qNGDGCX3/9lbFjx1JUVMSaNWusx5o1a3bJCSHfeustXn/99Qv2//nnn7i7u19XTeVhwYIF9i5B5LqpHUtVoHYsVYHasVQFasdSGeXk5JT63GofNGRmZgJcdp4ET09P4GxPgmv1+++/AzBmzJgLJpdcsmQJvXr1uuh1L730Es8884z1+/T0dEJDQ+ncuTNeXl7XVVNZKigoYMmSJfTu3RsnJyd7lyNyTdSOpSpQO5aqQO1YqgK1Y6nMznx2NgzjiudW+6ChPMXFxV3TdS4uLri4uFi/PxN4XGqoh4iIiIiIiEhZyMzMvOJ8hdU+aDjTIyA7O/uS52RlZQFccmhDeQsODiY+Ph4vLy9MJhPt27e3TmhZGqU9vzTnXe6cjIwM60SaFeXfzlau9t+8Mry3re57rfdROy5/ase2v4/acflTO7b9fdSOy5/ase3vo3Zc/tSObX+fitaODcMgMzOzVAsaVPugISwsDID4+PhLnnPm2Jlz7c1sNhMSEmL93sHB4ap+UJX2/NKcV5pzvL29q9wP0qv9N68M722r+17rfdSOy5/ase3vo3Zc/tSObX8ftePyp3Zs+/uoHZc/tWPb36cituPSrrxoLtVZVVibNm0ASElJueRkjxs2bAAgKiqq3Oq6GiNGjCiT80tz3tW+d1Vhz+cuq/e21X2v9T5qx+VP7dj291E7Ln9qx7a/j9px+VM7tv191I7Ln9qx7e9TmduxySjNTA6V1NChQ5k8eTJjx47llVdeueR5HTp0YP369bzxxhv83//9X4ljK1asoHv37ri4uHDs2LFSJzhi6Rrm4+NDenp6lUtspfpQO5aqQO1YqgK1Y6kK1I6luqj2PRoAXn75ZQDefvttNm3aZN2fkpLCk08+CcDIkSMVMlwlFxcX/vWvf5WYyFKkslE7lqpA7ViqArVjqQrUjqW6qFI9GjZt2mQNBgAOHDjAiRMnCAkJoU6dOtb9M2fOJCgoqMS1o0eP5qOPPsLJyYm+ffvi4eHBokWLSEtLo2vXrixYsAA3N7dyexYRERERERGRyqhKBQ1Lly6ld+/eVzwvNjb2ohM7/vTTT0yYMIEtW7ZQUFBAeHg4DzzwAE8//TTOzs5lULGIiIiIiIhI1VKlggYRERERERERsS/N0SAiIiIiIiIiNqOgQSqM6dOnM2jQIEJDQ3F3dycyMpL333+fgoICe5cmUmq//PIL3bp1o2bNmri4uNCgQQOeeeYZTp48ae/SRK5JYWEhLVu2xGQy8cMPP9i7HJFSW7p0KSaT6YKtefPm9i5N5Kr9+OOPdOjQAXd3d/z9/enbty9JSUn2LkvkkhztXYDIGe+99x5hYWG8++671KpVi1WrVvHKK6+wbds2Jk+ebO/yREolNTWVXr168c9//hMfHx+2b9/O66+/ztatW1m0aJG9yxO5auPGjSM5OdneZYhcs4kTJxIZGWn93t3d3Y7ViFy9999/n5deeonnnnuOd955h+zsbJYtW8apU6fsXZrIJWmOBqkwkpOTCQgIKLHvjTfeYMyYMRw9epRatWrZqTKR6/Pll18yfPhwDh06RGhoqL3LESm1I0eO0KxZM8aPH8+QIUOYNm0a99xzj73LEimVM5OEr169mk6dOtm7HJFrsn//fpo1a8a4ceN44okn7F2OSKlp6IRUGOeHDABt27YFIDExsbzLEbEZf39/AA0DkkrnqaeeIjo6mh49eti7FBGRaunrr7/G2dmZYcOG2bsUkauioEEua8+ePXz88ccMHTqUFi1a4OjoiMlk4o033ijV9T///DO9evXCz88PDw8PWrVqxbvvvlvqD1zLli3D2dmZ8PDw63kMqebs0Y6Lioo4deoUGzZs4PXXX6d///5qx3Jdyrsd//777/z555/897//teVjSDVnj5/Ht912Gw4ODtSqVYvhw4eTmppqq8eRaqo82/GqVato0qQJkydPpl69ejg6OtKqVSvmz59v68cSsS1D5DJGjx5tABdsY8eOLfW1jo6Oxk033WTccccdhq+vrwEY3bp1M3Jyci57/c6dOw03Nzdj5MiRtnocqabs0Y59fHys73PTTTcZWVlZtn4sqWbKsx3n5uYa4eHhxnvvvWcYhmHExsYagDFt2rQyeTapPsqzHW/atMl49tlnjdmzZxtLliwx3n77bcPHx8do3ry5cerUqbJ6RKkGyrMdN27c2PD09DSCgoKMKVOmGH/88YcxYMAAw9HR0dixY0dZPaLIdVPQIJf15ZdfGs8995zx/fffGzExMcaDDz5Yqh+kM2fONADD09PT2Lhxo3V/cnKy0aJFCwMwnn322Uten5ycbERERBgtWrTQBzS5bvZox5s3bzZWrlxpfPbZZ0ZISIjRu3dvo7Cw0KbPJdVLebbjMWPGGE2bNjXy8/MNw1DQILZjr98rzvjzzz8NwJg0adL1PopUY+XZjiMiIgzAmDt3rnVfXl6eERISYjz44IO2fTARG1LQIFdlyJAhpfpB2r59ewMw3njjjQuOLV++3AAMFxcXIy0t7YLjGRkZRrt27Yx69eoZCQkJNqtd5IzyaMfnWrNmjQEYP//883XVLXKusmrHcXFxhouLizF9+nTj5MmTxsmTJ42tW7cagPHVV19dsb2LXI3y/nlsGIbh7+9vPPnkk9dcs8j5yrIdd+jQwQAu6Olw9913G1FRUbZ5AJEyoDkaxOYSEhJYv349APfdd98Fx7t160bdunXJy8tj3rx5JY7l5eVx2223ERcXxx9//EFwcHC51Cxyvutpx+eLiorCZDKxf//+MqlV5FKupR3HxsaSl5fHnXfeiZ+fH35+frRq1QqAYcOGUadOnfJ7ABFs+/P4DJPJZNMaRa7kWtvxuUuznsswDC1vKRWaggaxuc2bNwOWmfbr169/0XPatWtX4lywTJ53zz33sH79eubNm0fjxo3LvliRS7jWdnwxK1euxDAMGjRoYNsiRa7gWtpx69atWbJkSYlt2rRpAIwZM0YTkEm5s+XP4z/++IPU1FQ6dOhg2yJFruBa23F0dDQAixYtsu7Ly8tjxYoV1vNFKiJHexcgVU9sbCwAoaGhlzynbt26Jc4FGDFiBL/++itjx46lqKiINWvWWI81a9YMb2/vMqpY5ELX2o779etH3759iYyMxMXFhc2bN/Pf//6Xli1bcvvtt5dpzSLnu5Z27OvrS69evUqcExcXB1h+Fnfv3t32hYpcxrX+PH7ggQeoX78+bdu2xcvLi7Vr1/LOO+/QunVr7rnnnrItWuQ819qOo6Oj6dy5M4888ghvvfUWtWvX5uOPP+bkyZM8//zzZVu0yHVQ0CA2l5mZCYCHh8clz/H09AQgIyPDuu/3338HLH8xGzNmTInzlyxZcsEvviJl6VrbcYcOHfjuu++svySEhYXx5JNP8swzz+Ds7FyGFYtc6FrbsUhFcq3tODIykqlTpzJu3Dhyc3MJCQlh2LBh/Otf/9LPYyl319qOzWYzc+bM4bnnnuPZZ58lNzeX9u3bs3jx4ksOqxCpCBQ0SIVx5i9mIpXZ2LFjGTt2rL3LELGpsLAwDMOwdxkiV+Wll17ipZdesncZItfN39+fr7/+mq+//trepYiUmuZoEJvz8vICIDs7+5LnZGVlAWg4hFRYasdSFagdS1WgdixVgdqxVDcKGsTmwsLCAIiPj7/kOWeOnTlXpKJRO5aqQO1YqgK1Y6kK1I6lulHQIDbXpk0bAFJSUkpMZnOuDRs2AJZl/0QqIrVjqQrUjqUqUDuWqkDtWKobBQ1icyEhIbRv3x6AqVOnXnB8xYoVxMfH4+LiQv/+/cu7PJFSUTuWqkDtWKoCtWOpCtSOpbpR0CBl4uWXXwbg7bffZtOmTdb9KSkpPPnkkwCMHDkSHx8fu9QnUhpqx1IVqB1LVaB2LFWB2rFUJyZD00jLZWzatMn6gw/gwIEDnDhxgpCQEOrUqWPdP3PmTIKCgkpcO3r0aD766COcnJzo27cvHh4eLFq0iLS0NLp27cqCBQtwc3Mrt2eR6kvtWKoCtWOpCtSOpSpQOxa5MgUNcllLly6ld+/eVzwvNjb2ohPX/PTTT0yYMIEtW7ZQUFBAeHg4DzzwAE8//bTWsJZyo3YsVYHasVQFasdSFagdi1yZggYRERERERERsRnN0SAiIiIiIiIiNqOgQURERERERERsRkGDiIiIiIiIiNiMggYRERERERERsRkFDSIiIiIiIiJiMwoaRERERERERMRmFDSIiIiIiIiIiM0oaBARERERERERm1HQICIiIiIiIiI2o6BBRESkmtm3bx8jR46kWbNmeHh44OrqSkhICO3bt2fkyJHMmDHD3iWWiW+++QaTycTQoUPtXcoFevXqhclkYunSpfYuRURE5Lo52rsAERERKT+//PIL9913H3l5edSoUYOuXbsSEBDAyZMn2bJlCxMmTOCHH35g8ODB9i5VREREKikFDSIiItXEsWPHGDJkCHl5eTz77LO88cYbuLq6ljhn48aNTJ8+3U4VVl9TpkwhJyeH0NBQe5ciIiJy3RQ0iIiIVBNz5swhKyuL4OBg3nvvvYue07ZtW9q2bVvOlYkCBhERqUo0R4OIiEg1cezYMQACAgKu+tpdu3bxr3/9i65du1KnTh2cnZ2pUaMGN9xwAz/99NNFr1m6dCkmk4levXqRl5fH66+/TqNGjXB1dSU0NJQXXniBU6dOAZCens5zzz1HgwYNcHV1JSwsjNdee43CwsIL7jt06FBMJhPffPMNW7du5Y477iAgIAA3NzdatmzJuHHjKCoquupnTExM5JlnnqFp06a4u7vj5eVF+/btGT9+/EXruJzi4mK++OILunbtiq+vL05OTgQGBtKqVStGjRpFXFxcifMvNkfDmTklrrSdf6/CwkImTpxIr1698Pf3x8XFhfr16/PEE08QHx9/1f8uIiIiV0s9GkRERKqJM38137FjB4sWLaJv376lvvaDDz7gq6++okmTJrRo0QJfX18OHz7MkiVLWLRoEWvWrOGDDz646LX5+fn069ePzZs306tXLxo3bszy5ct599132bVrF5MnT6ZLly6kpqbSo0cPIiIiWLZsGa+//jrHjh3j008/veh9161bxxNPPEHt2rXp27cvJ0+eZOnSpTz11FOsWLGCn376CZPJVKrnW7ZsGbfffjsnT54kLCyMG2+8kby8PNatW8eoUaOYPXs2c+bMwcnJqVT3e+SRR5g0aRKurq5069aNgIAAUlNTOXjwIOPHj6dv376EhYVd9h4NGzZkyJAhFz2WkJDAwoULAXBwcLDuz8zMJDo6mqVLl+Lp6Unbtm0JCAhg+/btfPbZZ/z8888sWLCANm3alOo5RERErokhIiIi1UJmZqZRp04dAzBMJpPRq1cvY+zYscbcuXON48ePX/bapUuXGgcOHLhg/+7du42QkBADMNauXVvi2JIlSwzAAIwOHToYJ06csB6Li4sz/Pz8DMBo0aKFMXDgQCM7O9t6fP369Yajo6NhNpuNQ4cOlbjvkCFDrPd98sknjYKCAuuxHTt2GAEBAQZgfPbZZyWumzRpkgEYQ4YMKbE/KSnJqFGjhmEymYxPPvnEKCoqsh47ceKE0adPHwMwXn/99cv+G51x6NAhAzBCQkKMpKSkC47v2rXrgmfq2bOnARhLliy54v1PnjxpREZGGoDx3HPPlTh23333GYAxYMAA49ixYyWO/e9//zMAIyIiwigsLCzVs4iIiFwLDZ0QERGpJjw9PVm0aBEdO3bEMAyWLl3KmDFjuPXWWwkMDKRNmzZ89tlnFx120LNnTxo0aHDB/saNGzNmzBiAS04iaTKZ+Oqrr6hRo4Z1X7169XjwwQcBiI2NZeLEibi7u1uPt2vXjltuuYXi4uJLLvkYFBTE+++/j6Pj2Q6akZGRvPrqqwC8//77V/gXsfjwww9JSUlhxIgRPPHEE5jNZ389qlGjBlOmTMHJyYnx48djGMYV73dmiEpUVBS1a9e+4HjTpk2veU6G/Px8Bg0axM6dO7n77rt59913rcdiYmKYNm0awcHBTJ06lcDAwBLXPvXUU/Tv3599+/Yxf/78a3p/ERGR0lDQICIiUo00btyYNWvWsHbtWl599VX69etnnbNhy5YtPPHEE9x8883k5+dfcG1WVhY///wzL7/8MsOHD2fo0KEMHTqUGTNmALBnz56LvmdoaCjNmze/YH9ERARgmYDy/A/F5x5PTEy86H3/9re/XbBqBmAdbrBv375LXnuuuXPnAnD33Xdf9HidOnWIiIggOTmZffv2XfF+TZo0wcvLi3nz5vHmm28SGxt7xWtKwzAMhg4dytKlS+nRoweTJ08uMTRk3rx5GIbBLbfcgpeX10Xv0atXLwBWrVplk5pEREQuRnM0iIiIVEMdOnSgQ4cOgOUD7ObNm/nvf//LDz/8wMKFCxk3bhz//Oc/refPnj2bhx9+mJSUlEveMyMj46L7L/XXe09Pz8seP/Nh+cyEkeerX7/+Ja+rUaMGKSkpHDlyhODg4EvWDHDw4EEAunfvftnzAJKTk2nUqNFlz/Hy8mLSpEk8/PDDvPLKK7zyyisEBQXRqVMnbr75Zu677z7rs1+Nl156iWnTptGsWTN+/fVXXFxcLvocX331FV999dUVn0NERKSsKGgQERGp5kwmE1FRUUybNo2cnBxmzZrFr7/+ag0aEhISuPvuu8nNzeX555/n/vvvJywsDE9PT8xmM3/++Sf9+vW75LCCc4ciXMvx61GaoQ7FxcUA3HnnnXh4eFz23HOHf1zO4MGDueGGG5g1axbLly9n5cqVzJw5k5kzZ/Lqq6+yYMECWrRoUap7AXz66ae88847BAUFMW/ePPz8/C75HK1bt6ZVq1aXvV/Hjh1L/d4iIiJXS0GDiIiIWN10003MmjWLEydOWPfNnj2b3NxcBg0axDvvvHPBNaUZTlAWLjUkITMz09rzIiQk5Ir3qVu3Lvv27eOFF16gXbt2NqvPx8eHBx980DoXRXx8PKNGjeK3335j5MiR/PXXX6W6z+zZsxk1ahReXl7MnTuXevXqXfI5ALp27cr48eNt8xAiIiLXQHM0iIiIVBOl+ev+4cOHgZIf0FNTUwEu+gHXMAymTp1qowqvzs8//0xeXt4F+7/99lvAsjxknTp1rnifW265BYCffvrJtgWep27durz++uuAZT6M0li/fj333HMPJpOJn3/++bLLUp55jlmzZl1yuImIiEh5UNAgIiJSTXzyyScMGTLkohMBGobBL7/8Yv1L+D333GM91rRpU8CyqkRSUpJ1f1FREa+++qrdJhZMTEzkueeeK7FKRkxMDP/+978BePrpp0t1n3/+85/4+vrywQcf8P777190IszY2Fi+++67Ut1v8+bN/Pjjj+Tm5l5wbPbs2cDFQ5vzHTx4kAEDBpCTk8MXX3xBv379Lnt+mzZtGDx4MPHx8dxxxx3ExcVdcE52djbff/+9dWUMERGRsqChEyIiItVEQUEBU6ZMYcqUKQQEBNCmTRtq1qxJWloau3btsn4wfeCBBxg2bJj1uoEDB9K2bVs2btxIo0aN6NmzJx4eHqxdu5bExEReeOGFiw6pKGuPP/44EydOZO7cuXTs2JGTJ0+yZMkS6xKQTzzxRKnuExISwm+//cbgwYN57rnnePfdd2nevDlBQUGkp6cTExPDgQMH6NixIw888MAV73fo0CHuuece3NzciIqKom7duhQWFrJ9+3b27NmDs7NziWUpL+XNN9/k+PHjBAQE8Ndff11yqMV7771HzZo1AZg0aRJpaWnMnz+fxo0b06pVK+rXr49hGMTFxbF161by8/OJiYmhVq1apfr3ERERuVoKGkRERKqJYcOGUb9+fRYtWsTatWvZtWsXx44dw9HRkeDgYO69914eeughbr755hLXOTo6snTpUt566y1mzJjBokWL8Pb2pkuXLsyYMYPMzEy7BA0dO3Zk+PDh/Otf/2LBggVkZWURERHBsGHDGDVqVImlH6+kR48e7Ny5k/HjxzN37lzWr19PXl4egYGBhIaG8sADDzB48OBS3atTp068/fbbLFu2jJiYGDZv3oyjoyMhISGMGDGCUaNG0bhx4yve50xPjeTkZCZPnnzJ81577TVr0ODl5cWff/7Jjz/+yHfffcfGjRvZsmUL3t7eBAUFcf/99xMdHU14eHipnkVERORamIzSDNgUERERqSCGDh3K5MmTmTRpEkOHDrV3OSIiInIezdEgIiIiIiIiIjajoEFEREREREREbEZBg4iIiIiIiIjYjOZoEBERERERERGbUY8GEREREREREbEZBQ0iIiIiIiIiYjMKGkRERERERETEZhQ0iIiIiIiIiIjNKGgQEREREREREZtR0CAiIiIiIiIiNqOgQURERERERERsRkGDiIiIiIiIiNiMggYRERERERERsZn/B/j+kBocDLrCAAAAAElFTkSuQmCC", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "dist_df = pd.DataFrame.from_dict(kernel_errors)\n", - "\n", - "fig, ax = plt.subplots(figsize=(12,4))\n", - "\n", - "ax.plot(nn, dist_df.quantile(q=0.95,axis=1), label='Q95')\n", - "ax.plot(nn, dist_df.quantile(q=0.5, axis=1), label=\"Q50\")\n", - "ax.plot(nn, dist_df.quantile(q=0.05,axis=1), label='Q05')\n", - "ax.plot(nn, (nn)**(-0.2), linestyle='--', color='black', linewidth=3.0, label=r\"$n^{-1/2}$\")\n", - "#ax.plot(nn, (1/16)*(nn)**(-0.5), linestyle='--', color='black', linewidth=3.0, label=r\"$\\frac{1}{16}n^{-1/2}$\")\n", - "ax.set_ylabel(r\"$|\\hat{f}(x^*) - f(x^*)|$\")\n", - "ax.set_xlabel(r\"Sample size\")\n", - "ax.set_yscale('log')\n", - "ax.set_xscale('log')\n", - "ax.legend(title=r\"$h_n = 2n^{-0.2}$\")\n", - "ax.grid()\n", - "\n", - "ax.tick_params(axis='both', which='major', labelsize=16)\n", - "ax.xaxis.get_label().set_fontsize(16)\n", - "ax.yaxis.get_label().set_fontsize(16)\n", - "ax.legend(prop={'size': 16})" - ] - }, - { - "cell_type": "markdown", - "id": "97866c6a", - "metadata": {}, - "source": [ - "Setting the bandwidth parameter $h_n \\approx n^{-0.5}$ means that the number of samples grows faster than the rate at which $h_n$ shrinks. This setting shows that convergence to the true distribution is achieved over the entire input domain. " - ] - }, - { - "cell_type": "markdown", - "id": "5b4cd191", - "metadata": {}, - "source": [ - "## 4. Using a Kernel Density Estimator" - ] - }, - { - "cell_type": "markdown", - "id": "23a98b66", - "metadata": {}, - "source": [ - "### 4.1 Distribution Visualisation\n", - "\n", - "A canonical use-case is to use the KDE for brief simple visualization tasks. Here, we might be interested in simple univariate or bivariate distributions. For example, below we have a simple Gaussian Mixture Model (a modification of the [scikit-learn](https://scikit-learn.org/stable/auto_examples/neighbors/plot_kde_1d.html) tutorial)." - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "id": "15e265da", - "metadata": {}, - "outputs": [], - "source": [ - "N = 10000\n", - "np.random.seed(1)\n", - "\n", - "lw= 3.\n", - "left_mass_param = 0.3\n", - "right_mass_param = 1. - left_mass_param\n", - "X_train = np.concatenate(\n", - " (np.random.normal(0, 1, int(left_mass_param * N)), \n", - " np.random.normal(5, 1, int(right_mass_param * N)))\n", - ")[:, np.newaxis]\n", - "\n", - "X_plot = np.linspace(-5, 10, 1000)[:, np.newaxis] # Linearly spaced points on the interval.\n", - "\n", - "################ True density function ################\n", - "true_dens = left_mass_param * stats.norm(0, 1).pdf(X_plot[:, 0]) + right_mass_param * stats.norm(5, 1).pdf(X_plot[:, 0])" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "id": "dbc04423", - "metadata": {}, - "outputs": [], - "source": [ - "def make_basic_plot():\n", - " fig, ax = plt.subplots(figsize=(16,8))\n", - " ax.fill(X_plot[:, 0], true_dens, fc=\"black\", alpha=0.2, label=\"input distribution\")\n", - " lw = 2\n", - "\n", - " ax.legend(loc=\"upper left\", title=\"N={0} points\".format(N))\n", - " ax.plot(X_train[:, 0], -0.005 - 0.01 * np.random.random(X_train.shape[0]), \"+k\", alpha=0.1, label='samples')\n", - "\n", - " ax.set_xlim(-4, 9)\n", - " return fig, ax" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "id": "97c19eb9", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 21, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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S2+//baysrLkdrvlcrkUFRVlOK/i9d26dWv2TaxYQxEAAAAAWpCDI/JglJ2dbXYLQKsxevRoJSYmauHChYZ1WJ1Op8aOHavU1FTDx/bt23XRRReVn1ddeH9wGq+k8hGOBwM4p9Op6667znDf9evXa8eOHeXh2pEsXbpUHTp0qPHju+++q/PXozrFxcWaNm2aYmNjtXTpUv388896//33JR3ajCYoKKjSWrYej8dwPG/ePG3atEkzZ87UV199paFDh5bf5+qrr9bu3bt1ySWXaOPGjRo3bpyefvrpKvt55JFH9OSTT+quu+7S119/rdTUVE2bNq3SxjiH/ztIB/4tDv47NBdGKAIAAABAC7J//365XC6z22hx7Ha7HA5Ho41eAuqic+co5efPPfKJTdxDbfXr10+PPvqoJk+erODgYD3zzDOSpDFjxuitt95Sly5dFBsb26j9jRkzRps3b1b//v3rfY+GTnk+XN++fRUaGqqff/5ZvXr1kiTZbDZt375dJ5xwgiRp69at2r9/v+bPn6/k5GRJKt9M5aDExEQ5HA7DKOnU1NRKzzdw4EANHDhQf/7zn3XhhRdq0aJFOuussyRJycnJuv7663X99dfr7rvv1ssvv6xbbrml0j1++OEHnXHGGfrjH/8o6UBYu3379lqPlGxOBIoAAAAA0EIEAgF2Na5BdnZ2pemKQHMICrLUeUMUsw0cOFBff/21Jk+erJCQED3xxBO6+OKL9cgjj+iMM87QAw88oJ49eyojI0Pvvfee7rzzTvXs2bPez3fXXXdpwoQJuvnmm3X11VeXb0DyxRdflAeaR9KYU55jYmJ02WWX6Y477lCnTp3UpUsX3XfffQoKCiofXdmrVy+FhYXp6aef1vXXX6/ff/9dDz74oOE+48ePV1RUlP7617/q1ltv1dq1a7V48eLyx0tLS3XHHXfo3HPPVZ8+fbR37179/PPPOueccyRJt912m6ZPn66BAweqqKhIX3/9dbXTvwcMGKB3331XP/74ozp27KjHHntMeXl5LTJQZMozAAAAALQQBQUFlaa24RCn0ym73W52G0CrMWjQIH311VdatmyZbr/9dkVFRenbb79Vr169dPbZZ2vIkCG66qqrVFZW1uARiyNGjNA333yj7du36/jjj9fo0aN17733VtoEpTk99thjmjhxombNmqWpU6dq0qRJGjJkSPkGMYmJiVq8eLHeeecdDR06VPPnz9eCBcbdvDt16qTXX39dn376qYYPH65ly5YZNn8JDg7W/v37demll2rgwIE6//zzNX36dN1///2SDqyLeNNNN2nIkCE67bTTNHDgQD333HNV9vu3v/1NY8aM0bRp0zR58mQlJSXpzDPPbJKvTUNZAhUngrdCdrtdcXFxstlsjT5kFwAAAACag9/v1++//15pbS4YRUdHl++kCjSlsrIypaWlqU+fPrXaoRgtX3FxsXr06KFHH31UV111ldntmKa67+265GtMeQYAAACAFqCgoIAwsRaKi4tlt9sZTALgiH777Tdt3bpVxxxzjGw2mx544AFJ0hlnnGFyZ60fgSIAAAAAmCwQCCgvL8/sNlqNnJwcAkUAtbJgwQJt27ZNYWFhGjt2rL777jslJCSY3VarR6AIAAAAACbbv38/ayfWgdPpZMdnAEc0evRo/frrr2a30SaxKQsAAAAAmCgQCCg3N9fsNloddsMGAPMQKAIAAACAiYqKiuRyucxuo9VxOBwqLi42uw20A21gL1vAoDG+pwkUAQAAAMBEjE6sP752aEqhoaGSpJKSEpM7ARrXwe/pg9/j9cEaigAAAABgEpvNptLSUrPbaLWsVqvKysoUERFhditog4KDgxUfH6/8/HxJUlRUlCwWi8ldAfUXCARUUlKi/Px8xcfHKzg4uN73IlAEAAAAAJMwwq7hcnNzlZKSYnYbaKOSkpIkqTxUBNqC+Pj48u/t+iJQBAAAAAATFBcXy+l0mt1Gq1dYWKgePXo0aOoeUB2LxaJu3bqpS5cu8ng8ZrcDNFhoaGiDRiYeRKAIAAAAACZgdGLjCAQCysvLU8+ePc1uBW1YcHBwo4QwQFtBoAgAAAAAzczlcslqtZrdRpX8/oCys0u0d2+JnE6Pysp88nj8iokJVceO4UpICFfPntEKDm45a8kVFBSoe/fuCgpi31EAaA4EigAAAADQzFrSemx+f0C//27Vd9/l6ZdfCrRzp0Olpb4ar4mODtGQIXEaPryjTjopSUOGxJm6WYXP51NBQYG6dOliWg8A0J5YAoFAwOwmGsputysuLk42m02xsbFmtwMAAAAA1fL5fNqwYYP8fr+pfWRnl+idd9L16adZ2r/f1aB79egRpWnTuuvcc3urS5fIRuqwbsLDwzVs2DB24QWAeqpLvlav8eDPPvusUlJSFBERofHjx+unn36q9tyXX35Zxx9/vDp27KiOHTtq6tSplc6//PLLZbFYDB+nnXZafVoDAAAAgBatoKDA1DBxyxar5s79WWee+ZVee213g8NEScrKKtHChTt1+ulf6cEH1ysjo/k3m3G5XLLZbM3+vADQHtU5UHzrrbc0Z84c3XfffVq3bp1GjhypadOmVTtkf9WqVbrwwgv19ddfa/Xq1UpOTtapp56qrKwsw3mnnXaacnJyyj+WLVtWv88IAAAAAFqoQCBg2nTn3NxS/f3vv+mSS77XqlV5OlKmGRsbqt69ozVkSJyOOipeyclR6tCh5lWzvN6APvxwj847b5Uefvh3ORzNuytuS5pKDgBtWZ2nPI8fP15HH320nnnmGUmS3+9XcnKybrnlFv3lL3854vU+n08dO3bUM888o0svvVTSgRGKVqtVH3zwQd0/AzHlGQAAAEDrYLVatWvXrmZ9Tq/Xr1df3aVXXtkht7v6FLFv3w464YSuGjcuQf37x6hz5/Aqpw8XFJRp0yar1q8v0tdf52jPnpJq79mpU5huvXWIZs7s2WxTkYcOHarISHOmXQNAa1aXfK1Om7K43W79+uuvuvvuu8trQUFBmjp1qlavXl2re5SUlMjj8ahTp06G+qpVq9SlSxd17NhRU6ZM0T/+8Q917ty5ynu4XC65XIeG5dvt9rp8GgAAAABgiuYeQZeW5tB996Vq8+aqpwJHR4fo9NOTdc45vZWS0qFW90xIiNCJJybpxBOTdMstg7V1q00ffrhHy5fvqRRYFha6NW/eeq1alau//32k4uLCGvw5HUl+fr569+7d5M8DAO1ZnaY8FxQUyOfzqWvXroZ6165dlZubW6t73HXXXerevbumTp1aXjvttNP06quvauXKlfr3v/+tb775RtOnT5fPV/XOYg899JDi4uLKP5KTk+vyaQAAAABAsystLZXD4Wi253v//QxdfPF3VYaJ0dEhuvnmwfr006m6/fZhtQ4TK7JYLBoyJF5/+ctwLV8+RZde2k/h4ZVfZq5alaeLLvpWv/22v17PUxeFhYXyer1N/jwA0J7Vacpzdna2evTooR9//FETJ04sr99555365ptvtHbt2hqvnz9/vh5++GGtWrVKI0aMqPa83bt3q1+/fvryyy918sknV3q8qhGKycnJTHkGAAAA0GJlZGSo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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "################ KDE functions ################\n", - "colors = [\"navy\"]\n", - "kernels = [\"gaussian\"]\n", - "fig, ax = make_basic_plot()\n", - "for color, kernel in zip(colors, kernels):\n", - " kde = kernel_density(X_train, X_plot, 0.5) \n", - " ax.plot(\n", - " X_plot[:, 0],\n", - " kde,\n", - " color=color,\n", - " lw=lw,\n", - " linestyle=\"-\",\n", - " label=\"kernel = '{0}'\".format(kernel),\n", - " )\n", - "ax.legend()" - ] - }, - { - "cell_type": "markdown", - "id": "505777e8", - "metadata": {}, - "source": [ - "We can also plot bivariate examples such as a 2d Gaussian distribution. The next cell generates a bivariate Gaussian distribution." - ] - }, - { - "cell_type": "code", - "execution_count": 40, - "id": "c7dc0f22", - "metadata": {}, - "outputs": [], - "source": [ - "x = np.linspace(-3, 3)\n", - "y = np.linspace(-3, 3)\n", - "\n", - "X_test, Y_test = np.meshgrid(x, y)\n", - "X_plot = np.c_[X_test.ravel(), Y_test.ravel()]\n", - "\n", - "# Generate input distribution\n", - "means = [0, 0]\n", - "covariances = np.array([[1., 0.4],\n", - " [0.8, 1.]])\n", - "mvn = stats.multivariate_normal(mean=means, cov=covariances)\n", - "X_train = mvn.rvs(size=10000)\n", - "dist = mvn.pdf(X_plot)" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "id": "372e55ba", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Text(0.5, 1.0, 'Samples from Bivariate Normal')" - ] - }, - "execution_count": 23, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAiIAAAGzCAYAAAASZnxRAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/SrBM8AAAACXBIWXMAAA9hAAAPYQGoP6dpAAB6PklEQVR4nO3deXgUZdY+/rsTks4C2QjQAVnCpoawCLKJw2YQFAV1dARlBPSLyuKCjiLOKDLMDCL+Bn0FETecdxTcFVSMA4IiGMRXiBAjCjFBJiRAFjohIQvp+v0Rq+mlqruquqq7Ork/18V1kU5315NOp+vU85znHIsgCAKIiIiIQiAi1AMgIiKi1ouBCBEREYUMAxEiIiIKGQYiREREFDIMRIiIiChkGIgQERFRyDAQISIiopBhIEJEREQhw0CEiIiIQoaBCJFGFosFTzzxRFCPeeLECdx4441o3749LBYLnnnmmaAe30hjx47F2LFjQ3LsL774AhaLBV988UVIjt8a9ejRA7NmzQr1MMgEGIhQSB08eBA33ngjunfvjpiYGHTp0gUTJkzAc889F+qhmdLChQvx2WefYfHixfj3v/+NSZMmhXpIsoqKimCxWNz+JSQkYNCgQVi9ejWamppCPURdbNmyxZCA9IknnoDFYkGnTp1QW1vr9f0ePXrgmmuu0f24RMHWJtQDoNbr66+/xrhx49CtWzfMmTMHNpsNx44dw549e/Dss8/innvuCfUQTWf79u2YOnUq/vSnP4V6KIpNnz4dV199NQDAbrdjy5YtuOeee3D06FGsXLnSeb///Oc/oRoiRo8ejbNnzyI6Olr1Y7ds2YI1a9YYNjt28uRJrF27Fg8++KAhz08UagxEKGT+/ve/IzExEd9++y2SkpLcvnfy5MnQDMrkTp486fVaSampqUF8fLzxA1Jg8ODBmDFjhvPrefPmYfjw4diwYYNbIKIlCAhUXV0doqOjERERgZiYmKAfX4lBgwZh5cqVmDdvHmJjYw05hsPhQENDg2lfA2rZuDRDIVNQUIB+/fpJnlg7duzo9vX69esxfvx4dOzYEVarFRkZGVi7dq3X48Tp6i+++AKXXnopYmNj0b9/f+fa//vvv4/+/fsjJiYGQ4YMwf79+90eP2vWLLRt2xa//PILJk6ciPj4eHTu3Bl//etfoaRRdXFxMW6//XZ06tQJVqsV/fr1w6uvvup1v+eeew79+vVDXFwckpOTcemll2LDhg2yz/vaa6/BYrFAEASsWbPGudTh+r0vv/wS8+bNQ8eOHXHBBRc4H/v888+jX79+sFqt6Ny5M+bPn4/Tp0+7Pf/YsWORmZmJAwcOYMyYMYiLi0Pv3r3x7rvvAgC+/PJLDB8+HLGxsbjwwguxbds2v6+FHHG5oU0b9+sg1xyREydOoE2bNli6dKnX43/66SdYLBasXr0aAFBRUYE//elP6N+/P9q2bYuEhARcddVV+P77790eJ+aBvPnmm/jLX/6CLl26IC4uDlVVVZI5Il999RVuuukmdOvWDVarFV27dsXChQtx9uxZ531mzZqFNWvWOH8u198L0HyCf+aZZ9CvXz/ExMSgU6dOuOuuu1BZWan49Xr88cdx4sQJyfe7p5qaGjz44IPo2rUrrFYrLrzwQjz99NNe712LxYIFCxbgjTfecL43srOzne+lXbt24d5770WHDh2QlJSEu+66Cw0NDTh9+jRuu+02JCcnIzk5GQ8//LDXcz/99NO47LLL0L59e8TGxmLIkCHO9xGRFM6IUMh0794dOTk5yMvLQ2Zmps/7rl27Fv369cOUKVPQpk0bfPTRR5g3bx4cDgfmz5/vdt8jR47glltuwV133YUZM2bg6aefxrXXXosXXngBjz76KObNmwcAWL58Of7whz/gp59+QkTE+Zi8qakJkyZNwogRI/DUU08hOzsbS5Yswblz5/DXv/5VdownTpzAiBEjnB/yHTp0wKeffoo77rgDVVVVuP/++wEAL730Eu69917ceOONuO+++1BXV4cDBw7gm2++wS233CL53KNHj8a///1v/PGPf8SECRNw2223ed1n3rx56NChAx5//HHU1NQAaM4zWLp0KbKysjB37lz89NNPWLt2Lb799lvs3r0bUVFRzsdXVlbimmuuwbRp03DTTTdh7dq1mDZtGt544w3cf//9uPvuu3HLLbdg5cqVuPHGG3Hs2DG0a9fO5+8NAGpra1FWVgYAqKqqwqeffors7GwsXrxY9jGdOnXCmDFj8Pbbb2PJkiVu33vrrbcQGRmJm266CQDwyy+/4MMPP8RNN92E9PR0nDhxAuvWrcOYMWOQn5+Pzp07uz1+2bJliI6Oxp/+9CfU19fLzsS88847qK2txdy5c9G+fXvs3bsXzz33HP773//inXfeAQDcddddOH78OLZu3Yp///vfXs9x11134bXXXsPs2bNx7733orCwEKtXr8b+/fu9Xn85v/vd7zB+/Hg89dRTmDt3ruysiCAImDJlCnbs2IE77rgDgwYNwmeffYaHHnoIxcXFWLVqldv9t2/fjrfffhsLFixAamoqevTogdzcXADAPffcA5vNhqVLl2LPnj148cUXkZSUhK+//hrdunXDP/7xD2zZsgUrV65EZmam2/vx2WefxZQpU3DrrbeioaEBb775Jm666SZ8/PHHmDx5st+fl1ohgShE/vOf/wiRkZFCZGSkMHLkSOHhhx8WPvvsM6GhocHrvrW1tV63TZw4UejZs6fbbd27dxcACF9//bXzts8++0wAIMTGxgpHjx513r5u3ToBgLBjxw7nbTNnzhQACPfcc4/zNofDIUyePFmIjo4WTp065bwdgLBkyRLn13fccYeQlpYmlJWVuY1p2rRpQmJiovNnmDp1qtCvXz8/r440AML8+fPdblu/fr0AQLj88suFc+fOOW8/efKkEB0dLVx55ZVCU1OT8/bVq1cLAIRXX33VeduYMWMEAMKGDRuctx06dEgAIERERAh79uxx3i6+nuvXr/c51sLCQgGA5L+5c+cKDofD7f5jxowRxowZ4/xa/P0cPHjQ7X4ZGRnC+PHjnV/X1dW5/Xzisa1Wq/DXv/7VeduOHTsEAELPnj293k/i91zfC1LvueXLlwsWi8XtfTR//nxB6qP0q6++EgAIb7zxhtvt2dnZkrd7WrJkiQBAOHXqlPDll18KAIR//vOfzu93795dmDx5svPrDz/8UAAg/O1vf3N7nhtvvFGwWCzCkSNHnLeJv9cffvjB7b7ie2nixIluv5+RI0cKFotFuPvuu523nTt3TrjgggvcfmeC4P26NTQ0CJmZmW6/M3H8M2fO9PkaUOvApRkKmQkTJiAnJwdTpkzB999/j6eeegoTJ05Ely5dsHnzZrf7ul4F2u12lJWVYcyYMfjll19gt9vd7puRkYGRI0c6vx4+fDgAYPz48ejWrZvX7b/88ovX2BYsWOD8vzjD0dDQILskIQgC3nvvPVx77bUQBAFlZWXOfxMnToTdbse+ffsAAElJSfjvf/+Lb7/9VtHrpNScOXMQGRnp/Hrbtm1oaGjA/fff7zbjM2fOHCQkJOCTTz5xe3zbtm0xbdo059cXXnghkpKScPHFFztfK8D36yblzjvvxNatW7F161a89957mD9/PtatW4cHHnjA5+NuuOEGtGnTBm+99Zbztry8POTn5+Pmm2923ma1Wp0/X1NTE8rLy9G2bVtceOGFztfc1cyZMxXlWrjep6amBmVlZbjssssgCILXkp6Ud955B4mJiZgwYYLb+2HIkCFo27YtduzY4fc5RKNHj8a4cePw1FNPuS0NudqyZQsiIyNx7733ut3+4IMPQhAEfPrpp263jxkzBhkZGZLPdccdd7gtMQ0fPhyCIOCOO+5w3hYZGYlLL73U633g+rpVVlbCbrfjd7/7neTvgghgjgiF2NChQ/H++++jsrISe/fuxeLFi1FdXY0bb7wR+fn5zvvt3r0bWVlZiI+PR1JSEjp06IBHH30UALwCEddgAwASExMBAF27dpW83XO9PiIiAj179nS7rW/fvgCat6RKOXXqFE6fPo0XX3wRHTp0cPs3e/ZsAOcTcBctWoS2bdti2LBh6NOnD+bPn4/du3f7fqEUSE9Pd/v66NGjAJoDClfR0dHo2bOn8/uiCy64wO3kAzS/RkpfNzl9+vRBVlYWsrKycMMNN2D16tWYN28ennnmGRw8eFD2campqbjiiivw9ttvO29766230KZNG9xwww3O2xwOB1atWoU+ffrAarUiNTUVHTp0wIEDB7zeG4D36yTn119/xaxZs5CSkoK2bduiQ4cOGDNmDADv95yUw4cPw263o2PHjl7viTNnzqhOyH7iiSdQWlqKF154QfL7R48eRefOnb2Wyy6++GLn9135eh3U/A15vg8+/vhjjBgxAjExMUhJSUGHDh2wdu1aRa8ZtU7MESFTiI6OxtChQzF06FD07dsXs2fPxjvvvIMlS5agoKAAV1xxBS666CL885//RNeuXREdHY0tW7Zg1apVcDgcbs/lOiug5HZBQRKqP+IYZsyYgZkzZ0reZ8CAAQCaTww//fQTPv74Y2RnZ+O9997D888/j8cff1wyOVOpQHdUBPN1u+KKK7B69Wrs3LkT/fv3l73ftGnTMHv2bOTm5mLQoEF4++23ccUVVyA1NdV5n3/84x947LHHcPvtt2PZsmVISUlBREQE7r//fq/3BqDsdWpqasKECRNQUVGBRYsW4aKLLkJ8fDyKi4sxa9Ysyef15HA40LFjR7zxxhuS3+/QoYPf53A1evRojB07Fk899RTuvvtuVY+V4ut1UPNecH0ffPXVV5gyZQpGjx6N559/HmlpaYiKisL69et9JmNT68ZAhEzn0ksvBQCUlJQAAD766CPU19dj8+bNbldqaqa21XA4HPjll1+csyAA8PPPPwNo3pUjpUOHDmjXrh2ampqQlZXl9xjx8fG4+eabcfPNN6OhoQE33HAD/v73v2Px4sW6baHs3r07gOZdJq4zPA0NDSgsLFQ0TqOcO3cOAHDmzBmf97vuuutw1113OZdnfv75Z68k13fffRfjxo3DK6+84nb76dOn3QIWNQ4ePIiff/4Z//rXv9wSMbdu3ep1X89ZJFGvXr2wbds2jBo1Srdtt0888QTGjh2LdevWeX2ve/fu2LZtG6qrq91mRQ4dOuT8vtHee+89xMTE4LPPPoPVanXevn79esOPTeGLSzMUMjt27JC8qt6yZQuA80sK4lWY633tdruhH27i1lDxuKtXr0ZUVBSuuOIKyftHRkbi97//Pd577z3k5eV5ff/UqVPO/5eXl7t9Lzo6GhkZGRAEAY2NjTr9BEBWVhaio6PxP//zP26v3SuvvAK73R7SHQwfffQRAGDgwIE+75eUlISJEyfi7bffxptvvono6Ghcd911bveJjIz0eh+98847KC4u1jw+qfecIAh49tlnve4r1mvx3BL9hz/8AU1NTVi2bJnXY86dO+d1fyXGjBmDsWPHYsWKFairq3P73tVXX42mpia39y4ArFq1ChaLBVdddZXq46kVGRkJi8XiVjW3qKgIH374oeHHpvDFGREKmXvuuQe1tbW4/vrrcdFFF6GhoQFff/013nrrLfTo0cOZW3HllVciOjoa1157Le666y6cOXMGL730Ejp27OicNdFTTEwMsrOzMXPmTAwfPhyffvopPvnkEzz66KM+p9OffPJJ7NixA8OHD8ecOXOQkZGBiooK7Nu3D9u2bUNFRYXz57HZbBg1ahQ6deqEH3/8EatXr8bkyZMVbYdVqkOHDli8eDGWLl2KSZMmYcqUKfjpp5/w/PPPY+jQoW5Fxoy0b98+vP766wCA6upqfP7553jvvfdw2WWX4corr/T7+JtvvhkzZszA888/j4kTJ3rVnbnmmmvw17/+FbNnz8Zll12GgwcP4o033vDK81HjoosuQq9evfCnP/0JxcXFSEhIwHvvvSeZFzNkyBAA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IV/GTInDZhoLEZHeGIiYhBEJneFKTb6MEcwQCJlxLERERmAgYiKhLONuJqHOlwl1IGTWsRARGYE5IibDlvKhz5cJdSCk5RjhnMRMRK0bAxETau3dYP1VTrWgeZbIqHyZUAdCWo4R7knMRNR6cWmGTCfU+TJmShw201iIiIzAQIRMKZT5MqEOhMw6FiIiI1gEQTBtun1VVRUSExNht9uRkJAQ6uFQCISyiJeZaneYaSxERP6oOX8zECHywUzVTM00FiIiX9Scv5msSuSDmRKHzTQWIiK9MEeEiIiIQoaBCBEREYUMAxEiIiIKGQYiREREFDIMRIiIiChkGIgQERFRyDAQISIiopBhIEJEREQhw0CEiIiIQsbUlVXF6vNVVVUhHgkREREpJZ63lXSRMXUgUl1dDQDo2rVriEdCREREalVXVyMxMdHnfUzd9M7hcOD48eNo164dLBb1zb2qqqrQtWtXHDt2jE3zTI6/q/DB31X44O8qfLS035UgCKiurkbnzp0REeE7C8TUMyIRERG44IILAn6ehISEFvGLbQ34uwof/F2FD/6uwkdL+l35mwkRMVmViIiIQoaBCBEREYVMiw5ErFYrlixZAqvVGuqhkB/8XYUP/q7CB39X4aM1/65MnaxKRERELVuLnhEhIiIic2MgQkRERCHDQISIiIhChoEIERERhQwDESIiIgqZVheI1NfXY9CgQbBYLMjNzQ31cMhDUVER7rjjDqSnpyM2Nha9evXCkiVL0NDQEOqhEYA1a9agR48eiImJwfDhw7F3795QD4k8LF++HEOHDkW7du3QsWNHXHfddfjpp59CPSxS4Mknn4TFYsH9998f6qEEVasLRB5++GF07tw51MMgGYcOHYLD4cC6devwww8/YNWqVXjhhRfw6KOPhnpord5bb72FBx54AEuWLMG+ffswcOBATJw4ESdPngz10MjFl19+ifnz52PPnj3YunUrGhsbceWVV6KmpibUQyMfvv32W6xbtw4DBgwI9VCCT2hFtmzZIlx00UXCDz/8IAAQ9u/fH+ohkQJPPfWUkJ6eHuphtHrDhg0T5s+f7/y6qalJ6Ny5s7B8+fIQjor8OXnypABA+PLLL0M9FJJRXV0t9OnTR9i6daswZswY4b777gv1kIKq1cyInDhxAnPmzMG///1vxMXFhXo4pILdbkdKSkqoh9GqNTQ04LvvvkNWVpbztoiICGRlZSEnJyeEIyN/7HY7APBvyMTmz5+PyZMnu/19tSam7r6rF0EQMGvWLNx999249NJLUVRUFOohkUJHjhzBc889h6effjrUQ2nVysrK0NTUhE6dOrnd3qlTJxw6dChEoyJ/HA4H7r//fowaNQqZmZmhHg5JePPNN7Fv3z58++23oR5KyIT1jMgjjzwCi8Xi89+hQ4fw3HPPobq6GosXLw71kFstpb8rV8XFxZg0aRJuuukmzJkzJ0QjJwpf8+fPR15eHt58881QD4UkHDt2DPfddx/eeOMNxMTEhHo4IRPWvWZOnTqF8vJyn/fp2bMn/vCHP+Cjjz6CxWJx3t7U1ITIyEjceuut+Ne//mX0UFs9pb+r6OhoAMDx48cxduxYjBgxAq+99hoiIsI6Zg57DQ0NiIuLw7vvvovrrrvOefvMmTNx+vRpbNq0KXSDI0kLFizApk2bsHPnTqSnp4d6OCThww8/xPXXX4/IyEjnbU1NTbBYLIiIiEB9fb3b91qqsA5ElPr1119RVVXl/Pr48eOYOHEi3n33XQwfPhwXXHBBCEdHnoqLizFu3DgMGTIEr7/+eqv4QwwHw4cPx7Bhw/Dcc88BaJ7279atGxYsWIBHHnkkxKMjkSAIuOeee/DBBx/giy++QJ8+fUI9JJJRXV2No0ePut02e/ZsXHTRRVi0aFGrWU5rFTki3bp1c/u6bdu2AIBevXoxCDGZ4uJijB07Ft27d8fTTz+NU6dOOb9ns9lCODJ64IEHMHPmTFx66aUYNmwYnnnmGdTU1GD27NmhHhq5mD9/PjZs2IBNmzahXbt2KC0tBQAkJiYiNjY2xKMjV+3atfMKNuLj49G+fftWE4QArSQQofCxdetWHDlyBEeOHPEKElvB5J2p3XzzzTh16hQef/xxlJaWYtCgQcjOzvZKYKXQWrt2LQBg7NixbrevX78es2bNCv6AiPxoFUszREREZE7MACQiIqKQYSBCREREIcNAhIiIiEKGgQgRERGFDAMRIiIiChkGIkRERBQyDESIiIgoZBiIEBERUcgwECEiIqKQYSBCREREIcNAhIiIiELm/weoNFgGUKrXIQAAAABJRU5ErkJggg==", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.scatter(X_train[:,0], X_train[:,1])\n", - "plt.title(\"Samples from Bivariate Normal\")" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "id": "5505c290", - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/var/folders/ts/39plpy691lg3xd9rvzndrmt40000gq/T/ipykernel_20006/3788610756.py:29: UserWarning: set_ticklabels() should only be used with a fixed number of ticks, i.e. after set_ticks() or using a FixedLocator.\n", - " ax_both.set_yticklabels(ylabels)\n", - "/var/folders/ts/39plpy691lg3xd9rvzndrmt40000gq/T/ipykernel_20006/3788610756.py:33: UserWarning: set_ticklabels() should only be used with a fixed number of ticks, i.e. after set_ticks() or using a FixedLocator.\n", - " ax_both.set_xticklabels(ylabels)\n" - ] - }, - { - "data": { - "text/plain": [ - "Text(0.5, 0.98, 'True Distribution')" - ] - }, - "execution_count": 24, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAp4AAALjCAYAAAC7ygWMAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/SrBM8AAAACXBIWXMAAA9hAAAPYQGoP6dpAAB2s0lEQVR4nO3dd3hUZd6H8e9Meg8hCS2hl9C7KCgERQTFipV1BXtfXV0Vyyoqroq9d9HVtfeuSFVRkS6d0FKAUEIK6cmc949AXpCWMjPPmZn7c125LkmZ+SVq5uY55zzHYVmWJQAAAMDDnKYHAAAAQGAgPAEAAOAVhCcAAAC8gvAEAACAVxCeAAAA8ArCEwAAAF5BeAIAAMArCE8AAAB4BeEJAAAAryA8AT/mcDjq/Zaenm567DqbNWvWAfOHhIQoISFBnTt31tlnn60nn3xS27ZtO+RjbNy4UQ6HQ23btvXe4Iex93v6678Hu825196fOwDURbDpAQB4zvjx4w9439atW/X9998f8uNpaWken8sT9n4vlmWpsLBQWVlZ+uKLL/Txxx/r1ltv1W233aa7775bISEhHnn+WbNmafjw4Ro2bJhmzZrlkefwtvT0dM2ePVszZ870qb+QALAvwhPwY2+88cYB75s1a1ZteB7s477qYN9Lfn6+nn32Wd13332aPHmy1q5dq3fffXe/FbpWrVpp5cqVHgvS+jrqqKO0cuVKRUZGmh6lTlauXGl6BAA+hEPtAPxWfHy87rrrLn3yySdyOBx6//339fbbb+/3OSEhIUpLS1OHDh0MTbm/yMhIpaWlqXXr1qZHqZO0tDSfXSUH4H2EJ4BakyZNksPh0KRJk5SZmalLL71UqampCgkJ0YQJEyTVrCw6HI7aP//Vkc5F3LVrl+655x716dNHMTExioyMVM+ePTV58mSVlJR45PsaM2aMzj77bEnSlClT6jzv2rVrdckll6hdu3YKCwtTdHS02rRpo1NOOUVTp06t/bz09HQNHz5ckjR79uz9zjnd93EnTJggh8OhN954Q8uWLdN5552nFi1aKCgoSJMmTZJ06HM891VVVaUpU6aoe/fuioiIUGJios4991ytWrXqgM+ty7mhbdu2lcPh0MaNG/ebYfbs2ZKk4cOH7/c97bu6fLhzPPPy8nTHHXeoe/fuioyMVExMjPr3768pU6aotLT0gM/f93uvrKzUww8/XPs9Nm3aVGeddRYrrICP41A7gAOsXbtWffv2VWhoqIYMGSLLspSYmNjox12xYoVGjRqlrKwstWjRQscee6xCQkI0b948/fvf/9bHH3+sWbNmKS4uzg3fxf4uvPBCffjhh1q2bJm2bt2q5s2bH/bzly1bpiFDhqiwsFBdunTRmDFjFBQUpOzsbM2ZM0c5OTm6+OKLJUmjRo1SeHi4vv/+ezVr1kyjRo2qfZyD/dzmzp2rq666Si1atNDQoUNVWlqqmJiYOn8v5513nr788ksNGzZMvXr10rx58/Thhx/q22+/1Q8//KBjjjmmzo91MM2bN9f48eP13XffKTc3VyeddNJ+P6+OHTse8THWr1+v448/Xps2bVJSUpJOPvlkVVZWaubMmbrtttv0/vvv68cff1STJk0O+NrKykqdfPLJmjt3roYOHaquXbtq3rx5+vTTTzVz5kwtWrTIdhdZAagjC0BAmTlzpiXJOtj//vfcc0/txy688EKrrKzsgM+ZOnWqJckaP378QR9/w4YNliSrTZs2+72/pKTE6tChgyXJuuuuu6zy8vLajxUXF1sXXHCBJcm6+OKL3fK9/FV2dnbt5/74449HnPfiiy+2JFmTJ08+4LFKSkqs2bNnH3SWYcOGHXKG8ePH184wceJEq7q6+pDf018fZ++ckqzExERryZIltR+rqqqyrr/++trvY99/b4f6/vbVpk0bS5K1YcOG/d4/bNgwS5I1c+bMQ37toX7+gwYNsiRZp512mrV79+7a92/bts3q16+fJckaN27cQb93SVbfvn2tLVu21H6stLTUOumkkyxJ1hVXXHHIeQDYG4faARwgISFBzz77rMLCwtz2mG+++abWrVunMWPG6P7771doaGjtxyIjI/Xyyy8rOTlZb731lnbt2uW2591r35XHnTt3HvHzc3NzJUknn3zyAR+LiIjQ0KFDGzxL586dNXnyZDmdDfsVfNddd6lXr161fw4KCtIjjzyiVq1aadOmTfr4448bPJs7/Pzzz/r9999r/71GRUXVfiwpKUkvv/yyJOm9995Tdnb2AV/vcDg0derU/VZZw8PDde+990qSfvzxRw9/BwA8hfAEcIARI0a4/XD3119/LanmMPHBREdHa8CAAaqqqtIff/zh1ueWJJfLVfvPddl38qijjpIkXX311fr+++9VVlbm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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "fig = plt.figure()\n", - "fig.set_figheight(8)\n", - "fig.set_figwidth(8)\n", - "\n", - "ax_component1 = plt.subplot2grid(shape=(3, 3), loc=(0, 0), colspan=2)\n", - "ax_component2 = plt.subplot2grid(shape=(3, 3), loc=(1, 2), rowspan=2)\n", - "ax_both = plt.subplot2grid((3, 3), (1, 0), rowspan=2, colspan=2)\n", - " \n", - "# plotting both Gaussian components\n", - "ax_component1.plot(x, stats.multivariate_normal.pdf(x, mean=means[0], cov=covariances[0][0]))\n", - "ax_component2.plot( stats.multivariate_normal.pdf(x, mean=means[1], cov=covariances[1][1]), x)\n", - "\n", - "\n", - "ax_both.contourf(X_test, Y_test, dist.reshape(X_test.shape), cmap=\"Blues\")\n", - "#ax_both.contour(X_train[:,0], X_train[:,1], dist)\n", - "#ax_both.scatter(X_train[:,0], X_train[:,1],alpha=0.1, marker='.')\n", - "\n", - " \n", - "plt.subplots_adjust(wspace=0, hspace=0)\n", - "ax_both.axis('equal')\n", - "\n", - "for a in [ax_component1, ax_component2]:\n", - " a.get_xaxis().set_visible(False)\n", - " a.get_yaxis().set_visible(False)\n", - "\n", - "plt.gcf().canvas.draw()\n", - "ylabels = ax_both.get_yticklabels()\n", - "ylabels[0] = ylabels[-1] = \"\"\n", - "ax_both.set_yticklabels(ylabels)\n", - "#ax_both.scatter(X_test, Y_test, alpha=0.2)\n", - "xlabels = ax_both.get_xticklabels()\n", - "xlabels[0] = xlabels[-1] = \"\"\n", - "ax_both.set_xticklabels(ylabels)\n", - "fig.suptitle('True Distribution', fontsize=16)" - ] - }, - { - "cell_type": "markdown", - "id": "3eb3dd9d", - "metadata": {}, - "source": [ - "Now, let's plot the KDE evaluated over the same test grid." - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "id": "60d88ad8", - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/var/folders/ts/39plpy691lg3xd9rvzndrmt40000gq/T/ipykernel_20006/3462036152.py:28: UserWarning: set_ticklabels() should only be used with a fixed number of ticks, i.e. after set_ticks() or using a FixedLocator.\n", - " ax_both.set_yticklabels(ylabels)\n", - "/var/folders/ts/39plpy691lg3xd9rvzndrmt40000gq/T/ipykernel_20006/3462036152.py:31: UserWarning: set_ticklabels() should only be used with a fixed number of ticks, i.e. after set_ticks() or using a FixedLocator.\n", - " ax_both.set_xticklabels(ylabels)\n" - ] - }, - { - "data": { - "text/plain": [ - "Text(0.5, 0.98, 'Kernel Density Estimate')" - ] - }, - "execution_count": 25, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "fig = plt.figure()\n", - "fig.set_figheight(6)\n", - "fig.set_figwidth(6)\n", - "\n", - "ax_component1 = plt.subplot2grid(shape=(3, 3), loc=(0, 0), colspan=2)\n", - "ax_component2 = plt.subplot2grid(shape=(3, 3), loc=(1, 2), rowspan=2)\n", - "ax_both = plt.subplot2grid((3, 3), (1, 0), rowspan=2, colspan=2)\n", - " \n", - "# plotting both Gaussian components\n", - "ax_component1.plot(x, stats.multivariate_normal.pdf(x, mean=means[0], cov=covariances[0][0]))\n", - "ax_component2.plot( stats.multivariate_normal.pdf(x, mean=means[1], cov=covariances[1][1]), x)\n", - "\n", - "\n", - "# Fit and plot the model\n", - "kde = kernel_density(X_train, X_plot, 0.5).reshape(X_test.shape)\n", - "ax_both.contourf(X_test, Y_test, kde, cmap=\"Blues\")\n", - "\n", - "plt.subplots_adjust(wspace=0, hspace=0)\n", - "ax_both.axis('equal')\n", - "\n", - "for a in [ax_component1, ax_component2]:\n", - " a.get_xaxis().set_visible(False)\n", - " a.get_yaxis().set_visible(False)\n", - "\n", - "#plt.gcf().canvas.draw()\n", - "ylabels = ax_both.get_yticklabels()\n", - "ylabels[0] = ylabels[-1] = \"\"\n", - "ax_both.set_yticklabels(ylabels)\n", - "xlabels = ax_both.get_xticklabels()\n", - "xlabels[0] = xlabels[-1] = \"\"\n", - "ax_both.set_xticklabels(ylabels)\n", - "fig.suptitle('Kernel Density Estimate', fontsize=16)" - ] - }, - { - "cell_type": "markdown", - "id": "947aa055", - "metadata": {}, - "source": [ - "Plot the two side by side." - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "id": "279b5838", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Text(0.5, 1.0, 'KDE')" - ] - }, - "execution_count": 26, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "fig, ax = plt.subplots(ncols=2)\n", - "ax[0].contourf(X_test, Y_test, dist.reshape(X_test.shape), cmap=\"Blues\")\n", - "ax[1].contourf(X_test, Y_test, kde, cmap=\"Blues\")\n", - "ax[0].set_title(\"True Distribution\")\n", - "ax[1].set_title(\"KDE\")" - ] - }, - { - "cell_type": "markdown", - "id": "518cf82c", - "metadata": {}, - "source": [ - "In practice, we may never have the true distribution for comparison. Instead, the user should vary the bandwidth and compare against some other held out data from their dataset to choose the best bandwidth.\n", - "An example of this approach on real data can be seen on the classical _iris_ dataset.\n", - "We choose the first two features which are `sepal_length` and `sepal_width`, respectively." - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "id": "4e746800", - "metadata": {}, - "outputs": [], - "source": [ - "from sklearn.datasets import load_iris" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "id": "4bc85d34", - "metadata": {}, - "outputs": [], - "source": [ - "iris = load_iris()\n", - "X_iris = iris.data[:, :2]\n", - "y_iris = iris.target" - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "id": "66ec81f8", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Text(0, 0.5, 'Sepal width')" - ] - }, - "execution_count": 29, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjgAAAGzCAYAAAAi6m1wAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/SrBM8AAAACXBIWXMAAA9hAAAPYQGoP6dpAACgMElEQVR4nOzdd1hU19YG8Hc6I2XoKIoNEUVEsIK9gAoWMBpLVIzRWGIvMWrKTWLUm+RLLCRejQY1QRN7SWLsShQBETV2jb0rIkXaMGV9f6AjE2aUOkNZv+fhubl7zrDXGSmLM2fvV0BEBMYYY4yxSkRo7gIYY4wxxkobNziMMcYYq3S4wWGMMcZYpcMNDmOMMcYqHW5wGGOMMVbpcIPDGGOMsUqHGxzGGGOMVTrc4DDGGGOs0uEGhzHGGGOVDjc4jDHGGKt0xOYu4IX//ve/mDNnDqZMmYLFixcbPGbNmjUYOXKk3phMJkNOTk6h59Fqtbh//z6sra0hEAhKUjJjjDHGTISI8OzZM7i6ukIofP31mXLR4CQkJGDFihXw8fF57bE2Nja4fPmy7v8XtUm5f/8+3NzcilwjY4wxxszvzp07qFWr1muPM3uDk5GRgaFDh2LlypX44osvXnu8QCBA9erViz2ftbU1gLwXyMbGptifhzHGGGOmk56eDjc3N93v8dcxe4MzYcIE9OrVC4GBgYVqcDIyMlCnTh1otVo0b94cCxYsQJMmTYwer1QqoVQqdf//2bNnAPKuBHGDwxhjjFUshX3nxqw3Gf/66684efIkFi5cWKjjPT09ERkZiR07diAqKgparRZt27bF3bt3jT5n4cKFUCgUug9+e4oxxhir/AREROaY+M6dO2jZsiX27dunu/emc+fO8PX1NXqT8b+pVCo0btwYQ4YMwbx58wwe8+8rOC8ucaWlpfEVHMYYY6yCSE9Ph0KhKPTvb7O9RZWYmIjHjx+jefPmujGNRoO//voL3333HZRKJUQi0Ss/h0QigZ+fH65evWr0GJlMBplMVmp1M8YYY6z8M1uD061bN5w9e1ZvbOTIkWjUqBE++OCD1zY3QF5DdPbsWYSEhJRVmYwxxhirgMzW4FhbW8Pb21tvzNLSEg4ODrrx8PBw1KxZU3ePzueffw5/f380aNAAqamp+Prrr3Hr1i2MHj3a5PUzxhhjrPwy+yqqV7l9+7beZj4pKSl499138fDhQ9jZ2aFFixY4duwYvLy8zFglY4wxxsobs91kbC5FvUmJMcYYY+ZX1N/fnEXFGGOMsUqHGxzGGGOMVTrc4DBWhSUkJGDY0KGo4eQEFwcH9AsNxaFDh8xdFmOMlRg3OIxVUZGRkWjTpg1itmzBwBwlhuaqcHnvXnTt2hULFiwwd3mMMVYifJMxY1XQ5cuX4eXlhbcs5JivsIXoebYLEWFRxjN8+ywd0dHR6Nixo5krZYyxPHyTMWPstZYtWwY7kQif5WtugLwQu2lW1vCwsMB3ERFmrJAxxkqGGxzGqqDYo0fRVSyBzEAqr0AgQE+xBLFHjpihMsYYKx3c4DBWBYlFIuTC+LvTSiKIxeV6H1DGGHslbnAYq4KCgoOxLzcX6VptgcdURPhNlYtuPXuaoTLGGCsd3OAwVgWNHTsWQpkM49NSkJqvycnSajEjLQVJGg2mTJlixgoZY6xk+Bo0Y1WQq6srtu/cibC+fdEq6RG6SKSQCIBDKhWyAUStW4emTZuau0zGGCs2bnAYq6K6deuGf65dw6pVq3Bg715otVq816EDxo4di7p165q7PMYYKxHeB4cxxhhj5R7vg8MYY4yxKo8bHMYYY4xVOtzgMMYYY6zS4QaHMcYYY5UONziMMcYYq3S4wWGMMcZYpcMNDmOMMcYqHW5wGGOMMVbpcIPDGGOMsUqHGxzGGGOMVTrc4DDGGGOs0uEGhzHGGGOVDjc4jDHGGKt0uMFhjDHGWKXDDQ5jjDHGKh1ucBhjjDFW6XCDwxhjjLFKhxscxsqpmJgYDBo4ENUdHVHd0RED33wTMTEx5i6LMcYqBG5wGCuHli5divbt2+Pkzt8wWJmLwcpcnPrtd7Rv3x5Lly41d3mMMVbuCYiIzF2EKaWnp0OhUCAtLQ02NjbmLoexAk6ePIkWLVpgrKUVPrJRQCAQAACICF+kp2FFZgYSExPRvHlzM1fKGGOmU9Tf33wFh7FyJiIiAjWlMszN19wAgEAgwFwbBWpKZfjuu+/MWCFjjJV/3OAwVs7EHz2KIIkYonzNzQsigQDdJRLEHTlihsoYY6zi4AaHsXJGKBIj9xVvHOcSQSQWm64gxhirgLjBYayc6R4SjD9Vucg2cHtcNhH+VOUiKDjYDJUxxljFwQ0OY+XMhAkTkCUQYFJqCp5ptbrxZ1otJqWmIEsgwIQJE8xYIWOMlX98nZuxcsbd3R2bNm/GwAED0PLJY3QRSwAAh9QqaIRCbNy8Ge7u7maukjHGyjducBgrh/r06YN/rl3DypUrEX3wIABgepcuGDNmDGrVqmXm6hhjrPzjfXAYY4wxVu7xPjiMMcYYq/K4wWGMMcZYpcMNDmOMMcYqHW5wWJWXnJyMefPmwdPdHQ4KW/g1bYqIiAhkZWWZuzTGGGPFxDcZsyrt5s2b6NyhA5IePEAfmQXqiUQ4q1Zjd042mvv5Yd/Bg1AoFOYukzHGqryi/v7mZeKsShs2ZAiQlITDjk5wFb38djinysWgM2cxbdo0REZGmrFCxhhjxcFvUbEq69SpU4iJi8PH1az0mhsA8JZI8Z5cjvVRUUhOTjZThYwxxoqLGxxWZcXFxUEkECDQwsLg48FyOZQqFU6fPm3awhhjjJUYNzisyhKJRCAAKiO3oSmfD4s5uZsxxiocbnBYldWtWzdoibA9O9vg41uzM6GwskLLli1NXBljjLGS4gaHVVnu7u7oFxqK+VkZSFAqdeNEhN+zs7AqKwvjJ06EpaWlGatkjDFWHLxMnFVpqampCOnRA7HHj6OFhRz1BQKcJS0u5eRgwBtvYP2vv0IikZi7TMYYq/J4mThjRWBra4voo0exY8cORP30E+49egTfevUQMXo0unXrBoFAYO4SGWOMFQNfwWGMMcZYucdp4owxxhir8rjBYYwxxlilww0OY4wxxiodbnAYY4WWlZWFiIgI+DVtCgeFLTzd3TFv3jyOs2CMlTvlpsH573//C4FAgKlTp77yuE2bNqFRo0awsLBA06ZNsWvXLtMUyFgVl5aWhk7t22P61Kmoee06xhDB7+Ej/Pezz9CiWTPcvHnT3CUyxphOuWhwEhISsGLFCvj4+LzyuGPHjmHIkCEYNWoUTp06hbCwMISFheHcuXMmqpSxqmvatGn45+w5/O7giBV29phobYNvbO1w2NEJePIkL5mdMcbKCbM3OBkZGRg6dChWrlwJOzu7Vx67ZMkS9OzZE++//z4aN26MefPmoXnz5vjuu+9MVC1jVdPTp0+xPioK78nl8JZI9R5zFYnxcTUrxMTF4dSpU2aqkDHG9Jm9wZkwYQJ69eqFwMDA1x4bGxtb4LgePXogNjbW6HOUSiXS09P1PhhjRXP69GkoVSoEy+UGHw+0sIBYIHjl9yJjjJmSWXcy/vXXX3Hy5EkkJCQU6viHDx/CxcVFb8zFxQUPHz40+pyFCxfis88+K1GdjFV1IpEIwMuE9X9TAdCCk9cZY+WH2a7g3LlzB1OmTMG6detgYWFRZvPMmTMHaWlpuo87d+6U2VyMVVYtW7aEwsoKW7MzDT6+IzsLhLyEdsYYKw/M1uAkJibi8ePHaN68OcRiMcRiMaKjo7F06VKIxWJoNJoCz6levToePXqkN/bo0SNUr17d6DwymQw2NjZ6H4yxorG0tMT4iROxKisLv2dnIX/Cy4lcJb7IzEBYnz5wd3c3Y5WMMfaS2a4nd+vWDWfPntUbGzlyJBo1aoQPPvhAd0k8v4CAABw4cEBvKfm+ffsQEBBQ1uUyVuV9/vnnuHrlCsZt3YpGFhZoKhDiOhESc7Lh36oVIteuNXeJjDGmY7YGx9raGt7e3npjlpaWcHBw0I2Hh4ejZs2aWLhwIQBgypQp6NSpE7755hv06tULv/76K06cOIEffvjB5PUzVtVIJBJs3LwZBw4cwI+rVuH2jRuo5eKC2eHhCA0NhUQiMXeJjDGmU67vCLx9+zaEwpfvorVt2xbr16/HRx99hLlz58LDwwPbt28v0CgxxsqGQCBAYGBgoVY9MsaYOQko/5vpVUBR49YZY4wxZn5F/f1t9n1wGGOMMcZKGzc4jDHGGKt0uMFhzARu3bqF4OBgWEqlkAiFsJLJEBoaivv375u7NMYYq5TK9U3GjFUGJ0+eRLs2baBRq9FHLkdDCzkuqFT4Y+dOeOzZg5N//w1PT09zl8kYY5UKNziMlbGe3bvDWqvFVufqqJcvyuCKSoU3njxGULduuH33rhkrZIyxyoffomKsDO3btw9Jycn40Eah19wAQEOJBO/bKHD33r1C57ExxhgrHG5wGCtDW7duBQAEWxhO4e5pIQflO44xxljp4AaHsTL0Il07F4a3m8p9vg0V7wLMGGOlixscxsrQqFGjIACwJSvL4ONbs7MgRF4OG2OMsdLDDQ5jZcjX1xf169XDf5+l46gyRzdORDiQk43Fz9Lh5e2NevXqmbFKxhirfHgVFWNl7OixY2jSqBEGJz+Bt1iCxhIJzqpycUmthrOjI44cOWLuEhljrNLhKziMlbHq1avjwePHmDNnDlKcHLFXKECGiws+/fRT3HvwALa2tuYukTHGKh0O22SMMcZYucdhm4wxxhir8rjBYYwxxlilww0OY4wxxiodbnBYpfP2229DLpNBIhBAIhDAxtoaX375pbnLKpcSEhIwbOhQ1HBygouDA/qFhuLQoUPmLosxVooyMzOxZMkS+Pj4wN7eHg0bNsT8+fPx9OnTUpsjJycH//vf/+Dn5wd7e3s0aNAAn376KR4/flxqcxQV32TMKpVatWrh3r17aCyWIEQuRw4RtmRl4pFWi+49emD37t3mLrHciIyMxOjRo1FHKkVfiRQiALvVKlzMycH8+fMxd+5cc5fIGCuhlJQUdO3aFWfPnoWfnx9q1aqFR48e4eTJk6hRowaio6NRu3btEs2RkZGB7t27Iz4+Hj4+Pqhbty6ePHmCEydOwN7eHocPH4aHh0eJz6Wov7+5wWGVxtChQ7F+/Xp8bKPAGEsrCAQCAICaCNNTn2Jbdja279iBvn37mrlS87t8+TK8vLzwloUc8xW2ED1/rYgIizKe4dtn6YiOjkbHjh3NXCljrCSGDx+O7du3Y9q0aahVq5ZuPDk5GYsWLYKXlxcOHz5cojkmTJiA1atXY8qUKXqblqampmLx4sWoUaMGTpw4ofuZXFy8iopVWVs2bUJTiQRjraz1vpHEAgEWKuxgIRBg4sSJZqyw/Fi2bBnsRCJ8lq+5AQCBQIBpVtbwsLDAdxERZqyQMVZSjx8/xoYNGxAcHKzX3ACAg4MD+vXrh+joaJw7d67Yc6Snp2PNmjUIDAwssCO7ra0tBgwYgJMnTyI+Pr7YcxQXNzis0lCrVOhlJLXbUihEF5kFHj14YOKqyqfYo0fRVSyBzMBfVAKBAD3FEsTyDsuMVWinTp2CSqWCr6+vwcebNWsGAIiNjS32HGfPnkVWVpbROby8vCCTyUo0R3Fxg8MqFeUr3nF91WNVjVgkMppwDuS9Vi+S0BljFZNIJAIAqNVqg4+/GC/J9/rr5tBqtdBqtbrjTIkbHFZpWMjl2JKdBY2BRuaJRoNoZQ7qN2hghsrKn6DgYOzLzUW6VlvgMRURflPlolvPnmaojDFWWtq0aQNLS0vExcUZfPz48eMQCoXo2rVrsefw8/ODg4OD0begTp48CZVKhaCgoGLPUVzc4LBKY8q0abit0WBOWgqy8zU5yRoN3k1JBgFYu3at+QosR8aOHQuhTIbxaSlIzdfkZGm1mJGWgiSNBlOmTDFjhYyxkrK2tsa4ceOwf/9+nDp1CvnXFF25cgXbtm1D//79UadOnWLPIZPJMGnSJBw+fBjx8fF6c9y4cQObNm1Cz5490bhx4xKdS3HwKipWqXTo0AExR4/CSiBAVwsL5GgJB5U50AKYOmMG/u///s/cJZYbBw4cQFjfvtAolegikUIiAA6pVMgG8HNUFAYNGmTuEhljJZSbm4uBAwdix44dcHNzQ82aNfH48WNcv34dbdu2xa5du6BQKEo0h1qtRnh4OH755Re4urqidu3aSE5Oxj///IPmzZtj7969cHBwKPG58DLx1+AGp/L76aefMGvWLKQ8eQIAqOvujsjISLRr187MlZU/Dx8+xKpVq3Bg715otVq07dABY8eORd26dc1dGmOslGi1Wuzfvx8//vgjbt++DRcXF4SHh6Nv376ldq8dEeHQoUP48ccfcf36dTg6OmLo0KF44403IJVKS2UObnBegxscxhhjrOLhfXAYY4wxVuVxg8MYY4yxSocbHMYYY4xVOtzgsEpnz5496B0SAmd7e7g6O2PkyJE4ffp0qc5x6NAh9AsNhYuDA2o4OWHoW28hISHB6PGpqan48ssv4dWwIRwUCvh4eeHbb7/Fs2fPSrUuxhhjefgmY1apzJ07FwsXLoS3hQV6SKTIIcIOVS4eqtX4OSoKgwcPLvEcCxYswIcffojGFhboKZZAA2CnKhe3cnOxatUqvPPOO3rH379/H507dMDtmzfRW2YBD7EYFzVq7MrJQaNGjXAwOhqOjo4lrosxxiozXkX1GtzgVF67du1Cr169DKaJz0hLwc7cXFy7fh1ubm7FnuPIkSPo2LEjpllZY7q1jW4ODRE+SkvFupxsXLhwAZ6enrrnBHfvjr+jo7HR1h718i3JvKJS4c3Up+jaty82bt5c7JoYY6wq4FVUrMqKWLwYfhZyg2niC2xsIQPwww8/lGyOpUvhYWGh19wAgEggwKcKW9iJRPjf//6nG//nn3+we98+fFDNUq+5AYCGEgmmV7PE1m3bcPfu3RLVxRhjTB83OKzSiI2NRQ+JxOBjlkIhOooliI2JKdkcR46ih1ii19y8IBMI0E0swbF8Kdwv8lmCjaSc97SQQ6PV4sSJEyWqizHGmD5ucFilIRKJXpkYngsqcaKtSCxC7qsSy0GQ5LtS82I+Y8ndLz4XJ3czxljp4gaHVRrde/bEDlWu0TTxv3JzEdSjR4nmCAoOxm+qXKgMzJGu1WJfbi4C86Vwd+7cGWKRCFuysgx+vq3ZWZDLZBwjwRhjpYwbHFZpTJ02DTdVKsxNSy2QJj4uLRWWVlYYOXJkieaYPHkykjQaTE9LQVa+FO5UrRbvpaVAKJNh7NixuvEaNWrgrSFD8HVWJo4qc3TjRIQDOdmIyMrEyFGjYGdnV6K6GGOM6eNVVKxSWb16Nd4dPRo2IhE6isXIIeBwrhJyS0v8/uefpXKlZMOGDRg+bBjkALpIJFARcEiVC5FMhu07d6Jbt256x2dkZKBvr1449NdfaGZhgYYCIS6QFudzchDSsye2bNsGCwuLEtfFGGOVGS8Tfw1ucCq/q1evYvny5TgeGwuxWIweISF455134OTkVGpz3Lx5Ez/88ANi/voLQqEQXYOC8O6776J69eoGj9doNPj999/x09q1eHjvHmrWro23R45Ez549IRTyhVTGGHsdbnBegxscxhhjrOLhfXAYY4wxVuVxg8MYY4yxSocbHMYYY4xVOtzgVFK3bt3CjBkzULdWLTja2qJ9QACioqKg0WjMVhMR4bfffkOPoCA42dmhposLxowZg/Pnzxt9zqNHj/DJJ5/Ao149OChs0crPDytWrIBSqTRh5YyxyuDAgQPo27cvHB0d4eLiguHDhyMxMdHcZbEywjcZV0Lx8fHoERgIoVKJMKkMzkIhjqlVOJKdjX6hodi4ebPJd84lIkyaNAnff/89msvl6CaW4JlWix2qXCQTYdPmzejbt6/ecy5fvowuHTsi/elThEllcBOJcEqtxr6cbLQLCMCfe/fC0tLSpOfBGKuYPvvsM3z66adwc3NDs2bNoNFocOLECSQnJ2P16tUIDw83d4nsNXgV1WtU9gYnNzcX9WrXhmtaOn6ytYNNviXI+3Ky8W5qCuYvXIhZs2aZtK4NGzZg8ODB+K/CFsMsrXTjSiJMTE1BNGlx8/Zt3VJuIoJf06bIunoNG2zt4JwvYuFErhJvpaTg3YkTsHjxYpOeB2Os4jlw4AACAwMRGhqK4OBgXZacVqtFVFQU4uPjcenSJbi7u5u5UvYqvIqqitu6dSvuP3qEr6xt9JobAAiykKO/hRzfL1li8reqIhYvRnt5Nb3mBsgLqPxKoYAmNxerV6/WjR85cgR/nz+PeVZWes0NALSUyjBaLkfkypXIyMgwSf2MsYpr6dKlcHNz02tuAEAoFGLw4MGwsLDA8uXLzVghKwvc4FQycXFxcLewQEMjqdrBFha4ff8+Hjx4YLKaiAhxx4+jh1Rq8HE7oQj+UimOHTumG4uLi4OVWIx2UpnB5/S0kONZVhYuXLhQJjUzxiqP2NhY+Pj46DU3L0ilUnh5eSEmJsYMlbGyxA1OJfMiUdvYO485ZkqvFolencKdC/2aRCIRtERQGz2eU7gZY4UjEomgVhv7aQKo1WpIjPxRyCoubnAqmaCgINxVKpGQm2vw8W05OfBu3BguLi4mq0kgECAoMBDbcpUGG6+7ajXilUoEBQXpxoKCgpCl0WB3TrbBz7k1Kwsujo7w9vYus7oZY5VDjx49kJiYaPCt+czMTJw/f17v5w+rHLjBqWS6d++Opo0bY3pGOq6rVbpxDRFWZDzDnuwszJg1y+Cl2rI0feZMnMvJwefpaVDma3IeaTQYn54KJwcHDB06VDfu4+ODbl264OOMZ/g7X7NGRNiUlYmo7CxMnjYNUiNvezHG2AtTpkxBSkoKfv75Z+Tm+3mSkZGBlStXQiqV4t133zVjhaws8CqqSujGjRsI6tIF12/dQgcLOZwFAsRqNLiXq8SsWbPw3//+1+QNDgB89913mDx5MuzFYnQUS5BBhMO5Stja2uLPvXvRokULveOTkpLQIzAQp86cQRsLOdwEApzSanFNmYMR4eH4MTISon/dgMwYY4asX78eI0aMgEwmg5eXF9RqNc6fPw+pVIrffvsNnTt3NneJ7DV4mfhrVIUGB8i77PrLL79g88aNyEhPRyNvb4wbNw4tW7Y0a12XLl3C8uXLkXj8OGQWFujVpw/efvtt2NnZGTw+NzcXW7ZswfqoKDx98gT1PTwwavRodOrUySxNGmOs4rpx4wZWrFiBmJgYiEQiBAUFYfTo0SZ9y54VHzc4r1FVGhzGGGOsMuF9cBhjjDFW5XGDwxhjjLFKhxscxhhjjFU63OCwcu3cuXPo2LEj5BIJJEIhbKpVw9ChQ5Genm70OfPnz0d1Z2dIhULIRCJ4NGiADRs2GD0+OTkZ8+bNg6e7OxwUtvBr2hQRERHIysoqi1MqtJiYGAwaOBDVHR1R3dERA998k3dbZYyxwiIzWrZsGTVt2pSsra3J2tqa/P39adeuXUaPX716NQHQ+5DJZEWaMy0tjQBQWlpaSctnZWzXrl0kEQrJQiCgodUsaba1DQXJLEgAkK21NT169KjAcwICAggANRZLaIa1DU2wsqbqQhEJAJo0aVKB42/cuEF1atWiaiIRDXo+Ry95NRIJBNSqeXNKTU01xakWsGTJEgJADWQWNMXKmqZYWVMDmQUBoCVLlpilJsYYM6ei/v426yqq3377DSKRCB4eHiAirF27Fl9//TVOnTqFJk2aFDh+zZo1mDJlCi5fvqwbEwgERVrix6uoKgatVgubatXgotZgs6NTgTTxQU+S0NjXF6dOndKNf/bZZ/j000/xsY0CYyytdMvI1USYnvoU27KzERsXhzZt2uie0z4gAHdPncImWzu4il7GPpxT5WJQSgreGD4MkZGRJjjjl06ePIkWLVpgrKUVPrJR6M6DiPBFehpWZGYgMTERzZs3N2ldjDFmThVqFVWfPn0QEhICDw8PNGzYEPPnz4eVlRXi4uKMPkcgEKB69eq6D96/oHL6/vvvkalUYoGtrcE08bFW1jh7+jQePnz48jkREWgqkWCslbXeHjligQALFXawEAgwc+ZM3fipU6cQExeHj6tZ6TU3AOAtkeI9uRzro6KQnJxcRmdpWEREBGpKZZibr7kB8r7259ooUFMqw3fffWfSmhhjrKIpN/fgaDQa/Prrr8jMzERAQIDR4zIyMlCnTh24ubkhNDQU58+ff+XnVSqVSE9P1/tg5d+ff/4JuUDwyjRxzfPjXkhJTkYvC7nB4y2FQnSRWeDiuXO6sbi4OIgEAgRaWBh8TrBcDqVKhdOnTxf7PIoj/uhRBEnEEBnYyFAkEKC7RIK4I0dMWhNjjFU0Zm9wzp49CysrK8hkMowbNw7btm2Dl5eXwWM9PT0RGRmJHTt2ICoqClqtFm3btsXdu3eNfv6FCxdCoVDoPtzc3MrqVFgpKmyauF4WlUCgl3P1b0oiCIQvv+RFIhEIgMrIc5TPh02dWC4UiZH7ijeOc4kg4hR1xhh7JbM3OJ6enjh9+jTi4+Mxfvx4jBgxAhcuXDB4bEBAAMLDw+Hr64tOnTph69atcHJywooVK4x+/jlz5iAtLU33cefOnbI6FVaKRowYASXwyjRxiUCA0NBQ3ZhrrVrYkp0FjYGG5YlGg2hlDtrkuzrYrVs3aImwPdvIHNmZUFhZmTzeontIMP5U5SLbwHlkE+FPVS6CgoNNWhNjjFU0Zm9wpFIpGjRogBYtWmDhwoVo1qwZlixZUqjnSiQS+Pn54erVq0aPkclksLGx0ftg5d+AAQPgYGuLuampBtPEf87KROfAQFhZWeke++Q//8FtjQZz0lL0moNkjQbvpiQDAgEWLVqkG3d3d0e/0FDMz8pAglKpN8fv2VlYlZWF8RMnwtLSsozPVt+ECROQJRBgUmoKnmm1uvFnWi0mpaYgSyDAhAkTTFoTY4xVNMW6zq3VanH16lU8fvwY2nw/gAGgY8eOJSpIq9VCme+XzatoNBqcPXsWISEhJZqTlU9Hjh1D6+bN0evJY7SUSlFXJMaJXCVuajRwr18fv//+u97xo0aNQkxMDNasXo3fsrPR1cICOVrCQWUOtAAili2Dh4eH3nMi16xBSI8e6Hf8OFpYyFFfIMBZ0uJSTg4GvPEGPv/8cxOecR53d3ds2rwZAwcMQMsnj9FFLAEAHFKroBEKsXHzZri7u5u8LsYYq1CKug49NjaW6tWrR0KhkAQCgd6HUCgs0ueaPXs2RUdH040bN+jMmTM0e/ZsEggEtHfvXiIiGj58OM2ePVt3/GeffUZ79uyha9euUWJiIg0ePJgsLCzo/PnzhZ6T98GpWJ49e0YTJ04kFycnUlhaUr26dWnRokWk0WiMPmf//v3UokULsrW2JnuFgnr27EkXLlwwenxubi5t2rSJQvv0obatW9PgQYNo3759pNVqy+KUCu3OnTv0ySefUKf27alT+/b08ccf0507d8xaE2OMmUuZ74Pj6+uLhg0b4rPPPkONGjX0lrECgEKhKPTnGjVqFA4cOIAHDx5AoVDAx8cHH3zwAYKCggAAnTt3Rt26dbFmzRoAwLRp07B161Y8fPgQdnZ2aNGiBb744gv4+fkVek7eB4cxxhireIr6+7vIDY6lpSX+/vtvNGjQoNhFmhM3OIwxxljFU+Yb/bVp0+aVN/UyxhhjjJlboW4yPnPmjO6/J02ahBkzZuDhw4do2rQpJBKJ3rE+Pj6lWyFjjDHGWBEV6gqOr68v/Pz84Ovri/79++PixYt455130KpVK73HinIvDCtbt27dwowZM1C3Vi042tqifUAAoqKioNFoSm2OEydOICAgAHKxGBKhEApLS4wcObJUU7iLkya+Z88e9A4JgbO9PVydnTFy5MhX7kZsijTxW7duITg4GJZSKSRCIaxkMoSGhuL+/fulNkdloVQqsWLFCrRq4QcHOwU83Ovik08+waNHj0ptDpVKhcjISLRu3Rr29vaoW7cuZs+ejXv37hl9zpUrVzBx4kTUrFkTDg4O6Nq1KzZv3owivsvPGDOVwtyJfPPmzUJ/lHdVYRVVXFwcKaysyE4ioZGWVvSBtQ11kMsJAPULDSWVSlXiOTZs2EBigYAsBQIKf57C3VkmIwFATvb2pfL6FidNfM6cOQSAvC0sdGnitWQyEotE9MsvvxQ43hRp4omJiWQhFpMEoDfkcpptbUN9LeQkAqiaTEaXLl0q8RyVRUZGBnVo15aEQgH1bSSgBV1BY5qDrGQiquHiVCqvVU5ODnXv3p0EAgE1bdqUwsLCqFOnTlStWjVycHCg06dPF3jOvn37SC6Xk0KhoMDAQAoNDaWGDRsSABoxYsQrV/UxxkpHma+i+uuvv9C2bdsC29er1WocO3asxPvglLXKfpNxbm4u6tWuDde0dPxkawebfNEE+3Ky8W5qCuYvXIhZs2aVaA6FpSXqQYCNjo6wE74MwzyqzMGw5Cfwb98eR0qQl1ScNPFdu3ahV69eBtPEZ6SlYGduLq5dv64X12GKNHFnR0cgJQVbHZ1RL9/3zRWVCm88eQxrV1fcfkXcSFUydepUrFr+HfYO1aBtvlSVhxlAtygRxE6eOH3mXIHVm0Xx8ccf48svv8SECRPQuHFj3XhGRgaWLl0KkUiEK1euQPT8ay49PR1ubm5wc3PDuHHj9OJB4uPjsXr1avzwww8YPXp0sWtijL1emd9k3KVLFzx9+rTAeFpaGrp06VLUT8dK2datW3H/0SN8ZW2j19wAQJCFHP0t5Ph+yZISvVW1YMEC5KjV+MrWTq+5AYD2MguEW1ohPiYGGRkZxZ6jOGniEYsXw89CbjBNfIGNLWQAfvjhB924KdLE9+3bh6TkZHxoo9BrbgCgoUSC920UuHvvHhISEoo9R2WRkZGByB9XYlpr/eYGAKpbAUu7a3Dm3IUSNc65ublYvnw5OnTooNfcAICVlRWGDBmC69evY8+ePbrxqKgoZGRkYPjw4frZZ8hbdNGsWTMsXbq02DUxxspGkRscIjL411NycrLJt7RnBcXFxcHdwgIN/3Xz9wvBFha4ff8+Hjx4UOw5Dhw4AAehEL5G55BDRYTDhw8Xe47ipInHxsaih5GaLIVCdBRLEBsToxszRZr41q1b8z6XkZTznhZyUL7jqrKLFy/iWUYWwhoZfrxrPcBGLkJsbGyx57h+/TqePHkCX19fg4/XrVsX9vb2OHbsmG4sLi4O9erVg52dncHn+Pr64uzZs6V6zxZjrOQKHdXwxhtvAAAEAgHefvttyGQvf/FoNBqcOXMGbdu2Lf0KWZGIRCIoiYw2ojnP35EsSUK2SCSCmggEwNAbBS8SvfN/jRRnjhdp4oZaFkNp4iKRCEqN1sDRL58jync1KH+auNjAa1UaaeIvnpsLgqH2P/f5a/Xv1YhV0Yt/G6WRi4tqLaDWUIm/doG8t9QNISKo1Wq9OUQikdHjgbwblvN/bsZY+VDoKzgKhQIKhQJEBGtra93/VygUqF69OsaMGYOoqKiyrJUVQlBQEO4qlUjIF1CZ37acHHg3bgwXF5dizzFo0CCkEeGwMsfg41uyMyETidCpU6diz1GcNPHuPXtihyrXaJr4X7m5COrRQzdmijTxUaNGQQBgi5G/7rdmZ0EIYOTIkcWeo7Lw9vaGi5MDos4Yfnz7JSArV6vb6bw43N3dUadOHcTHxxt8/MKFC0hPT9ebIygoCLdu3TK44o2IkJCQgPbt25eooWeMlb4i32T82WefYebMmRX27ajKfpOxVquFr7c3nl2/jp8Utqj/PKhRQ4RVmRmYl56G1atX4+233y7RHHY2NrDIzsY6Byc0fn71QUuEqKxMzE1LRf/+/bF58+YSnYujnR20aemIcnBEs+dXaogIm7OzMD01BYFBQdi7d6/u+Pj4eLRt2xZDLOT4VGEL+fOrMskaDcampeKyVIJ/rl+Hg4OD7jlvhIXh0K5dWG1ji1bPf0EREf7IycaktFTMmDULCxcuLNF5NKhfH/du3sQaewe0l1no5jiozMHop8nw9PbG2bNnSzRHZbFgwQJ8/PFHWN2XMNwHeHFhLfE+0OtXMZq26oB9Bw6WaI6IiAhMnjwZb731Fjp06ADh83vV7t27h++//x4NGjRAbGys7gqoUqlEw4YNodVqMWHCBNjb2wPIu3L9+++/Y9euXdixYwf69u1boroYY69W5N/fZbCSq1yrCsvEr1+/Tu516pAAoI4Wchogr0Y1pTICQLNmzSqVEMmEhASSS6UEgPyl0rw5RCICQE2aNCmVZbMXLlwgKwsLAkAtn89R9/kc7vXrk1KpLPCcyMhIEgmFZCeRUKhcTj0s5CQTCsnW2pqOHj1a4PiUlBQKaN2aAFALCzm9Ka9GjZ7POeCNNyg3N7fE5/HgwQOyVyjylq+LJXlziMUEgJwdHSklJaXEc1QWarWaRoSHEwDydBJTeDNQhzpCAkB+zZrS48ePSzyHVqul8ePHEwBycXEhf39/atSoEQGgRo0a0d27dws859y5c+Tq6kpCoZC8vb3J39+f7OzsCAAtXLiwxDUxxl6vTJaJ+/n5FXpZ5smTJwt1nLlU9is4L2RmZuKXX37B5o0bkZGejkbe3hg3blyJ3m75t6dPn+KDDz7Ajm3boFIq4ejigpnvv4+xY8eW2hwZGRmYM2cONm3YgJysLNg7OWHylCmYPHmy7i/vf7t69SqWL1+O47GxEIvF6BESgnfeeQdOTk4Gj1epVNixYweifvoJSY8eoXa9ehg1ejS6detWouXI+eXm5uLTTz/FT2vWICM9Hda2thj97rv48MMPS3RPSWVERIiOjsaPq1bh+rV/YO/giCFvDUX//v1L9W2gY8eOYeXKlbh8+TIUCgUGDx6MgQMHQi43fEN4eno6fv75Z2zbtg3Z2dnw9fXF2LFjefd2xkykTMI2P/vsM91/5+TkYNmyZfDy8kJAQACAvFUG58+fx3vvvVfiy/llrao0OIwxxlhlUtTf34X60/E///mP7r9Hjx6NyZMnY968eQWOuXPnThHLZYwxxhgrfUW+yVihUODEiRPw8PDQG//nn3/QsmVLpKWllWqBpY2v4DDGGGMVT5nvZCyXyxGTb7O0F2JiYmBhZMM0xhhjjDFTKnKDM3XqVIwfPx6TJ09GVFQUoqKiMGnSJEyYMAHTpk0rixpZFfbo0SN88skn8KhXDw4KW7Ty88OKFSugVCqNPqeoaeKMFcaePXvg4+MDqVQKsVgMB3t7zJgxA1qt8c0ly6P4+Hi0bt0aMpkMYrEYCoUCo0ePRk6O4X2tGKuoivwWFQBs3LgRS5YswcWLFwEAjRs3xpQpUzBw4MBSL7C08VtUFcfly5fRpWNHpD99ijCpDG4iEU6p1diXk412AQH4c+/eAvsxzZ07FwsXLoS3hQV6SKTIIcIOVS4eqtX4OSoKgwcPNtPZsIrsq6++wuzZs2FZrRr8AwJgaWmJc+fO4tq162jg7o6Lly5ViNVw69atw4gRIyCRSODv7w9bW1tcuXIFFy5cgLOzM65duwYrKytzl8mYQWWyiqoy4QanYiAi+DVtiqyr17DB1q5AmvhbKSl4d+IELF68WDdenDRxxl7n7t27qFOnDhp5emL8e+8VSBOPjIxEeHg41q5da8YqXy8nJwc2NjaoUaMGpk6dqvfHwYULFxAREYFOnTrh4MGSbaTIWFkp83twGDOFI0eO4O/z5zHPyspgmvhouRyRK1fqJZYXNU2cscKYOXMmiAjhI0YYTBP38fHB5k2bzFRd4X322WdQqVQYPnx4gSufXl5e6NChA44cOcKhoazSKFSDY29vjydPngAA7OzsYG9vb/SDsdIQFxcHK7H4lWniz7KycOHCBd1YUdPEGSuMhIQE1Kld22iaePPmzZGVna37GVleHTp0CLa2tqhdu7bBx319faFWq0uU1s5YeVKoN40XLVoEa2tr3X+X1u6ujBlT2DTxf6c+FyVNnLHCEAqFyH3FTe0v0sT/fXWnvHmRik5EBn+Gv0hM59BQVlkUqsEZMWKE7r9LEtLIWGEFBQVh5syZ2J2TjT7yagUe35qVBRdHR3h7e+vGuvfsiR3bt2MqEUT/+gH+Ik18fr40ccYKo3v37li2bBnu378PV1dXvceICHFxsVAobMr9PX1vvvkmjh07hkuXLqFx48YFHo+Li4NMJoO/v78ZqmOs9BX5Hpzw8HCsXr0a165dK4t6GAMA+Pj4oFuXLvg44xn+zs3VjRMRNmVlIio7C5OnTdP7q3nqtGm4qVJhbloqsvPdO5+s0WBcWiosrawwcuRIk54Hq/gWLlwIiUSCH374AU+fPtWNazQa7Ny5E9euXceECRPNWGHhTJ48GZaWllizZg3u37+vG9dqtTh48CASExPxxhtvVIjVYIwVRpFXUY0ePRp//fUXrl69ipo1a6JTp07o3LkzOnXqVGB34/KIV1FVHElJSegRGIhTZ86gjYUcbgIBTmm1uKbMwYjwcPwYGVngLafVq1fj3dGjYSMSoaNYjBwCDucqIbe0xO9//ol27dqZ6WxYRbZjxw4MGDAAGo0GTby8YGVtjfPnz+HZswz06NEDu3fvNneJhRIfH49OnTpBqVTC09MTdnZ2uHz5MlJSUuDr64vExESjIbaMmZvJlonfu3cPf/31F6KjoxEdHY0rV66gRo0auHv3bnE+nclwg1Ox5ObmYsuWLVgfFYWnT56gvocHRo0ejU6dOhm9F6yoaeKMFcbdu3cxffp0HDhwABqNGm5utfGf//wHAwYMMHdpRfL06VPMnDkTv//+O5RKJZydnfHBBx9g9OjR5i6NsVcyWYOTlZWFo0eP4tChQzh8+DBOnjwJLy8vnDp1qjifzmS4wWGMMcYqnjLfB2fu3Llo27YtHBwcMHv2bOTk5GD27Nl4+PBhuW9uGGOMMVY1FPkKjlAohJOTE6ZNm4Y33ngDDRs2LKvaygRfwWGMMcYqnqL+/i7y7fKnTp1CdHQ0Dh8+jG+++QZSqVR3o3Hnzp0rXMPDGGOMscqnyG9RNWvWDJMnT8bWrVuRlJSEXbt2QSqVYsKECQb3VmAFXb16FZMnT0ZtV1c42tqiS8eO2LhxY6mmEt+6dQszZsxA3Vq14Ghri/YBAYiKioJGozF4vFarxYwZM+BoawupUAiZSAQfHx/s2bOn1GoqjuKkibPy5fTp0xg5ciRcqzvB2dEevXuFVJhVRyWRm5uL8ePHw1ahgFgshkwqRcuWLXH06FGjz7lx4wamTZsGNzc32Nvbo0OHDli/fr3R71tTICJs374dgYGBcHBwgKurK8aNG6cLWzbkwYMH+Oijj1C/fn3Y29ujZcuWWLlyJXLzbfnw7zl27dqFkOCecHKwQ80azhj1zjs4c+ZMqZ7LgQMH0LdvXzg6OsLFxQXDhw9HYmJiqc7ByhEqIq1WS4mJifTNN99Qnz59yM7OjkQiEfn5+dHUqVOL+ulMLi0tjQBQWlqaWeY/dOgQWcrl5CCR0LuWVvSBtQ0FyOUEgIYOGUIajabEc8TFxZHCyorsJBIa+XyODs/n6BcaSiqVSu94lUpFDdzdCQC1lEpplrUNjbG0IjuhkIQAffnllyWuqTguXbpENZydyVIspqHVLGm2tQ31kFcjoUBAHdq2pYyMDLPUxQrvl19+IbFYRHXsxDS7HeizzqDmNUUEgObMmWPu8spMdnY2udaoQQCokacnhYaGUpcuXUgul5NQKKSVK1cWeE5MTAxZW1uTtbU1de3alUJDQ6lRo0YEgAYMGEBqtdrk56HVamnMmDEEgBo0aEB9+/aloKAgsrOzI5lMRrt27SrwnPPnz5OzszPJ5XLq2LEjhYWFUbNmzUggEFDnzp0pKyurwBwzZ87M+/lTS0SfdwZ90A7kZismiURMmzdvLpVz+fTTTwkAubm5Ue/evSk4OJicnJxIKBTS2rVrS2UOVraK+vu7yPfg2NnZISMjA82aNdO9NdWhQwfY2tqWYttVdsx5D05mZiZq16wJr9xcRCrsUC3ffhM7s7MwIeUpvl+2DOPHjy/2HLm5uahXuzZc09Lxk60dbPLNsS8nG++mpmD+woWYNWuWbnzEiBH4+aefsMTWHm9Ue7lrcLZWi9EpyTiqVOL2vXsFdnEtS1SMNHFWvty5cwcN3N0xsLEKq0MB8fMvRSLg21hg5j7gjz/+QEhIiHkLLQMhIXlXqcaPH49mzZrpxrOzs7F06RLcvn0HKSkpsLKyApCX9F2nTh3Y2tpiwoQJsLCw0D3n9OnTWLFiBf7v//4P06ZNM+l5REVFYfjw4QgPD9fbQ0qlUmHlypW4evUqbt++rcshJCI0adIEz549w5QpU/R+xv7zzz+IiIjApEmT8PXXX+vGd+zYgbCwMCzpCUxu83JulQYYsV2ArVfEuH7jZol+/hw4cACBgYEIDQ1FcHCwbosJrVaLqKgoxMfH49KlS3B3dy/2HKzslfkqqqioKCQnJ+PEiRP45ptv0KdPnwrT3Jjb+vXrkZKWhv+zVug1NwDQV14NIfJqiFi0CEXsOfVs3boV9x89wlfWNnrNDQAEWcjR30KO75cs0bvkvWXDBgTJLPSaGwCQC4X42tYOBGDGjBnFrqk4ipMmzsqXFStWQCbS4n+9XjY3ACAQADPaAq1qiRCxdLHZ6isrubm52L9/PwICAvSaGwCQy+UYPjwcarUaH374oW5806ZNePz4MYYNG6bX3AB5IZitWrXC0qVLS/Vt7MJYsmQJvL29C2yQKZFIMGzYMCiVSqxdu1Y3fvDgQVy8eBGDBg0q8AvIw8MDnTp1wsqVK/USy5cuXoR2dUR6zQ0ASETA/3oRRNBg1apVJTqPpUuXws3NTa+5AfIWzQwePBgWFhZYvnx5ieZg5U+RG5xevXrx6qNiiouLQ1O5HLWMbIUeLLPAxX/+QXp6eonmcLewQEMjqdrBFha4ff8+Hjx4ACBv069MpRLBcrnB411FYvhIJIiPjy92TcVRnDRxVr7ExR5DUD0NrIxkUL7hqUHsscqXXH3mzBmoVCr4+voafNzV1RVOTo6Ijo7WjcXFxaFWrVpwcXEx+BxfX1/cvHkTSUlJZVGyQRqNBidOnCjQpL1gY2ODBg0a6KWPx8XFwcrKyuiu9n5+fkhLS8Ply5dfPic+HmENDd9jpLAAAutpEXvsWAnOBIiNjYWPj4/BzUGlUim8vLwQExNTojlY+cN7cpuQSCRC7isuziifJ2SXJPFaJBJBSWT0KlAO6adwv/hf5SuuGuVSyWoqjvxp4gZrMpAmzsoXkUgEpbF/QAA5akAsrnzp7i/y0V6kc/8bEUGtUut97b5I+jbmxWOm/HoXCAQQCoWvrevf56HVao1eaTJ0HiKR8DVfJ4ISn3dhXl+JkT8KWcXFDY4JBQUF4VJONi6oDK8k2KrMgX+rVrr35Ys7x12lEglGVitsy8mBd+PGur8UbWxsYGdtjc3ZWQaboisqFS6oVejevXuxayqOoKAgZGk02J2TbfBxQ2nirHwJ6t4D+24I8cjAu4gaLbD+vBiBQZUv3d3b2xtyuQXi4+IMPn7t2jWkpKYiLCxMNxYUFISHDx/ixo0bBp9z/Phx+Pr66u51MQWhUIhu3bohISHB4M+GpKQkXLt2DYGBgbqxoKAgZGVlGV39FB8fD1dXV70Vt0FB3bH+ghhaA39j3X8GHLwJBAYFlehcevTogcTERIOr0TIzM3H+/HkElXAOVv5wg2NCYWFhcK9TBxPT03En318TKiJ8+ywdMdnZmPnBByWao3v37mjauDGmZ6TjulqlG9cQYUXGM+zJzsKMWbP0LtWOnzQJJ3Jz8X/P0qHK94PsnlqNcSnJkIpEWLhwYYnqKqripImz8uWdd96BpZUVBm4RIinz5Xi2CnjvD+DaUw2mTZ9uvgLLiFAoxFtvDcXfZ85g3759elczHj16hNWRkZDLLTB79mzdeEhICBo2bIg1a9bg8ePHunGNRoPdu3fj7NmzmDlzptH8tbIyY8YMXL9+HVu3btW7ApKSkoJVq1ahevXqGDx4sG68RYsW6NixIzZs2IDbt2/rxrVaLWJiYhATE4OpU6fqXZGZPmMmLj7WYNKuvKt6LzzOBAZuEUJho8CIESNKdB5TpkxBSkoKfv75Z72l6hkZGVi5ciWkUinefffdEs3ByqEyWctVjpl7mfjFixfJzdWVRAIBdbaQU395NaoulRIA+vzzz0tljuvXr5N7nTokAKijhZwGyKtRTamMANCsWbNIq9UWeE7Pnj0JADkIhfSGvBp1kclICJBEKKTt27eXSl1F9fjxY/Lz8SEA1Ob5ebjLLAgAjQgPN8uyWVY0R48eJVuFNckkQgprBHqrKcjeUkQikZAiIyPNXV6Z0Wg01Lp1awJAtrYK8vf31y35lkqlFB0dXeA5//zzD9WpU4eEQiF5eXmRv78/OTg4EAD68MMPDX7fmsK3335LAEihUFCbNm3Ix8eHRCIROTs70+nTpwsc//DhQ2ratCkBIE9PT/L396fq1asTAHrnnXcMboXxww8/kFAoJAdLEb3VFBTqCZKKhWRvp6C4uLhSOY9169aRWCwmS0tLatWqFfn5+ZFUKiUrKys6dOhQqczBylaZLBPfuXNnoRumvn37FrXHMqnyENXw7NkzREVFYduWLcjOzIS3ry/Gjh1r9KbE4sjMzMQvv/yCzRs3IiM9HY28vTFu3Di0bNnS6HO2bNmCTz/9FHdv3YJILEaXbt3wzTffoHbt2qVWV1EVJ02clS9PnjxBZGQkdv/5B9QqFVr7t8W4cePQoEEDc5dW5n766ScsmD8fDx8+hEQqQUhIL3z99ddwdnY2eHxGRgbWr1+PzZs3IyMjA02aNMH48ePRvHlzE1eu78KFC1i+fDkSExMhl8vRp08fjBgxwugKWqVSiU2bNuGXX35BSkoKGjRogNGjR6NDhw5Gv2+vXLmCFStW4HjcMUilMgT36o2RI0fCwcGh1M7jxo0bWLFiBWJiYiASiRAUFITRo0cbvbmblS9lkiYuFBbunSyBQGDWHTcLozw0OIwxxhgrmjLJojL13guMMcYYYyXBNxkzxhhjrNIp1uYCmZmZiI6Oxu3btwuEp02ePLlUCmOMMcYYK64iX8E5deoUGjRogCFDhmDixIn44osvMHXqVMydO5dzgcqRoqaJF8e9e/cwZ84c1K9dGw4KW/i3bInIyEioVCqDx2u1Wnz88cdwdnDQJZY3btwYO3bsKLWaGCsvNBoNoqKi0L59e9jb26N27dqYMWMGbt68ada6du7ciRo1akAsFkMkEkEqkaBjx46lGnuyb98+uLm56eaQSCQICAjA06dPS20Oxl6rqMu0OnXqRO+++y5pNBqysrKia9eu0e3bt6ljx460ZcuWon46kzP3MnFTKGqaeHGcPn2aHO3syEYspvDnSd9d5dVIAFCPwEDKycnRO16j0eiWjjaTSOh9axsaZ2lFTkIhCQCaO3duiWtirLxQqVQUFhZGAMjLy0uXJm5lZUU2NjYUGxtrlrrmzZtHQqGQLCxk1LlzZwoLCyMvr8YEgGQyGSUnJ5d4joiICBIKhSSVSnVp4i++9yUSCd29e7cUzoRVRWWeJm5ra4v4+Hh4enrC1tYWsbGxaNy4MeLj4zFixAhcunSp1Juw0lTZV1EVJ028qDQaDRo1aACLhw/xi60d7IQvt9s/qszBiNQUvD9nDubNm6cbnzJlCpYuXYr/KmwxzPLlTs1KIkxIScbenBycu3BBb4dTxiqqr776CnPnzsXYsWMLpIl/9913yMzMxM2bN026UWVGRgZsFQrUrFUTU6dOg6Wlpe6xCxcuICIiArVr1za6m3JhaDQayGQyODk5YcaMGQXSxBcvXgwHBwc8fPiwROfCqqYyTxOXSCS6ZePOzs663SoVCgXu3LlT1E/HSllx0sSLavfu3bh68yYWWtnoNTcA0F5mgaEWcqxYtkzv/qy1kZFoK5XpNTcAIBMI8LWtHUQwfWI5Y2VBo9EgIiIC/v7+BtPEhw4digcPHmDbtm0mrWvEiBHQaLUYPjxcr7kBAC8vL3To0AG3b99GWlpasecYP348NBoNhg4dajBNvGvXrkhKStLb5ZixslLkBsfPzw8JCQkAgE6dOuGTTz7BunXrMHXqVM4FKgeKmiZe3Dmqy2TwNTqHHElPn+LatWsA8u69Sc/IMJpYbicUwV8qw6lTp4pdE2PlxcOHD3H37l2jKdyurq6oUaMGjpUwIbuoYmNjYWurMLpxp6+vL7RabYnuiTt48CAsLCxemSau1Wqxbt26Ys/BWGEVucFZsGABatSoAQCYP38+7OzsMH78eCQlJeGHH34o9QJZ0RQ1Tby4c6i0BGPvbSqNzJH7qsRykMkTyxkrCy++jl+ZJv6vFG5TyEsG1xj92fCiXrmRP0QKO0dh0sRlMlmx52CssIrc4LRs2RJdunQBkPcW1e7du5Geno7ExESjf7Ew0ylqmnhx50hW5eKwMsfg41tzslDPzQ3169cHkPdDz9nJCZuzDCeW31WrcTw3F506dSp2TYyVFy4uLvDy8sLx48cNPn7t2jUkJSWZPL06LCwMGRkZRu+TjIuLg0gkRGhoaLHnGD58OHJzc1+ZJi4UCjFmzJhiz8FYYRV7o7/Hjx/jyJEjOHLkCJKSkkqzJlYCxUkTL6q2bdvCv1UrzM54hov5loRrifBTZga2ZmVh2vvv612Ref+DD3BRrcLn6Wm6KzwA8EijwZiUZIgFAnzzzTfFromx8kIgEOD999/H6dOnDaaJ//TTT/Dy8kL37t1NWteSJUsgFouwZs0a3L9/Xzeu1Wpx8OBBJCYmws+veYlufP74448hkUiwbt06g2niR48eRcOGDWFlZfWKz8JYKSnqMq309HQaNmwYicViEggEJBAISCwW09ChQyk1NbWon87kqsIy8eKkiRfV3bt3ycvTkwBQ2+dz1JHlzTF+/HiDcwwYMCAvXVkgoH7yahQosyARQGKBgH7++ecS18RYeaHVamnWrFkEgBwdHcnf35+8vLxIIBBQ/fr16fr162apa8eOHSQSCZ8nfTckf39/srez09WpVqtLPMehQ4dIJBIRAGrQoAH5+/uTo6MjASAbGxtSKpWlcCasKirq7+8iNzgDBw4kDw8P2r17N6WlpVFaWhrt3r2bPD09adCgQUUu2NSqQoNDRJSRkUErV66kHkFB1K5NGxo1ahQlJCSU6hxZWVm0Zs0aCu7Rg9q1aUNvv/02xcTEvPI5f/zxB/n6+pKttTU52NpSaGio2X7YM1bWEhISaNSoURQQEEDdu3enlStXUkZGhllrunv3LrVv355kUilJJGKysbam2bNnl+ocjx8/pq5du5JMJiOJREJWVlY0efLkUmmgWNVV5vvgWFpaYs+ePWjfvr3e+JEjR9CzZ09kZmaW9KJSmars++AwxhhjlVGZ74Pj4OAAhUJRYFyhUMDOzq6on44xxhhjrNQVucH56KOPMH36dL2dKB8+fIj3338fH3/8cakWxxhjjDFWHEV+i8rPzw9Xr16FUqnUbRh1+/ZtyGSyAps7nTx5svQqLSX8FhVjjDFW8ZT5W1RhYWGYOXMmPvzwQwwfPhzDhw/Hhx9+iJkzZyI0NFTvoypQq9VYs2YN2rZuDUdbW9Rzc8OsWbNeGVtx9epVTJ48GbVdXeFoa4suHTti48aNRjfHKq9OnDiBgIAAyMViSIRCKCwtMXLkSGRlZRk8nojw22+/oUdQEJzs7FDTxQVjxozB+fPnjc7x6NEjfPLJJ/CoVw8OClu08vPDihUroFQqy+q0ykRqaiq+/PJLeDXygIOdAj7eXvj222/x7NmzUpvj/v37CA0NhVU1GaRiASzlUvTs2RO3bt0y+pyEhAQMGzoUNVwc4eJkj35hoTh06FCp1QQAGzZsgIeHByQSCSQSMVxcXPDFF18YPV6pVGLFihVo0aIF7O3t4e7ujk8++QSPHj0y+pydO3eicePGkEokkIjFcHJ0xIcffljhvqc2bNgAZ2fnl0nfUimCgoKQnZ1t8HitVouNGzeiS6eOcLS3Re1aNTB58mRcvXrV6Bzx8fFo3bo1ZDIpxGIxFDY2GD16NHJyDO9rRUTYvn07AgMD4eDgAFdXV4wbNw4XL14slXMurqSkJHz22Wdo0KAB7O3t4evri++//97oawUABw4cQN++feHo6AgXFxcMHz4ciYmJJqy6dMTHx2Pw4MFwdnaGk5MT3njjDURHRxs9PjMzE0uWLIGPjw/s7e3RsGFDzJ8/v/Knu5fZ7c6FsGzZMmratClZW1uTtbU1+fv7065du175nI0bN5KnpyfJZDLy9vamP/74o0hzluYqKqVSSb2CgwkAdZFXo9nWNjSimiUpxBKyVygoMTGxwHMOHTpElnI5OUgk9O7zpO+A50nfQ4cMIY1GU+K6TGHDhg0kFgjIUiDQpYl3lslIAJCTvX2B11er1dKECRMIADWXy3Vp4jWkUpJKJLRjx44Cc1y6dIlqODuTpVhMQ5/P0UNejYQCAXVo29bsq1EK6969e+ThXo9kEiEN9wEt7AYa4i0giUhATZs0pqSkpBLPcenSJapmISWxEDSoSd4cw3xAEiHIQio2+LX4448/kkAgIHcHMX3YAfSfTqCm1cUEgObPn1/imoiIJk2alLc1gK0t9ezZk/r06UO1atUkABQQEFDg+IyMDGrfvj0JhUJq1qwZhYWFUYcOHUgul1P16tXp0qVLBZ7z0UcfkUAgIBsbG+revTv17duX6tSpQwCoadOmFeZ76v333yehUEhyuZy6du1KoaGh1LBhQwJA1apVo6ysLL3jNRoNDX1rCAGgTvWENL8raJo/yMlKRJbV5HTo0KECc0RFRZFIJDKYJu7s7EzPnj3TO16r1dKYMWN0S7779u1LQUFBZGdnRzKZ7LU/r8vK1atXqWbNmmRhYUHt2rWjfv36kZ+fHwmFQmrTpg2lp6cXeM6nn35KAMjNzY169+5NwcHB5OTkREKhkNauXWuGsyie5cuXk0AgoOrVq1NISAj17t2batbM+5766quvChz/9OlT8vX1JZFIRC1btqSwsDAKCAggmUxGdevWpVu3bpnhLIqnzFdRAXl/jW7evBnXrl3D+++/D3t7e5w8eRIuLi6oWbNmoT/Pb7/9BpFIBA8PDxAR1q5di6+//hqnTp1CkyZNChx/7NgxdOzYEQsXLkTv3r2xfv16fPnllzh58mShc7BK8y2qzz//HPM/+wyrbe3RycJCN56q1WJYagpSHB1w9cYN3ZbsmZmZqF2zJrxycxGpsEO1fGGYO7OzMCHlKb5ftgzjx48vUV1lLTc3FwpLS9SDABsdHQukiQ9LfgL/9u1x5MgR3fiGDRswePBgg2niE1NTEE1a3Lx9G05OTgDy/mr0a9oUWVevYYOtHZzzbRp4IleJt1JS8O7ECVi8eHHZn3AJBffsjrNxh3A4XI0G9i/HLyQBnX8SoXPPMGzctLlEc9R2q4XM5Hs4MhLwcno5fu0p0H41oLWwx6OkZN345cuX4eXlhXf9tPg+BBA9/1IkAj6PBj6NBqKjo9GxY8di1xQfH4+AgAC0btUKI95+W7fxIxFh//792Lx5Mz799FP85z//0T1n6tSpWLFiBSZPngx3d3fdeFpaGpYsWQJ7e3v8/fffuo0qL168iCZNmqCZjw9Gv/suJPny0f766y+sW7cOkydPxpIlS4p9Hqbw8OFD1KxZE/Xr18ekSZNgke/nyenTp7F8+XI0adIEZ8+e1Y3/73//w4QJ7+GXN4BB+X78ZeYCYRuFOPnUGrfv3NMFa+bk5EBhY4PqNWpg6tSpBtPEO3XqhIMHD+rGo6KiMHz4cISHh6Ndu3a6cZVKhZUrV+Lq1au4ffs27O3zfWGXMSJC69atcffuXUydOlVvccvNmzexZMkSDBs2DCtWrNCNHzhwAIGBgQgNDUVwcLDu60er1SIqKgrx8fG4dOmS3tdceXT+/Hk0bdoUnTp1wqBBg3TB10SEHTt24M8//8SxY8cQEBCge87w4cOxfft2TJs2DbVq1dKNJycnY9GiRfDy8sLhw4dNfSrFUuZvUZ05cwYNGzbEl19+if/7v/9DamoqgLwU6zlz5hTpc/Xp0wchISHw8PDQXTKzsrJCXFycweOXLFmCnj174v3330fjxo0xb948NG/eHN99911RT6PEVCoV/vfddxhsIddrbgDAVijEQitr3Lp7F7///rtufP369UhJS8P/WSv0mhsA6CuvhhB5NUQsWmQ0K6a8WLBgAXLUanxla2cwTTzc0grxMTHIyMjQjUcsXoz28moG08S/Uiigyc3F6tWrdeNHjhzB3+fPY56VlV5zAwAtpTKMlssRuXKl3hzl0T///IPde/ZhYRf95gbIa0Q+7ajB1m3bcPfu3WLPceLECdy9ew/zuug3NwDgbg98FQg8fvIUe/bs0Y0vW7YMDtWEWNLzZXMDAAIB8EknoLGzGN9FRBS7JiAvHV4ikeCtoUP1drUWCAQICgpC7dpu+D7f925GRgZ+/PFHdO3atcAvGoVCgTfffBNnz57Va5ynT58OoVCI4eHhes0NAHTs2BENG3pgzZo1JToPU3jrrbeg1WoRHh6u19wAeSGYrVq1wsWLF5H7PIKFiBCxZBEGeAn0mhsAsJQCq3prkZKahl9++UU3/tlnnyFXpcLw4cONpokfOXJE7y3mJUuWwNvbW6+5AQCJRIJhw4ZBqVRi7dq1pfESFFpCQgJOnDiBAQMGFFi5W7duXQQGBuKnn37S/W4CgKVLl8LNzU2vuQHyYmQGDx4MCwsLLF++3FSnUGzff/89FAoFBg4cqGtugLzvqb59+8LFxQUR+b5vHz9+jA0bNiA4OFivuQHyVkT369cP0dHROHfunMnOwZSK3OBMnz4db7/9Nv755x+9b8SQkBD89ddfxS5Eo9Hg119/RWZmpl73mV9sbCwCAwP1xnr06IHY2Fijn1epVCI9PV3vozTcvn0bD5OS0NPCcDBdU6kUtWQWerXFxcWhqVyOWkZC9oJlFrj4zz+lVmNZOXDgAByEwlemiauIdH8VEBHijh9HDyNbwOeliUv10pXj4uJgJRajndRwKF9PCzmeZWXhwoULJTuZMhYfHw8A6NfY8OP9GgEajRYnTpwo9hxbt24FPf9cBud4Pve2bdt0Y3HHjiLEXQ2ZgS9FgQDo11CN2JgjBR8sgosXL6BJkyYFfmG/0KJFSyTnuwfg4sWLyMjIgK+vr8HjGzVqhGrVqul9T/39999o6OFhdOv/5s1bID09vdzfi/P333+jevXqRjPi/Pz8oNFodN8j6enpuHj5H4R5Gv5jqI4t0KKmWO+1OnTo0GvTxNVqte45Go0GJ06cMJoxaGNjgwYNGrzy529ZiIuLg0QiMXiVH8h7rXJycvTysGJjY+Hj42MwokYqlcLLywsxMTFlVnNpOXbsGLy9vQ0GEwuFQjRr1kzv5+ipU6egUqmMfk+9+Lc19b+hqRS5wUlISMDYsWMLjNesWVNv6XhhnT17FlZWVpDJZBg3bhy2bdsGLy8vg8c+fPiwwA8AFxeXV867cOFCKBQK3Yebm1uRazTkxRdYrpFMbSKCikgvMVgkEiH3FRdnlM8/V3lP1RaJRFDT69PE8ycG5537q9LEUeC10hLBcB7zy9fd1InMRfXi31Jp5ESUmrz/Lcl5vHjui89VYI7nc+e/wiESiYweDwA56pK/tgKBEOp8WWX/plKp9H7hvC6FW6vVQqPR6NUlFAqhMnL8i89Vktw1UxEIBFC94rV68ZpUq1YNwOu/roC8r4d/f08VJk38xfetQCB4nkD+6tfX1N+DIpEIRASNxvAX8It6C577q8/j31cAy6PXnYdKpSpw3oDx7ylDr1VlUuQGRyaTGbzCcOXKFd39E0Xh6emJ06dPIz4+HuPHj8eIESNK9a/yOXPmIC0tTffxqtVNRVG7dm141KuHrUbu2I/JVeJRrlIvMTgoKAiXcrJxQWU46XurMgf+rVqV+yC6QYMGIY3IaJr4luxMyEQiXTq4QCBAUGAgtuUqjaaJxysLvlZZGg125xh+fbdmZcHF0bHQ916ZS+fOnSEWi/Cz4XBlRJ0B5BayAm8BFMXIkSMhFAA//218DgGAUaNG6caCegTjt3+ESDPwT6jSABsuihHYvWexawIAf39/nL9wweDPC61Wi7i4WLi6uurGvL294ezsrLvq9W+nT5+G8l9fJ506dcK1a9fw5MmTAscTEeJiY+Hk6Kh3Ob886tatG5KTk3Hjxg2Dj8fFxUEsFqNFixYAACsrKwS0aYWoc4bP68wj4OwDtd4V7zfffPO1aeIymRT+/v4A8prHbt26ISEhweD3bVJSEq5du1bgqnpZCwwMhFqtNrr6KS4uDnZ2dvDz89ON9ejRA4mJiQaboszMTJw/f97k6e7F0aNHD5w5c8bgijeVSoWTJ0/qhbi2adMGlpaWRm/7OH78OIRCIbp27VpmNZtTkb/r+/bti88//1z314ZAIMDt27fxwQcfoH///kUuQCqVokGDBmjRogUWLlyIZs2aGb0hsHr16gWWij569AjVq1c3+vllMhlsbGz0PkqDUCjE9FmzsDM7C5EZGdDk+wFwRaXCzGfP0KJZM90veSBvib17nTqYmJ6OO/k6ahURvn2WjpjsbMz84INSqa8sjR07FjaWlpiZmmIwTXxbdjZ6h4XppRJPnzkT53JyDKaJj09PhZODA4YOHaob9/HxQbcuXfBxxjP8nfuyISQibMrKRFR2FiZPm1ai5GNTqFGjBt4aMgQfHxbhwPWX40TAH1eA+UeFeOedUSXaBbxevXpo0sQbXxwBfr+S97lfOHAdmHMAqF+/nt5l6rFjx0IglmHQFgFS8vWQmbnAOzuBR5mEyVOmFLsmIO/+DQGAFSuW6y2Hz83Nxfr16/DkSbLeDcZSqRRTpkzBkSNHEBsbq/dL9datW9iwYQO6desGHx8f3fg333wDkVCIFStWIC0tTTeuUqmwadMm3L13DzPff79E52EKa9asgUgkwqpVq/D48WPduEajwe7du3H+/Hl06tRJ7+rujPc/wMHrWnx2OK8pfeFmKvDWNhHq162NsLAw3fjkyZNhaVntlWnib7zRX++v+RkzZuD69evYunWr3lWAlJQUrFq1CtWrV8fgwYNL9bV4HU9PT/Tq1QubN2/G9esvv6mICAkJCTh8+DAmTpwIufzl7QNTpkxBSkoKfv75Z919TEDefV8rV66EVCrFu+++a9LzKI7x48eDiLBq1Sq9e6VycnKwZs0aZGdnY9KkSbpxa2trjBs3Dvv378epU6f0vqeuXLmCbdu2oX///qhTp45Jz8NkirpMKzU1lQIDA8nW1pZEIhG5ubmRRCKhjh07lsqy3S5dutCIESMMPjZw4EDq3bu33lhAQACNHTu20J+/NJeJa7Vamjx5MgGg2jIZDZBXo/ZyOQkA8nR3N7j87uLFi+Tm6koigYA6W8ipv7waVZdKCQB9/vnnJa7JVBISEkj+vG5/qTQvsfx5gnCTJk0MLs2NiIgggUBADhIJ9ZNXoyALOUmEQnKyt6cTJ04UOP7x48fk5+NDAKjN88Ryd5kFAaAR4eEVJrjv2bNn1KVzRwJALWuKaEQzkK9r3msVEtyTsrOzSzxHSkoKuTjlJTY3dQaNaAbyqw4CQPa2Cnrw4EGB5+zfv5+sLKuRXCqk/o1Bg71BCrmIJBIx/frrryWuiShvKwihUEgikYiaNWtGrVu3JvnzbRFGjhxZ4Hi1Wk3h4eEEgGrUqEH+/v7k4eFBAMjX15ceP35c4Dkvlj4LhUJq2rQptW7dmqpVq0YAaMCAAaVyHqawdu1aEgqFJBAIqHHjxuTv708KhYIAUK1atQx+vX/++ecEgFwVYhruA+rZQEAioYBquVanixcvFjg+Li6OZDKZwTRxX19fg9+33377LQEghUJBbdq0IR8fHxKJROTs7EynT58uk9fidZKTk6lly5a65esBAQG6pdKDBg0ilUpV4Dnr1q0jsVhMlpaW1KpVK/Lz8yOpVEpWVlYGl9SXV7t376Zq1aqRTCaj5s2bU8uWLUkul5NMJqPNmzcXOF6pVFJoaKhuiby/vz/Vr1+fAFDbtm0pNTXVDGdRPGWeJv7C0aNH6fvvv6cvv/yS9u3bV6zPMXv2bIqOjqYbN27QmTNnaPbs2SQQCGjv3r1ERDR8+HC9lNuYmBgSi8X0f//3f3Tx4kX6z3/+QxKJhM6ePVvoOcsiTTw2NpbefvttatemDQX36EGRkZEF9qzILz09nZYtW0ZB3bpRe39/GjduHJ06darU6jGV5ORkGj16NDk5OJCtlRU1cHen5cuXv/I5Fy9epClTplD7gADq1qULffvtt/T06VOjxyuVSlq/fj31Dgmhtq1b07ChQ+nQoUOk1WpL+3TKlFqtpu3bt9Mb/fpRW//W9OaAAfTHH3+U6h4tKpWKPv30U6pVqybZ2lhSTdcaNGfOHFIqlUaf8+DBA5o3bx517tiBOrZvR7Nnz6YbN26UWk1EeXv0BAcHk52dLSkUNtSiRQvav3+/0eO1Wi0dOnSIhg0bRv7+/tSrVy9at24d5eTkGH3O9evXKTQ0lOzt7UhhY0PNmjUr8h5Z5cHVq1epdevWJJVKSSKRkEKhoHnz5r3yOadPn6Zx48ZR+7b+FBTYjb7//vtX/nxLTk6mkSNHkpOTEylsbMijQQNauXLlK+c4f/48TZo0idq2bUvdunWjxYsXU0pKSnFOsdQolUrasGED9enTh/z9/emtt96i/fv3v/Jnw/Xr1+mDDz6g9u3bU6dOneiLL76ghw8fmrDq0nH//n369NNPqWPHjtShQweaO3fuK/ez0Wg0tGfPHho4cCD5+/tTaGgobdmyxWAjWJ6ZZB+c0jJq1CgcOHAADx48gEKhgI+PDz744APde6GdO3dG3bp19ZZ5btq0CR999BFu3rwJDw8PfPXVVwgJCSn0nBzVwBhjjFU8Rf39XegGJzY2FsnJyejdu7du7KeffsJ//vMfZGZmIiwsDBEREXorZ8ojbnAYY4yxiqfMNvr7/PPP9TKDzp49i1GjRiEwMBCzZ8/Gb7/9hoULFxavasYYY4yxUlToBuf06dPo1q2b7v//+uuvaNOmDVauXInp06dj6dKl2LhxY5kUyRhjjDFWFIVucFJSUvQ22YuOjkZwcLDu/7dq1arU9pip7CpLmjgrX549e4Zvv/0WPt5ecLBTwKuRB/773//qbVn/b6ZIEy+qF2nirVr4wcFOAQ/3uq9NE79w4QLGjBmDmjWc4eRghx5Bgdi5c6fRTe1UKhUiIyPh37olHOwUqF/XDbNnz8a9e/eMznHlyhVMnDgRNWvWhIODA7p27YrNmzcbnUOj0SAqKgod2rWFo70t6tauiRkzZuDmzZtFej1epThp4qzwUlJSsHDhQnh6esLe3h5NmzbF4sWLy31EDHuusHcv165dm6Kjo4ko7+51uVyutxLizJkzZGdnV+i7oc2lLFZRFUVlSRNn5UtSUhJ5ezUiiUhAg70FtLAbaLgPSCYRkod7Pbp3716B55giTbyoMjIyqEO7tiQUCqhvIwEt6Aoa0xxkJRNRDRcng2niO3fuJKlETDUVYnq/LWheF1Abt7xl+BMnTCiwqiYnJ4d6dA8kgQAU0lBIC7qCxrfMWyLvaG9ncOnzvn37SC6Xk0KhoMDAQL2k7xEjRhT4vlWpVNQvLG9pbqB7XtL3pNYge0sRKWysKDY2tsSvVXHSxFnh3blzh+rXr09SqZQCAgIoLCyMWrZsqdvyIDk52dwlVjlltopq/Pjx+Pvvv/Hll19i+/btWLt2Le7fv6/baG3dunVYvHgxEhISyqQRKy3mvMm4sqSJs/Jn4JsDcHj3dhwO1xRIE+/8sxjerbvgzz17deOmSBMvjqlTp2LV8u+wd6gGbfOlqjzMALpFiSB28sTpM+d08QtJSUmoW6c2etRV4pc3SC9ba8UJYNwfeW+nDxo0SDf+8ccf4+svF+CPwVp0q//y+OQsoPt6EdKktXD5n2u6TfXS09Ph5uYGNzc3jBs3Tm9zyfj4eKxevRo//PADRo8erRv/6quv8OHc2dj6JqGP58s50pVAyC8i3FA64MatOyXaqLKoaeKsaLp164YzZ85g2rRpcHR01I3fu3cPixYtQu/evbF+/XozVlj1lNlNxvPmzYNYLEanTp2wcuVK3e6PL0RGRuptEc0Kqixp4qx8uXfvHrZu24ZPO2oMpokv6KzG7r37cOXKFd24KdLEiyojIwORP67EtNb6zQ0AVLcClnbX4My5C3pp4pGRkdCoc7GyNxUIDh3bEuhaX4iIJYt1Y7m5uVjxv+8xrrl+cwMADtWA/wVrcO3GLb3k9aioKGRkZGD48OEFGpI2bdqgWbNmWLp0qW5Mo9Hg+4glCG+q39wAgI0M+KGXBvcfPtYLPy0qKkaaOCu8ixcv4uDBgwgLC9NrboC83MXg4GBs2rSpWPmLzHQK3eA4Ojrir7/+QkpKClJSUtCvXz+9xzdt2qS37TorqLKkibPy5cSJE9BotK9NE8+f8WSKNPGiunjxIp5lZCHMyHl0rQfYyEV6ycdxcXHoWJvgUM3wc97w1CLu+HHdHw3Xr19HUnKK0TlauQKuCnGBZPt69eoZjdPw9fXF2bNndVvnP3z4ELfv3jc6h5cT4Oks0ZujqIqTJs4K70V2k7EUbj8/v1fmYbHyocgRogqFwuC4vb19iYup7CpLmjgrX3TJ0q9JE/93yrCRrFQApZMmXlSvOw+1FlBrqOB5vCYVXSQU6R0PGE/hJgC5BlO4X53gnP9zv+48iPLmL8nrW5w0cVZ4+VO4DaWMv/g359e3fCvfEbuVTGVJE2flS7t27SC3kL0yTVwsFqFz5866MVOkiReVt7c3XJwcEGUkeX37JSArV1sgdf7orbyAyX8jAtadFyEwsJvunh13d3fUq+OGqLOG59h7DXiSoS4wx61bt/QCKl/OkRfw2L59e90mpy4uLvD2aoSoswKDcxy7A9x8qipRenVx0sRZ4XXp0gVCodBosn18fDyqVaumS15n5RM3OCZUWdLEWfliZ2eHd94ZhQUxQoNp4h8dFuGtIUNQo0YN3bgp0sSLSiqVYvLU6VhxUoCf/tY/j8T7wKQ9YgR27aKXJj506FA4OTpg4BYRHrwMLIdSDczYC5y6r8H0GTN140KhENNmvI+oM8D/EgBtvjnOPQbG/CGGf+uWaNu2rW68f//+qF27Nn788Uc8ffpUN67RaLBz505cuXIF7+dLLBcIBJjx/gfYcYnwzTFAk2/3hyvJwNu/ieHt1ajE9ywWNU2cFZ6bmxsGDhyIHTt26N27RkQ4ffo09u7dizFjxhh9R4OVE2W1nKu8Mvcy8cqSJs7Kl+zsbAoJ7pmXCu2al1jesmbeUukunTvSs2fPCjzHFGniRaVWq2nE8zRxTycxhTcDdagjJADk16ypwTTxxMREcnKwJ4lIQH0agoY2BTlZiUkgEFBERESB47VaLb03fjwBIHeHvDm61Mubo7GnB929e7fAc86dO0eurq4kFArJ29ub/P39ye55CvfChQsNzjFr1iwCQLXt8uYIcheQQAByr1eHrl+/XiqvV1HTxFnhpaenU/v27QkA1a9fnwICAsjNzY0AUJ8+fV4Z/srKRoUK2zSH8pBF9ezZM0RFRWHbli3IzsyEt68vxo4da/SGNsYKQ6vVYvfu3VizejXu3b2N6jVqInzECPTu3dvofV0PHz7EqlWrcGDfXmi1WrRt3wFjx45F3bp1TVt8PkSE6Oho/LhqFa5f+wf2Do4Y8tZQ9O/f32jWXUpKCtasWYM/ftsJpTIHzVu2xvjx49GokZE7fQEcO3YMK1euxD+XL8JGYYtBg4dg4MCBkMvlBo9PT0/Hzz//jG3btiE7Oxu+z79v819R+rcTJ05gxfLluHjhHKysbTDgzYEYMmRIqS7d/vvvv7F8+XKcO3Ma8mqWCOv3BoYNG8ZZe6VArVbjt99+w9q1a/Ho0SO4ublh1KhRCAoKglDIb4CYWpmFbVYW5aHBYYwxxljRlNk+OIwxxhhjFQU3OIwxxhirdLjBYYwxxlilww0OY5XEizRxb29v2Nvbo1GjRq9NE1+7di3q1asLmUQImViImjWq49tvvzV6fFZWFiIiItCsWTPY29vDw8MD8+bNQ3JychmcUeHt3LkTjRs3hoVECKlYAGdHe3z44YfQarUGj3+RJt66dWvY29ujbt26pZ4mnpubi/Hjx8PW1hZisRhSqRQtW7bE0aNHjc5x48YNTJs2DXXcXOFob4uO7dti/fr10GhesZthGSMibN++HUHdusLJwQ61XF0wbtw4XLx40Ww1lWdHjhxB//794eTkBGdnZwwaNMjsO0pnZmZiyZIl8PHxgb29PRo2bIj58+frbXtQKZXVcq7yytzLxBkrC0lJSdSkSRMSi8XUqlUr6tevH/n7+5NEIqEGDRoYTBN/++23CQDVUUCXJu7lCAJAQUFBBY5PTU2lFi1akEgkoubNm1NYWBi1a9eOZDIZ1a5dm27cuGGCMy3oo48+IqEA5GIJXZp4S9e882jatGmBpO+cnBzq3r07CQQCatq0KYWFhVGnTp2oWrVq5ODgUCpp4tnZ2VSjRo285e6enhQaGkpdunQhuVxOQqGQVq5cWWCOmJgYsrG2JAdLEU1pA5rfFdS1ft7y9TcH9Ce1Wl26L1whaLVaGjtmDAGgtrVFNK8LaGYAqIaNmGRSCe3atcvkNZVn33zzDQGgmjVrUq9evSgkJISqV69OAGjZsmVmqenp06fk6+tLIpGIWrZsSWFhYRQQEEAymYzq1q1Lt27dMktdxcHLxF+DV1GxyujNN9/E3r17MW3aNLi6uurGk5KS8O2336JVq1bYvXu3bvzPP/9ESEgIxraA0TTxpUuXYtKkSbrnvPPOO9i4cSOmTp2K2rVr68afPn2KRYsWoUGDBoiJiSn7k83n4sWL8G7ihb4NgV8HwGCa+OTJk7FkyRLd+Mcff4wvv/wSEyZMQOPGjXXjGRkZWLp0KUQiEa5cuVKiNPGQkBDs3r0b48ePR7NmzXTj2dnZWLp0KW7fvo2UlBTdruU5OTmoW9sNnpZP8ftgLazzrYbffgkYsEmAr//vG0ybNq3UXrvCiIqKwvDhw/FjX+Adv5fjOWpg0GYBDt6V49btOxzVA+D48eNo06YNevTogX79+ul2z9Zqtdi0aRMOHTqE06dPv3JbgbIwfPhwbN++HdOmTUOtWrV048nJyVi0aBG8vLxw+PBhk9ZUXLyKirEq5t69e9i2bRt69eql19wAgJOTE0JDQ7Fnzx69HVnnzJkDewsYTRP3sAe+/upL3fjTp0+xfv16dO/eXa+5AfJy6Pr3749jx47h1KlTZXOSRkyfPh0iAbCqLwymiXeuA/y0JlI3lpubi+XLl6NDhw56zQ2QF38wZMgQXL9+vURp4rm5udi/fz8CAgL0mhsAkMvlGD58ONRqNT788EPd+KZNm/Ao6QlW9tZvbgAgrBEwxJvw3dLFRt9yKysRSxahp4dQr7kBAAsxsLIPQZmTjbVr15q0pvIqIiICzs7OCAsL0zU3QN7u2QMGDICtrS2WLVtm0poeP36MDRs2IDg4WK+5AQAHBwf069cP0dHROHfunEnrMhVucBir4PLSxDXw8/Mz+PiLDSTz5+rcuHYFfTwLNgVAXpPzphfw+OED3djp06ehVCqNztG0aVOIRCKT32vw999/o1NdGE0TH+AFpKVn6BqD69ev48mTJ0Y31axbty7s7e1LlCZ+5swZqFQqo3O4urrCyckJ0dHRenN4V5egoYPh8+jXCLh+8zaSkpIMH1AGNBoNjp84ibCGhpsqZ0ugfW2B2e8vKS+OHTuGpk2bGtwAUCQSoWnTpia/wnnq1KlXfi2+aMAr678hNziMVXAv3kp5kXD8by+SsPMnHwsEwtemcOf7I1QvXdkQjUYDIjJ5urJQKETOKxK1c9QAinAeRAS1Wl2iNPEXV3leNYdKpSpSKrqhRPiyJhAIIBS++uuEE8tfKszXialfq9d9vRv62VCZcIPDWAXXrl07WFhYvDL5WCwW66WJN/NrgR2XYDRNfN1ZoE69Brqxli1bwsbGBnFxcQbnSEhIABGhW7duJTqXourUqRNibhtPE//pb8DJ0VH3V7W7uzvq1Klj9LW6cOEC0tPTS5Qm7u3tDblcbvS1unbtGlJTU/WCMIOCgvBPkgrxdw2fZ9RZIfyaNTXpvS5CoRCB3bpi3TkRDN2pee0pEHtHy4nlz/Xo0UN3xeTfcnJy8Pfff5c4YLWo2rRpA0tLS6Nfi8ePH4dQKETXrl1NWpepcIPDWAWXlyb+Dnbv3o0zZ87oLVu+ePEidu7ciSH/ShNftGgRcjXAm5tQIE185A7gcSYwf8EC3bilpSXee+89HDx4EImJiXpzXLt2DVu3bkVoaCjc3d3L9mT/5ZtvvoFYJED/jTCYJn7mMTDz/Vm6caFQiBkzZiA+Ph7R0dF697Tcu3cP69evR5s2bUqUJi4UCvHWW2/hzJkz2Ldvn94cjx49QmRkJORyOWbPnq0bDwkJQaOGDRC+U4yr+VbuqrXAf48Cu/7RYsb7H+jd22EK02fMxPG7GnywH8jNdyXnXjowaKsINVycMXjwYJPWVF5NnDgROTk5iIyMRE7Oy78csrOzERkZCa1Wi/Hjx5u0Jmtra4wbNw779+/HqVOn9L5vr1y5gm3btqF///6oU6eOSesymTJZy1WO8TJxVhllZ2dTcHBwXnp17doUEBBA9erVIwDUuXNng2niX331FYkEIJkI9MbzNHErKUgA0OTJkwscn5ubS/379ycAVKtWLQoICCB3d3cCQG3atKGUlBQTnGlBUVFRJBEJSCwE9fbISxO3t8hbJj5gwIACx2u1Whr/PE3cxcWF/P39qVGjRgSAGjVqVCpp4hqNhlq3bk0AyNbWVm8OqVRK0dHRBZ7zzz//UN3atUgoFFB3dwGFNwO52YoJAH344Yek1WpL5wUrom+//ZYAkLO1mIb5gHo3BIlFAnJxMrykvirbtm0byWQyksvl1KJFC2revDlZWFiQXC4325J6pVJJoaGhBIDc3NzI39+f6tevn7f0v21bSk1NNUtdxcHLxF+Dl4mzyupFmvjq1atx9+5d1KhRAyNekyZ+5swZTJ8+HacS895i8mzcBF9//TXat29v8HgiwoEDB7Bq1SrcunULzs7OGD58OEJDQyGRSMry9F7pxQZ5R/+KhlajRu167liwYAFCQkKMPudFmvjly5ehUCgwePDgUk8T/+mnnzB//nw8fPgQUqkUISEh+Prrr+Hs7Gzw+IyMDKxfvx5bNm9CZsYzeDVpinHjx6N58+ZFe0FK2YULF7B8+XKcSkyAhbwaevfpixEjRsDW1tasdZVHd+7cwYoVK/DXX39BIBCgS5cuGDNmTIEVjqak1Wqxf/9+/Pjjj7h9+zZcXFwQHh6Ovn37Vqj7bzhN/DW4wWGMMcYqHt4HhzHGGGNVHjc4jDHGGKt0uMFhjDHGWKXDDQ6r8pKTkzFv3jx4etSHg50Cfs2aIiIiQrczbUXxIk3cx9sLDnYKeDXyeG2aeFFdvnwZNWvWhFgshkgkglgshp2dHfbt21dqcyiVSqxYsQKtWvjBwU4BD/e6+OSTT/Do0aNSm6M4ipomrtFoEBUVhfbt28Pe3h61a9fGjBkzcPPmTdMWzlgVxTcZsyrt5s2b6NyxPZIePcBgLy0a2AMnHwqw7RLQ3M8P+w4chEKhMHeZr/XkyRN06dQBly9fRv/GQDMXwoUkYONFIWrXroPDfx0t8SqO2NhYtG/fHkQEX19f1KlTB48fP8bx48eh1WqxdOlSTJgwoURzZGZmIrhHd8TExqJ3Q8DflXAzFVh/XgRrW3scij4CT0/PEs1RHPv370ffvn0hlUrRqlUrWFpa4uLFi7hy5QpGjBiByMhIvS361Wo13nzzTWzfvh1eXl7w8PBAeno6EhISIBQKsWfPHvj7+5v8PBiryHgV1Wtwg8Pya982AA+unMDh4Wq45etjTj0AukaJ8MagcPwYGWn8E5QTA98cgMO7t+NwuAZeTi/Hrz0FOv8shnfrLvhzz94SzSGVSiESiTBjxowCaeJff/010tJSoVa/Yl//Qpg6dSpWLf8Oe4dq0Nbt5fjDDKBblAhiJ0+cPnPOpBveFSdN/KuvvsLcuXMxduzYAmni3333HTIzM3Hz5s0C4Z2MMeN4FRVjhXTq1CnExMbhm0D95gYA/GoAswM0WLcuCsnJyeYpsJDu3buHrdu24dOO+s0NALjbAws6q7F77z69NPGiOnjwINRqNYKDgw2miQ8aNAgajRaTJk0q9hwZGRmI/HElprXWb24AoLoVsLS7BmfOXcCRI0eKPUdxFDVNXKPRICIiAv7+/gbTxIcOHYoHDx5g27ZtJqmfsaqKGxxWZcXFxUEkFKB3Q8OP92sMKHNVOH36tEnrKqq8NHEt+jUy/Hi/xnn/ayx/qTAWLVoEInplmrhQKMSOHTuKPcfFixfxLCMLYUbOo2s9wEZu+sTyoqaJP3z4EHfv3i3Q3Lzg6uqKGjVq6CWWM8ZKHzc4rMoSiUQgIr2MnfzMkeBcHC92KTaW+lwa5/Fil+LXpYkb2zG5MF53HmotoNaYPrG8qGnixUksZ4yVPm5wWJXVrVs3aAn45azhx6POAAobK7Rs2dK0hRVRu3btILeQ4ee/DT8edQYQi0V6aeJFNW/ePAiFwtemiU+cOLHYc3h7e8PFyQFRZww/vv0SkJWr1Uv6NoWipom7uLjAy8sLx48fN/j5rl27hqSkJJOfB2NVDTc4rMpyd3dHv7BQvH9AhJjbL8eJgE3ngUXxAox/byIsLS3NV2Qh5KWJj8KCGCF+v5JX/wsHrgMfHRbhrX+liRdVkyZNUK1aNezfv99gmvjGjRshFufdgFxcUqkUk6dOx4qTAvz0t/55JN4HJu0RI7Brl1dmP5WFoqaJCwQCvP/++zh9+rTBNPGffvoJXl5e6N69u0nPg7EqpzSTPisCThNn+aWkpFBAm7zU54DaIhrRDORdPS/BeUD/Nyg3N9fcJRZKdnY2hQT3JADk65p3Hi1riggAdenc0WCaeFElJSWRSJT3OatXr04BAQFUt25dAkBCoZCOHDlS4jnUajWNCA8nAOTpJKbwZqAOdYQEgPyaNaXHjx+XeI7iKGqauFarpVmzZhEAcnR0JH9/f/Ly8iKBQED169en69evm+EsGKvYOE38NXiZOPs3lUqFHTt2IOrnn5D0+BFq16mHUaNHo1u3biZdjlxSL9LE16xejXt3b6N6jZoIf02aeFGp1Wr07dsXe/e+WHJOaNbMF3v27IGjo2OpzEFEiI6Oxo+rVuH6tX9g7+CIIW8NRf/+/XVvA5lDcdLET5w4geXLl+PChQuwtrbGm2++iSFDhpT7q4KMlUe8D85rcIPDGGOMVTy8Dw5jjDHGqjxucBhjjDFW6XCDwxhjjLFKhxscxsqpmJgYDBo4ENWdHVDd2QED33wTMTExpTpHQkIChg0dihoujnBxske/sFAcOnTI6PFZWVmIiIiAX7OmcLBTwNOjPubNm2f2OIsLFy5gzJgxqFGjBhwcHNC9e3fs3LnTaNI3Y1VJZmYmlixZAh8fH9jb26Nhw4aYP3++3rYHlRHfZMxYObR06VJMmTIFjZzFeLNR3o64my6JcemxGkuWLMHkyZNLPEdkZCRGjx6N+vYiDPZSQywEtl4W4+xDNebPn4+5c+fqHZ+WlobArl1w+u/TCPMEmlcnXH0K/HpBCCeXGjj811HUrVu3xHUV1W+//YYBAwbAyipvU0YLCwucO3cO169fx4QJExAREVGhVsMxVppSUlLQtWtXnD17Fn5+fqhVqxYePXqEkydPokaNGoiOji6QL1de8Sqq1+AGh5V3J0+eRIsWLTAjAPg6CHjxu5kImLUP+L9YIDExEc2bNy/2HJcvX4aXlxfe9dPi+xBAJHw5x+fRwKfRQHR0NDp27Kh7zqh33sHWDT/h4DAN/PLtGXgnLS+xvEbDljh6zLQ5UUlJSahTpw4aNWqEUaNG6SIlAOCvv/7CunXr8Ouvv2LQoEEmrYux8mL48OHYvn07pk2bhlq1aunGk5OTsWjRInh5eeHw4cPmK7AIeBUVYxXcdxERqG0nxpeBL5sbIO+//xsI1LYT4/vvvivRHMuWLYNDNSGW9HzZ3LyY45NOQGNnMb6LiNCNP336FOvWRWF2gH5zAwBuCuCbQDViYuNw6tSpEtVVVJGRkVCr1Rg2bJhecwMAHTt2RKNGjfSSvhmrSh4/fowNGzYgODhYr7kBAAcHB/Tr1w/R0dE4d+6cmSosW9zgMFbOxB07ir4N1HqNxwsiIRDqoUZszF8lniPEXQ2ZgbxHgQDo11CN2JgjurHTp09DmavSJZP/W++GgFgkMEvSd4MGDWBlZWXwcV9fX8THx/O9OKxKOnXqFFQqFXx9fQ0+/iLx3tTft6bCDQ5j5YxILDKaqA3kpYOLxRLjBxRmDtGr58hR66eP65K+jYRqqzSAVmuepG+NxviJqNXqUtvFmbGK5nXJ9i/GK2uyPTc4jJUzQT1CsOWyCNmqgo9lq4Atl0UI7BFcwjmC8ds/QqTlFHxMpQE2XBQjsHtP3VjLli2hsLEymvT9yzmAIEC3bt1KVFdRBQUF4erVq3jy5EmBx+h50ndFi9xgrLS0adMGlpaWiIuLM/j48ePHIRQK0bVrVxNXZhrc4DBWzkyYMAGZKiGGbhMgXflyPF0JDN0mQKZahAkTJpRojrFjx0IglmHQFgFSsl+OZ+YC7+wEHmUSJk+Zohu3tLTE+PcmYlG8AJvO6yd9H7sDzNwvQljfPnB3dy9RXUU1dOhQODo6YtWqVUhLS9ONq1QqbNq0Cbdu3SpRwjljFZm1tTXGjRuH/fv349SpU3pv1V65cgXbtm1D//79UadOHTNWWYZKP++zfOM0cVYR7Ny5kyxkUrKSiehNL9CbXiArmYgsZFLauXNnqcyxf/9+srKsRnKpkPo3Bg32BinkIpJIxPTrr78WOD43N5cG9H+DgLzE9RHN8hLYAZB/61aUkpJSKnUVVWJiIjk6OpJYLCYfHx9q3bo12djYkEAgoIiICLPUxFh5oVQqKTQ0lACQm5sb+fv7U/369QkAtW3bllJTU81dYqFxmvhr8DJxVlHcvXsXK1euRPShgwCAjp27YMyYMQVWQ5TEw4cPsWrVKhzYtxdarRZt23fA2LFjje5nQ0Q4cOAAfly1Crdv3YCTswuGDQ9HaGhogVVMppSSkoI1a9bg999/R05ODlq2bInx48ejUaNGZquJsfJCq9Vi//79+PHHH3H79m24uLggPDwcffv2rVD33/A+OK/BDQ5jjDFW8fA+OIwxxhir8rjBYYwxxlilww0OY4wxxiodbnCYyRARfvvtN/To0QMODg6oUaMGxowZg/Pnz5fqPHv27EHvXiFwdrSHa3UnjBw5EqdPny7VOUyhqGniz549w7fffgsfby842Cng1cgD//3vf5Gammr0OQkJCRg2bBhcXFzg5OSEsLCwV6aJV2V79uyBj48PpFIpxGIxHOztMWPGDGi1WnOXViR37tzBrFmzUKdOHdjb2yMgIABr1qwxuhkcYxVWma3nKoQFCxZQy5YtycrKipycnCg0NJQuXbr0yuesXr2aAOh9yGSyQs/Jy8TNQ6vV0oQJEwgAubu7U9++fal79+5kb29PUqmUduzYUSrzzJkzhwCQn6uIPusMmt0OVMdOTGKxiH755ZdSmcMUlixZQgCokbOYPu4I+rhj3n8DoCVLlhQ4Pikpiby9GpFEJKDB3gJa2A003AckkwjJw70e3bt3r8BzfvzxRxIIBOTi4kLBwcHUu3dvcnNzIwA0f/58U5xmhfHll1+SQCAgK0tLCgwMpNDQUHJ3z1tq28DdnVQqlblLLJTExESys7MjS0tL6ty5M4WFhZG3tzcBoJCQEFIqleYukTGjKtQy8Z49e2Lw4MFo1aoV1Go15s6di3PnzuHChQuwtLQ0+Jw1a9ZgypQpuHz5sm5MIBDAxcWlUHPyKirz2LBhAwYPHoyhQ4fqJVSrVCr8+OOPuHTpEm7dugUnJ6diz7Fr1y706tUL/xcETA94GVSp1gLv7AB+vSjGtWvX4ebmVtLTKVPFSRMf+OYAHN69HYfDNfDK9xJee5qX9O3dugv+3LNXN/4iTbx9+/YYMmQIhELh8zkIv//+O37//fcCaeJV1d27d/MSyz09Mf699yCVSnWPxcfHIzIyEuHh4Vi7dq0Zq3w9tVqNBg0aQCgUYtKkSXo/Yy9cuIBly5bho48+wieffGLGKhkzrkKtotq9ezfefvttNGnSBM2aNcOaNWtw+/ZtJCYmvvJ5AoEA1atX130Utrlh5rN06VI0bty4wC9MiUSCYcOGQa1WY/Xq1SWaI2LpYrR2E2FGW/0UbrEQWNYLsBARfvjhhxLNYQpFTRO/d+8etm7bhk876jc3AOBuDyzorMbuvftw5coV3fiyZctgZWWFgQMH6pqbvDkE6N27N1xdXRGRL028Kps5cyaICOEjRug1N0DeVvg+Pj7YvGmTmaorvN9//x23bt3CW2+9VeAPSC8vL7Rt2xbLli2DSmUgI4SxCqhc3YPzYqt1e3v7Vx6XkZGBOnXqwM3NDaGhoa+8h0OpVCI9PV3vg5kWESE+Pl6XXPtvVlZW8PDwwLFjx0o0T+yxWIR5GA5etJIC3etpEHvM+D0s5UVR08RPnDgBjUaLfkb2tHuRAB4fH68bO3bsGJo0aWJwcz6BQIBmzZqV+N+jskhISECd2rVhZ2dn8PHmzZsjKzvbYB5WeRIXFwcnJyfUrl3b4OO+vr549OgRbt26ZeLKGCsb5abB0Wq1mDp1Ktq1awdvb2+jx3l6eiIyMhI7duxAVFRU3u6rbdvi7t27Bo9fuHAhFAqF7qO8vz1RWYlEolfexKhWq0u8o6ZIJHx1CrcGFSJZuqhp4rqkbyPPeZEAnv/1FYvFr/z3UKlUFWqH07IkFApf+1oBKHB1p7wRiURQqVQwdldCZU+WZlVPuWlwJkyYgHPnzuHXX3995XEBAQEIDw+Hr68vOnXqhK1bt8LJyQkrVqwwePycOXOQlpam+7hz505ZlM9eQSAQIDAwEAkJCQZ/uCYnJ+Pq1asICgoq0TzdewRj/XkxNAYWtTzOBPZeFyKoe48SzWEKRU0Tb9euHeQWMvz8t+HPF3UGEItF6Ny5s26se/fuOHv2LLKzswscr9FocPLkyRL/e1QW3bt3x91793D//v0CjxER4uJioVDYlPt7+oKCgpCamopLly4ZfDw+Ph7u7u5Gr/AwVtGUiwZn4sSJ+P3333Ho0KEi5+xIJBL4+fnh6tWrBh+XyWSwsbHR+2CmN2PGDNy6dQubNm3Se48/LS0Nq1atgqOjI4YOHVqiOaZOm4ZrTzV47w/oNQdJmcCbm4WwtLLCyJEjSzSHKRQ1TdzOzg7vvDMKC2KE+P2KftL3gevAR4dFeGvIENSoUUM3PnbsWIhEIqxcuRKZmZm6caVSibVr1yI9PR1T8qWJV2ULFy6ERCLBDz/8gKdPn+rGNRoNdu7ciWvXrmPChIlmrLBwOnXqhObNmyMqKkqvWdNqtTh48CBOnDiBmTNn6t2TxViFVkaruQrlxdJhV1dXunLlSrE+h1qtJk9PT5o2bVqhjudl4uYTERFBAoGAbGxsqHXr1uTj40NisZgcHR3pxIkTpTJHZGQkiURCsrcU0RBvUFijvKXStgprOnr0aKnMYQpFTRPPzs6mkOCeBIB8XUU0ohmoZc28pO8unTvSs2fPCjxn//79ZGlpSTKZjJo3b06tWrWiatWqkUQiMZgmXpVt376dxGIxCQQC8m7ShPz9/cna2ooAUI8ePcxdXqHdvn2bPDw8SCAQUOPGjcnf35+cnJwIAE2ePJm0Wq25S2TMqAq1TPy9997D+vXrsWPHDnh6eurGFQoF5HI5ACA8PBw1a9bEwoULAQCff/45/P390aBBA6SmpuLrr7/G9u3bkZiYCC8vr9fOycvEzevSpUtYvnw5EhISYGFhgd69e+Ptt982egNncVy9ehXLly/H8bhjEEsk6NEzBO+8806JlqCbQ1HTxLVaLXbv3o01q1fj3t3bqF6jJsJHjEDv3r2N3nv0Ik18//790Gq1aNeu3SvTxKuyu3fvYvr06Thw4AA0GjXc3GrjP//5DwYMGGDu0ookOzsbv/76KzZu3Ii0tDR4enpi7Nix8Pf3N3dpjL1ShUoTF+RfA5vP6tWr8fbbbwMAOnfujLp162LNmjUAgGnTpmHr1q14+PAh7Ozs0KJFC3zxxRfw8/Mr1Jzc4DDGGGMVT4VqcMyBGxzGGGOs4qlQG/0xxhhjjJUFbnAYY4wxVulwg8NMhp6niffsHgQnBzvUrOFcJmnilcX//vc/1HZzg0wihEwiRG23Wvjf//5n7rIYY6xC4AaHmQQRYfKkSejbty/SLh3ClGapGFo/Cbs2rUZzP1/s3LnT3CWWK/3798d7770HWdZdfNCW8EFbgizrHt577z3079/f3OUxxli5xzcZM5N4kSa+vBcwtuXLcaUaeGurALtvynDz1u0Kt5S7LKxbtw7Dhg17ZZp4VFRUiTdGZIyxioRvMmblUsSSxehWX6jX3ACATAz80JugUeeWOE28svjs00/hag2jaeKu1sBnn31mvgIZY6wC4AaHlTkiQtzx4wjzNBASBcChGtCpNnF69XP3797CG41gNE28f2Pg/p0bpi+MMcYqEG5wmEmIhCJdqrUhSo2AU4zzeV2auEDA37qMMfYq/FOSlTmBQICgoECsOy+CoTu+bqUCR24Rp1c/5+nVFBvPw2ia+MYLQMPG3qYvjDHGKhBucJhJTJ8xE6fuazBjL/Su5Dx4BgzcIoKToz3fNPvc119/jWe5wFtbUCBN/MXY119/bb4CGWOsAuD3BJhJdO3aFREREZg8eTKizonQvZ4a6Upg9zUBbG0V+HPPHlhZWZm7zHKha9eumPvhR1gw/wtU/z+gd8O88d+v5L11NffDj9C1a1fzFskYY+UcLxNnJvUiTTwxIR4ymQV69elb6mnilUVCQgJmzpyJs3+fAgB4+/jim2++QatWrcxcGWOMmR6Hbb4GNziMMcZYxcP74DDGGGOsyuMGhzHGGGOVDjc4jDHGGKt0uMGpADQaDdavX4+O7drB0dYWdWrWxLRp03DjRuXfzfbRo0f45JNP4OFeFw52CrRq4YcVK1ZAqVS+/skVXExMDAYNHIjqzg6o7uyAgW++iZiYGHOXVWVduXIFEydOhFvN6nC0t0W3Lp2xefNmVLHbGBmrMPgm43JOo9FgyKBB2LRlC9rJ5WgvluCJVottuUqopFL8uWcP2rVrZ+4yy8Tly5fRpVMHPEt9ireaaFDXFoi/L8BvV4B2AQH4c89eWFpamrvMMrF06VJMmTIFjZzFeLNR3sZBmy6JcemxGkuWLMHkyZPNXGHVsn//foT27QNrsRpDm6hhLwf23BDhyE0N3h4xAj9GRkIo5L8XGStLvIrqNSpag7No0SK8P2MGVtjao6dcrhvP0GrxdmoKblhZ4uadO7CwsDBjlaWPiODXrClyH13CweEaVM+3Rc6xO0D3dSKMHjcRixcvNluNZeXkyZNo0aLFK9PEExMT0bx5c/MWWkWkp6ejtltN+DtnYetALapJXj627gwwfDvwww8rMXr0aLPVyFhVwKuoKhGtVovvFi9GmFyu19wAgJVQiK9sbPDoyRNs2rTJTBWWnSNHjuDvs+cR0UO/uQGAtm7A1NYaRP64EhkZGeYpsAx9FxGB2nZio2nite3E+P6778xXYBUTFRWFjIxMrOqj39wAwFAfoK+nABFLFpmnOMaYUdzglGNPnjzB9du30UMmN/h4fbEEjeRyxMbGmriyshcXFwdrCxG61jP8eL9GwLOMLFy4cMG0hZlA3LGj6NtAbTRNPNRDjdiYv0xfWBUVFxeHVjWFqGXkD8Y3GhHOnLuArKws0xbGGHslbnDKMZFIBADIfcW7iLlElTKFWyQSQaMlqLWGH3+Rtl0pz10sem2auFgsMX4AK1UikQhKjcDo4znql8cxxsoPbnDKMXt7e/g1bYqtyhyDj5/KzcX1nJxKmcIdFBSErFwttl0y/HjUGcDFyQHe3pUvVTuoRwi2XBYZTRPfclmEwB7Bpi+sigoKCsKp+2pcSCr4GBEQdU6EDu3aQiaTmb44xphR3OCUYwKBADM++AAHs7Pw3bN0qPNdybmhVmPKszQ0atAAISEhZqyybPj4+CCwaxdM2iPCifsvx4mAtaeBFScFmDx1OqRSqdlqLCsTJkxApkqIodsEBdLEh24TIFMtwoQJE8xXYBXTv39/1Pn/9u48Ksqy7wP4d5gRRhrAlUUWlREEF0JyCU1wQ1wqeTO3UDHTFjGxN0s95qPP8RSPlcdjJyWfngQTyTdTyR1FAQ3RRBTRDBERXFjUlIE0iJnr/aPjPI2CbAMz3Hw/53Dsvq7rvu/fz8vr8OteZlydMXWnHAWl/23/Uwv8Iwk4fk2LRR8uNl2ARFQtvkVl5oQQWL58OT7++GN0sbSEv1yBO0LgeMUfcHNxweGjR9GjRw9Th9kkbt++jeCgkTibmYWhXS3QvZ0Op24pkH27CmEzZ+KbTZske1tgz549mDzpVSigxVj1X/erDuTKUQU5vt/+A1566SUTR9i6XLx4EcFBI1FUXIJgNdCxrUDiNQUKNVWIjIzEkiVLTB0ikeTxNfFatLQC55GMjAxERUXhUlYWnrGxwcRJk/Daa69BpVLVvnMLVllZiR07diBuayx+u3sH7moPvDFnDgIDAyGT1fxchBTcuHEDX3/9NVKSjgIAAoYNx5tvvgkXFxcTR9Y6aTQabNmyBfG7duKPhw/g4+uHt956Cz4+PqYOjahVYIFTi5Za4BAREbVm/BwcIiIiavVY4BAREZHksMAhIiIiyWGBQ0RmRaPRIDQ0FDYqFRQKBZRKKwQEBODChQtGO8eff/6JTZs24fmB/dGxvR3cu7liyZIluHnzptHOQUSmxYeMichslJSUwNPTAxpNGfr26QN3tRp3797FyZMnIYTA7t27MXZs4z7ksKKiAhNefhGHDidirIcFXnDR4boGiLsoR5u2tkg8moRnn33WSBkRkbHwLapasMAhMl/9+vXDxYsX8d5770GtVuvbS0tLsWbNGpRpNCgrL4eFRcMvPi9fvhyfrf4E+6bqMNL9v+13HwCj4+QotXRBdk6uZD9jiail4ltURNQiFRUV4fz58wgKCjIobgDAzs4O06ZNw4OHD7F+/foGn6OyshIbo9bjbT/D4gYAOloDUWO1yM3LR0JCQoPPQUTmgQUOEZmFhIQE6HQ6+Pr6Vtvv5eUFS0tL7N+/v8HnuHr1Km7fvYcQr+r7B3QButgpcOLEiQafg4jMAwscIjILj74Zvqqqqtp+nU4HnU7XqG+Qf3TbqaL6U0AAqNRK81vqiVobFjhEZBYmTJgAhUKOU6dOVdt/7tw5VFVVISwsrMHnUKvV6N7VFbFZ1fcfygXulFchKCiowecgIvPAAoeIzIJKpcLw4SNw7NgxpKWl4e/vP+Tn5yMubis6duiAV199tcHnsLCwwHvvf4DY80DUaUD3t1csLpQAb+5T4PmB/TF48ODGpEJEZoBvURGR2aisrESvXr2Qm5uLzp07Q61W4/bt28jNzYW1tTXS09Ph7e3dqHMIITA/PBwboqKg7qjAEJcqXNdYIClPB++eHjh8JAnOzs5GyoiIjIVvURFRi2VpaYnLly9j7dq1UD3zDH755SLKy8owb948FBYWNrq4AQCZTIb1GzYgNTUVQ1+ajlzrQVD2DEJMTAzOnM1kcUMkEbyCQ0RERGaPV3CIiIio1WOBQ0RERJLDAoeIiIgkhwUOERERSQ4LHCIiIpIcFjhEREQkOSxwiIiISHJY4BAREZHksMAhIiIiyWGBQ0RERJLDAoeIiIgkhwUOERERSQ4LHCIiIpIcFjhEREQkOSxwiIiISHJY4BAREZHksMAhIiIiyWGBQ2atuLgY//jHP+Ch7oaO7e0w4Ll+2LhxIyoqKkwdGhERmTGTFjiRkZEYMGAAbGxsYG9vj5CQEGRnZ9e63/bt2+Hl5QWlUom+ffti//79zRAtNbfs7Gz0e7Yv1n76CUa0y8ciPw2cH2Ri3rx3EDRyBH7//XdTh0hERGbKpAVOSkoKwsPDcfLkSRw+fBh//vknRo8e/dRfXCdOnMC0adPwxhtv4OzZswgJCUFISAguXLjQjJFTUxNCYMqkiWgnfkPOfC02vgQsHQrETxE4PksgI/0Uli1bZuowiYjITMmEEMLUQTxy+/Zt2NvbIyUlBQEBAdWOmTJlCn7//Xfs3btX3/b888/D19cXX331Va3n0Gg0sLOzQ2lpKWxtbY0WOxnXsWPHEBgYiMQZwEj3J/s/Ogp8cdYatwqLoVKpmj9AIiJqVvX9/W1Wz+CUlpYCADp06FDjmLS0NIwaNcqgLTg4GGlpadWOr6iogEajMfgh83fy5EnYKOUY0b36/v/xAsrKH+CXX35p3sCIiKhFMJsCR6fTYeHChRgyZAj69OlT47iioiI4ODgYtDk4OKCoqKja8ZGRkbCzs9P/uLq6GjVuahpyuRxanUCVrvr+Cu1ffyoUiuYLioiIWgyzKXDCw8Nx4cIFbNu2zajHXbp0KUpLS/U/169fN+rxqWkEBQXhQaUOu36tvj/2PODQueNTi2EiImq9zOJ/f+fPn4+9e/fi2LFjcHFxeepYR0dHFBcXG7QVFxfD0dGx2vFWVlawsrIyWqzUPHx8fDBqxHC8m3AM7u216N/lr3YhgG8zgY0ZMqxa9b+wtLQ0baBERGSWTHoFRwiB+fPnY9euXTh69Ci6d6/hgYu/8ff3x5EjRwzaDh8+DH9//6YKk0wkbtv/wdm9FwZ8DQTEWCAsHvCOUmDWj8CM6TOwePFiU4dIRERmyqQFTnh4OGJjYxEXFwcbGxsUFRWhqKgIDx8+1I+ZOXMmli5dqt+OiIjAwYMHsWbNGvz6669YuXIl0tPTMX/+fFOkQE2oc+fOOPlzOuLi4mDXZwyutB2IAaOnICkpCdExMZDL5aYOkYiIzJRJXxOXyWTVtkdHR2PWrFkAgGHDhqFbt26IiYnR92/fvh0fffQRrl27Bg8PD3z66acYN25cnc7J18SJiIhanvr+/jarz8FpDixwiIiIWp4W/Tk4RERERMbAAoeIiIgkhwUOERERSQ4LHCIiIpIcFjhEREQkOSxwiIiISHJY4BAREZHksMAhIiIiyWGBQ0RERJJjFt8m3pwefXCzRqMxcSRERERUV49+b9f1CxhaXYFTVlYGAHB1dTVxJERERFRfZWVlsLOzq3Vcq/suKp1Oh1u3bsHGxqbGL/s0ZxqNBq6urrh+/Xqr+i6t1po3wNxbY+6tNW+AubfG3OuatxACZWVl6NKlCywsan/CptVdwbGwsICLi4upw2g0W1vbVrUAHmmteQPMvTXm3lrzBph7a8y9LnnX5crNI3zImIiIiCSHBQ4RERFJDgucFsbKygorVqyAlZWVqUNpVq01b4C5t8bcW2veAHNvjbk3Vd6t7iFjIiIikj5ewSEiIiLJYYFDREREksMCh4iIiCSHBQ4RERFJDgscM/Wvf/0LMpkMCxcurHFMTEwMZDKZwY9SqWy+II1k5cqVT+Th5eX11H22b98OLy8vKJVK9O3bF/v372+maI2rvrlLZc4fuXnzJqZPn46OHTuibdu26Nu3L9LT05+6T3JyMvz8/GBlZYUePXogJiameYI1ovrmnZyc/MS8y2QyFBUVNWPUjdetW7dq8wgPD69xH6ms9frmLpW1rtVqsXz5cnTv3h1t27aFWq3GqlWrav0+KWOs81b3ScYtwenTp7Fx40b4+PjUOtbW1hbZ2dn67Zb49RMA0Lt3byQmJuq3FYqa/2meOHEC06ZNQ2RkJF588UXExcUhJCQEGRkZ6NOnT3OEa1T1yR2Qzpzfu3cPQ4YMwfDhw3HgwAF07twZOTk5aN++fY375OXlYfz48Xj77bexdetWHDlyBHPmzIGTkxOCg4ObMfqGa0jej2RnZxt80qu9vX1Thmp0p0+fhlar1W9fuHABQUFBmDRpUrXjpbTW65s7II21vnr1akRFRWHz5s3o3bs30tPT8frrr8POzg4LFiyodh+jrXNBZqWsrEx4eHiIw4cPi8DAQBEREVHj2OjoaGFnZ9dssTWVFStWiGeffbbO4ydPnizGjx9v0DZo0CDx1ltvGTmyplff3KUy50IIsXjxYvHCCy/Ua58PP/xQ9O7d26BtypQpIjg42JihNamG5J2UlCQAiHv37jVNUCYSEREh1Gq10Ol01fZLaa0/rrbcpbLWx48fL2bPnm3Q9sorr4jQ0NAa9zHWOuctKjMTHh6O8ePHY9SoUXUaX15ejq5du8LV1RUTJkzAxYsXmzjCppGTk4MuXbrA3d0doaGhKCgoqHFsWlraE38/wcHBSEtLa+owm0R9cgekM+e7d+9G//79MWnSJNjb26Nfv374+uuvn7qPFOa+IXk/4uvrCycnJwQFBSE1NbWJI21alZWViI2NxezZs2u8MiGF+a5OXXIHpLHWBw8ejCNHjuDy5csAgMzMTPz0008YO3ZsjfsYa95Z4JiRbdu2ISMjA5GRkXUa37NnT2zatAk//vgjYmNjodPpMHjwYNy4caOJIzWuQYMGISYmBgcPHkRUVBTy8vIwdOhQlJWVVTu+qKgIDg4OBm0ODg4t7nkEoP65S2XOAeDq1auIioqCh4cHEhIS8M4772DBggXYvHlzjfvUNPcajQYPHz5s6pCNoiF5Ozk54auvvsKOHTuwY8cOuLq6YtiwYcjIyGjGyI0rPj4e9+/fx6xZs2ocI6W1/nd1yV0qa33JkiWYOnUqvLy80KZNG/Tr1w8LFy5EaGhojfsYbZ3X63oPNZmCggJhb28vMjMz9W213aJ6XGVlpVCr1eKjjz5qggibz71794Stra34z3/+U21/mzZtRFxcnEHb+vXrhb29fXOE16Rqy/1xLXnO27RpI/z9/Q3a3n33XfH888/XuI+Hh4f45JNPDNr27dsnAIgHDx40SZzG1pC8qxMQECCmT59uzNCa1ejRo8WLL7741DFSXet1yf1xLXWtf/fdd8LFxUV899134vz58+Lbb78VHTp0EDExMTXuY6x1zis4ZuLMmTMoKSmBn58fFAoFFAoFUlJS8MUXX0ChUBg8nFaTR9XxlStXmiHiptOuXTt4enrWmIejoyOKi4sN2oqLi+Ho6Ngc4TWp2nJ/XEuecycnJ/Tq1cugzdvb+6m36Gqae1tbW7Rt27ZJ4jS2huRdnYEDB7bIeQeA/Px8JCYmYs6cOU8dJ8W1XtfcH9dS1/oHH3ygv4rTt29fzJgxA++9995T71QYa52zwDETI0eORFZWFs6dO6f/6d+/P0JDQ3Hu3DnI5fJaj6HVapGVlQUnJ6dmiLjplJeXIzc3t8Y8/P39ceTIEYO2w4cPw9/fvznCa1K15f64ljznQ4YMMXhDBAAuX76Mrl271riPFOa+IXlX59y5cy1y3gEgOjoa9vb2GD9+/FPHSWG+H1fX3B/XUtf6gwcPYGFhWGrI5XLodLoa9zHavDf4uhM1ucdvUc2YMUMsWbJEv/3Pf/5TJCQkiNzcXHHmzBkxdepUoVQqxcWLF00QbcO9//77Ijk5WeTl5YnU1FQxatQo0alTJ1FSUiKEeDLv1NRUoVAoxOeffy4uXbokVqxYIdq0aSOysrJMlUKD1Td3qcy5EEL8/PPPQqFQiI8//ljk5OSIrVu3CmtraxEbG6sfs2TJEjFjxgz99tWrV4W1tbX44IMPxKVLl8T69euFXC4XBw8eNEUKDdKQvNeuXSvi4+NFTk6OyMrKEhEREcLCwkIkJiaaIoVG0Wq1ws3NTSxevPiJPimvdSHql7tU1npYWJhwdnYWe/fuFXl5eWLnzp2iU6dO4sMPP9SPaap1zgLHjD1e4AQGBoqwsDD99sKFC4Wbm5uwtLQUDg4OYty4cSIjI6P5A22kKVOmCCcnJ2FpaSmcnZ3FlClTxJUrV/T9j+cthBDff/+98PT0FJaWlqJ3795i3759zRy1cdQ3d6nM+SN79uwRffr0EVZWVsLLy0v8+9//NugPCwsTgYGBBm1JSUnC19dXWFpaCnd3dxEdHd18ARtJffNevXq1UKvVQqlUig4dOohhw4aJo0ePNnPUxpGQkCAAiOzs7Cf6pLzWhahf7lJZ6xqNRkRERAg3NzehVCqFu7u7WLZsmaioqNCPaap1LhOilo8TJCIiImph+AwOERERSQ4LHCIiIpIcFjhEREQkOSxwiIiISHJY4BAREZHksMAhIiIiyWGBQ0RERJLDAoeIiIgkhwUOEbU4MpkM8fHxNfYPGzYMCxcubLZ4niY5ORkymQz37983dShErQoLHCKqk9u3b+Odd96Bm5sbrKys4OjoiODgYKSmppo6NLNhToUVUWunMHUARNQyTJw4EZWVldi8eTPc3d1RXFyMI0eO4O7du6YOjYjoCbyCQ0S1un//Po4fP47Vq1dj+PDh6Nq1KwYOHIilS5fi5ZdfNhg3Z84cdO7cGba2thgxYgQyMzP1/StXroSvry82btwIV1dXWFtbY/LkySgtLdWPOX36NIKCgtCpUyfY2dkhMDAQGRkZjYq/oqICixYtgrOzM5555hkMGjQIycnJ+v6YmBi0a9cOCQkJ8Pb2hkqlwpgxY1BYWKgfU1VVhQULFqBdu3bo2LEjFi9ejLCwMISEhAAAZs2ahZSUFKxbtw4ymQwymQzXrl3T73/mzBn0798f1tbWGDx4MLKzsxuVExE9HQscIqqVSqWCSqVCfHw8Kioqahw3adIklJSU4MCBAzhz5gz8/PwwcuRI/Pbbb/oxV65cwffff489e/bg4MGDOHv2LObNm6fvLysrQ1hYGH766SecPHkSHh4eGDduHMrKyhoc//z585GWloZt27bh/PnzmDRpEsaMGYOcnBz9mAcPHuDzzz/Hli1bcOzYMRQUFGDRokX6/tWrV2Pr1q2Ijo5GamoqNBqNwXNA69atg7+/P+bOnYvCwkIUFhbC1dVV379s2TKsWbMG6enpUCgUmD17doPzIaI6aNT3oBNRq/HDDz+I9u3bC6VSKQYPHiyWLl0qMjMz9f3Hjx8Xtra24o8//jDYT61Wi40bNwohhFixYoWQy+Xixo0b+v4DBw4ICwsLUVhYWO15tVqtsLGxEXv27NG3ARC7du2qMdbAwEAREREhhBAiPz9fyOVycfPmTYMxI0eOFEuXLhVCCBEdHS0AiCtXruj7169fLxwcHPTbDg4O4rPPPtNvV1VVCTc3NzFhwoRqz/tIUlKSACASExP1bfv27RMAxMOHD2vMgYgah1dwiKhOJk6ciFu3bmH37t0YM2YMkpOT4efnh5iYGABAZmYmysvL0bFjR/0VH5VKhby8POTm5uqP4+bmBmdnZ/22v78/dDqd/pZNcXEx5s6dCw8PD9jZ2cHW1hbl5eUoKChoUNxZWVnQarXw9PQ0iCslJcUgLmtra6jVav22k5MTSkpKAAClpaUoLi7GwIED9f1yuRzPPfdcnePw8fExODYA/fGJyPj4kDER1ZlSqURQUBCCgoKwfPlyzJkzBytWrMCsWbNQXl4OJycng2dbHmnXrl2dzxEWFoa7d+9i3bp16Nq1K6ysrODv74/KysoGxVxeXg65XI4zZ85ALpcb9KlUKv1/t2nTxqBPJpNBCNGgc1bn78eXyWQAAJ1OZ7TjE5EhFjhE1GC9evXSP4fi5+eHoqIiKBQKdOvWrcZ9CgoKcOvWLXTp0gUAcPLkSVhYWKBnz54AgNTUVGzYsAHjxo0DAFy/fh137txpcIz9+vWDVqtFSUkJhg4d2qBj2NnZwcHBAadPn0ZAQAAAQKvVIiMjA76+vvpxlpaW0Gq1DY6ViIyHt6iIqFZ3797FiBEjEBsbi/PnzyMvLw/bt2/Hp59+igkTJgAARo0aBX9/f4SEhODQoUO4du0aTpw4gWXLliE9PV1/LKVSibCwMGRmZuL48eNYsGABJk+eDEdHRwCAh4cHtmzZgkuXLuHUqVMIDQ1F27ZtGxy7p6cnQkNDMXPmTOzcuRN5eXn4+eefERkZiX379tX5OO+++y4iIyPx448/Ijs7GxEREbh3757+agwAdOvWDadOncK1a9dw584dXqEhMiEWOERUK5VKhUGDBmHt2rUICAhAnz59sHz5csydOxdffvklgL9uu+zfvx8BAQF4/fXX4enpialTpyI/Px8ODg76Y/Xo0QOvvPIKxo0bh9GjR8PHxwcbNmzQ93/zzTe4d+8e/Pz8MGPGDCxYsAD29vaNij86OhozZ87E+++/j549eyIkJASnT5+Gm5tbnY+xePFiTJs2DTNnzoS/vz9UKhWCg4OhVCr1YxYtWgS5XI5evXqhc+fODX5uiIgaTyaMeZOZiOgpVq5cifj4eJw7d87UoTSaTqeDt7c3Jk+ejFWrVpk6HCJ6DJ/BISKqg/z8fBw6dAiBgYGoqKjAl19+iby8PLz22mumDo2IqsFbVEREdWBhYYGYmBgMGDAAQ4YMQVZWFhITE+Ht7W3q0IioGrxFRURERJLDKzhEREQkOSxwiIiISHJY4BAREZHksMAhIiIiyWGBQ0RERJLDAoeIiIgkhwUOERERSQ4LHCIiIpKc/weJxU877B4z0wAAAABJRU5ErkJggg==", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# Plot the training points\n", - "plt.scatter(X_iris[:, 0], X_iris[:, 1], c=y_iris, cmap=plt.cm.Set1, edgecolor=\"k\")\n", - "plt.xlabel(\"Sepal length\")\n", - "plt.ylabel(\"Sepal width\")" - ] - }, - { - "cell_type": "markdown", - "id": "d747686d", - "metadata": {}, - "source": [ - "The plotted contours represent the kernel density estimates. The estimates in one dimension are also plotted." - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "id": "25fd9e42", - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/var/folders/ts/39plpy691lg3xd9rvzndrmt40000gq/T/ipykernel_20006/975648639.py:44: UserWarning: set_ticklabels() should only be used with a fixed number of ticks, i.e. after set_ticks() or using a FixedLocator.\n", - " ax_both.set_yticklabels(ylabels)\n", - "/var/folders/ts/39plpy691lg3xd9rvzndrmt40000gq/T/ipykernel_20006/975648639.py:47: UserWarning: set_ticklabels() should only be used with a fixed number of ticks, i.e. after set_ticks() or using a FixedLocator.\n", - " ax_both.set_xticklabels(ylabels)\n" - ] - }, - { - "data": { - "text/plain": [ - "Text(0.5, 0.98, 'Kernel Density Estimate')" - ] - }, - "execution_count": 30, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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/eVrcT5/fK3Pd3vjjTfK7/PZZ58ZU6ZMMdq1a2f4+fkZLi4uRlhYmDF06FBj/vz55/zZ7NmzxxgxYoQREBBQvirS71+Dv5rH9Hzz2p7vfmec73c6OzvbePzxx43w8HDD1dXVCAwMNK6//npj69atf/ozSktLM+644w6jcePG5atfnes9dbHvXxExDIthXOSQQxERsQsrVqzgqquuIjw8nOjo6L+cGktExN6pj6mISA1UWlpaPtXYgw8+qFAqIrWCWkxFRGqQWbNm8euvv7J161b27t1L+/bt2b59O46OGjIgIjWfWkxFRGqQ1atXM3v2bOLi4hg5ciQ//PCDQqmI1BpqMRURERERu6AWUxERERGxCwqmIiIiImIXFExFRERExC4omIqIiIiIXVAwFRERERG7oGAqIiIiInZBwVRERERE7IKCqYiIiIjYBQVTEREREbELCqYiIiIiYhcUTEVERETELiiYioiIiIhdUDAVEREREbugYCoiIiIidkHBVERERETsgoKpiIiIiNgFBVMRERERsQsKpiIiIiJiFxRMRURERMQuKJiKiIiIiF1QMBURERERu6BgKiIiIiJ2QcFUREREROyCgqmIiIiI2AUFUxERERGxCwqmIiIiImIXFExFRERExC4omIqIiIiIXVAwFRERERG7oGAqIiIiInZBwVRERERE7IKCqYiIiIjYBQVTEREREbELCqYiIiIiYhcUTEVERETELiiYioiIiIhdUDAVEREREbugYCoiIiIidkHBVERERETsgoKpiIiIiNgFBVMRERERsQsKpiIiIiJiFxRMRURERMQuKJiKiIiIiF1QMBURERERu6BgKiIiIiJ2QcFUREREROyCgqmIiIiI2AUFUxERERGxCwqmIiIiImIXFExFRERExC4omIqIiIiIXVAwFRERERG7oGAqIiIiInZBwVRERERE7IKCqYiIiIjYBQVTEREREbELCqYiIiIiYhcczS7gcthsNhISEvDy8sJisZhdjoiI1GKGYZCdnU3Dhg2xWtWuI1IVanQwTUhIIDQ01OwyRESkDomNjSUkJMTsMkRqpRodTL28vICyPxLe3t4mVyMiIrVZVlYWoaGh5Z89IlL5anQwPXP53tvbW8FURESqhbqOiVQddZIREREREbugYCoiIiIidkHBVERERETsgoKpiIiIiNgFBVMRERERsQs1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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.clf()\n", - "fig = plt.figure()\n", - "fig.set_figheight(8)\n", - "fig.set_figwidth(8)\n", - "\n", - "ax_component1 = plt.subplot2grid(shape=(3, 3), loc=(0, 0), colspan=2)\n", - "ax_component2 = plt.subplot2grid(shape=(3, 3), loc=(1, 2), rowspan=2)\n", - "ax_both = plt.subplot2grid((3, 3), (1, 0), rowspan=2, colspan=2)\n", - " \n", - "# first_kde\n", - "first_x = np.linspace(X_iris[:,0].min(), X_iris[:,0].max(), num=len(X_iris))[:, np.newaxis]\n", - "first_kde = kernel_density(X_iris[:,0][:, np.newaxis], first_x) \n", - "ax_component1.plot(first_x, first_kde)\n", - "\n", - "# Second kde\n", - "second_x = np.linspace(X_iris[:,1].min(), X_iris[:,1].max(), num=len(X_iris))[:, np.newaxis]\n", - "second_kde = kernel_density(X_iris[:,1][:, np.newaxis], second_x) \n", - "ax_component2.plot(second_kde,second_x)\n", - "\n", - "\n", - "# Fit and plot the model\n", - "buffer = 0.5\n", - "x = np.linspace(X_iris[:,0].min()-buffer, X_iris[:,0].max()+buffer, 100)\n", - "y = np.linspace(X_iris[:,1].min()-buffer, X_iris[:,1].max()+buffer, 100)\n", - "X_test, Y_test = np.meshgrid(x, y)\n", - "X_plot = np.c_[X_test.ravel(), Y_test.ravel()]\n", - "ests = kernel_density(X_iris, X_plot, 0.5).reshape(X_test.shape)\n", - "ax_both.contour(X_test, Y_test, ests)\n", - "ax_both.scatter(X_iris[:, 0], X_iris[:, 1], c=y_iris, cmap=plt.cm.Set1, edgecolor=\"k\")\n", - "ax_both.set_xlabel(\"Sepal length\")\n", - "ax_both.set_ylabel(\"Sepal width\")\n", - "\n", - "# automatically adjust padding horizontally as well as vertically.\n", - "plt.subplots_adjust(wspace=0, hspace=0)\n", - "ax_both.axis('equal')\n", - "\n", - "for a in [ax_component1, ax_component2]:\n", - " a.get_xaxis().set_visible(False)\n", - " a.get_yaxis().set_visible(False)\n", - "\n", - "plt.gcf().canvas.draw()\n", - "ylabels = ax_both.get_yticklabels()\n", - "ylabels[0] = ylabels[-1] = \"\"\n", - "ax_both.set_yticklabels(ylabels)\n", - "xlabels = ax_both.get_xticklabels()\n", - "xlabels[0] = xlabels[-1] = \"\"\n", - "ax_both.set_xticklabels(ylabels)\n", - "fig.suptitle('Kernel Density Estimate', fontsize=16)" - ] - }, - { - "cell_type": "markdown", - "id": "f6a73ab2", - "metadata": {}, - "source": [ - "## 5. The Shape of Things to Come: Coresets\n", - "\n", - "One problem with the KDE method, is that the ``test`` time is high.\n", - "For every query point the user provides, the query must evaluate $\\frac1n \\sum_{i=1}^n K(x - x^*)$.\n", - "This sum is a sum over $n$ length $d$ vectors so costs $O(nd)$ time to return the estimate. In addition, $O(n)$ space is required for any query since the entire dataset is needed. Clearly, for a large dataset, this is not a feasible solution so we need a more scalable method. \n", - "\n", - "The method that we have developed is called a _coreset_ - a specially chosen weighted subset of the data. The coreset should be a small representation of the entire dataset for the kernel query.\n", - "\n", - "The idea is tha a query on test point $x^*$\n", - "\\begin{align}\n", - "q^* = \\frac1n \\sum_{i=1}^n K(x^* - x_i)\n", - "\\end{align}\n", - "should be well approximated by evaluating the kernel on the weight-point pairs $(w_i, v_i)$:\n", - "\\begin{align}\n", - "\\hat{q} = \\frac1m \\sum_{i=1}^m K(x^* - w_i v_i)\n", - "\\end{align}" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "id": "d595e479", - "metadata": {}, - "outputs": [], - "source": [ - "from datasketches import density_sketch" - ] - }, - { - "cell_type": "markdown", - "id": "e177768a", - "metadata": {}, - "source": [ - "We will build a density estimator from the coreset so define a wrapper class." - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "id": "d0247f18", - "metadata": {}, - "outputs": [], - "source": [ - "class CoresetKDE:\n", - " def __init__(self, k_, dim_, bandwidth_=1):\n", - " self.k = k_\n", - " self.dim = dim_\n", - " self.bandwidth = bandwidth_\n", - " self.normalisation_factor = np.sqrt(2.)*self.bandwidth\n", - " self.estimation_scale_factor = 1./(np.sqrt(2*np.pi)*self.bandwidth)\n", - " self.sketch = density_sketch(self.k, self.dim)\n", - " \n", - " def fit(self, X_):\n", - " \"\"\"Fits the coreset to the data\"\"\"\n", - " for x_ in X_:\n", - " self.sketch.update(x_ / self.normalisation_factor)\n", - " \n", - " def predict(self, X):\n", - " \"\"\"Returns density estimates over array X\"\"\"\n", - " predictions = np.zeros((len(X)), dtype=X.dtype)\n", - " for i, x in enumerate(X):\n", - " predictions[i] = self.estimation_scale_factor*self.sketch.get_estimate( x / self.normalisation_factor)\n", - " return predictions\n", - " \n", - " def get_coreset(self):\n", - " \"\"\"Returns the weighted coreset\"\"\"\n", - " samples_weights = [pw for pw in self.sketch]\n", - " samples = np.zeros((self.sketch.get_num_retained(), self.dim))\n", - " weights = np.zeros((self.sketch.get_num_retained(),))\n", - " for i, pw in enumerate(self.sketch):\n", - " samples[i] = pw[0]\n", - " weights[i] = pw[1]\n", - " return samples*self.normalisation_factor, weights" - ] - }, - { - "cell_type": "markdown", - "id": "5f32708f", - "metadata": {}, - "source": [ - "We plot the original dataset in white. The coreset is smaller than the original input size and also has weights associated to each point. The weights are indicated by the colorbar. Only the coloured points are retained by the coreset." - ] - }, - { - "cell_type": "code", - "execution_count": 33, - "id": "5ba2fa78", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 33, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAf4AAAGiCAYAAAAGI6SpAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/SrBM8AAAACXBIWXMAAA9hAAAPYQGoP6dpAABqoUlEQVR4nO3deVxU5f4H8M+ZAQYEBndERSHFNSwtSzBcbpK5Xci05Wdp273dMJcyTK17tUUx0SwrbLtpXTNvKmKR5lVT08TcDdxSc0EFXNhRtjnP7w9jamQ7M3OY9fN+vc4fHJ5zzvOcmcPDebavJIQQICIiIregsXcGiIiIyHZY8RMREbkRVvxERERuhBU/ERGRG2HFT0RE5EZY8RMREbkRVvxERERuhBU/ERGRG2HFT0RE5EZY8RMREbkRVvxEREROwGAw4J///CdCQ0Ph4+ODDh064I033oC5K+97NFD+iIiISEVvvfUWFi9ejM8//xzdu3fH3r178eSTTyIgIAATJ05UfB6JQXqIiIgc3/DhwxEYGIh///vfxn0PPvggfHx8sGzZMsXnseqNf+7cuZg+fTomTZqEd955p8Y0S5cuxZNPPmmyT6fTobS0VPF1ZFnGxYsX4e/vD0mSrMkyERG5MCEEioqK0Lp1a2g0DdebXVpaivLyclXOJYSoVrfpdDrodDqTfZGRkfj444/x66+/olOnTjh06BB27NiBt99+26zrWVzx79mzBx999BF69OhRb1q9Xo/jx48bfza38r548SKCg4PNziMREbmnzMxMtG3btkHOXVpaitY+fsiDQZXz+fn5obi42GTfzJkzMWvWLJN906ZNQ2FhIbp06QKtVguDwYDZs2djzJgxZl3Pooq/uLgYY8aMwSeffII333yz3vSSJKFVq1aKz19WVoaysjLjz1W9EZmZmdDr9eZnmIiI3EJhYSGCg4Ph7+/fYNcoLy9HHgz43PsWNLJyjPw1yBhX/Fu1+u3mt30A+Prrr/Hll19i+fLl6N69Ow4ePIjJkyejdevWGDdunOJrWlTxjx8/HsOGDcOgQYMUVfzFxcVo3749ZFlGr169MGfOHHTv3r3W9AkJCXjttdeq7dfr9az4iYioXrboFm4EDRpJWutO8vsoOyX1W3x8PKZNm4ZHHnkEABAeHo6zZ88iISHBrIrf7H9VVqxYgf379yMhIUFR+s6dO+Ozzz7D2rVrsWzZMsiyjMjISJw/f77WY6ZPn46CggLjlpmZaW42iYiIGpTkIUFj5SZ5KP8H5dq1a9XGLWi1WsiybFa+zXrjz8zMxKRJk7Bx40Z4e3srOiYiIgIRERHGnyMjI9G1a1d89NFHeOONN2o8pqZBDURERI5E8tRAkqxr6pfMmFg3YsQIzJ49G+3atUP37t1x4MABvP3223jqqafMuqZZFf++fftw6dIl9OrVy7jPYDDgxx9/xPvvv4+ysjJotXU3e3h6eqJnz544efKkWRklIiJyJBqtBI3Gui4Fjaz8+Pfeew///Oc/ERcXh0uXLqF169Z49tln8a9//cusa5pV8d97771IT0832ffkk0+iS5cuePnll+ut9IEb/yikp6dj6NChZmWUiByfwWBARUWFvbNBLs7T01NRfeNq/P398c4779Q6fV4psyp+f39/3HrrrSb7fH190axZM+P+sWPHok2bNsYxAK+//jr69OmDjh07Ij8/H4mJiTh79iyeeeYZqzJORI6luLgY58+fN3v5UCJzSZKEtm3bws/Pz7758JQgWfnGL5nxxq8W1ZfsPXfunMngg7y8PPztb39DdnY2mjRpgjvuuAM7d+5Et27d1L40EdmJwWDA+fPn0ahRI7Ro0YILbVGDEULg8uXLOH/+PMLCwuz65q/xsG1Tv1qcYsnewsJCBAQEoKCggNP5iBxQaWkpTp8+jZCQEPj4+Ng7O+Tirl+/jjNnziA0NLTaQHNb1BdV1/gmuBt8Ndb941EiG/DXzCM2rd8YpIeIVMM3fbIFR/mesamfyIUYDAZs374dWVlZCAoKQlRUlFsOJiKi2mm0EjRaK5v6Dbav+BsuggGRk0pOTkbHjh0xcOBA/N///R8GDhyIjh07Ijk52d5ZIyKyGit+oj9JTk7GqFGjEB4ejrS0NBQVFSEtLQ3h4eEYNWoUK39yOSEhIVZPD3NXklZSZbM1VvxEvzMYDJgyZQqGDx+OlJQU9OnTB35+fujTpw9SUlIwfPhwvPTSSzAY1InIRdVdu1aJtL1XsX3XFWRfUh662xrZ2dmYMGECbrnlFuh0OgQHB2PEiBHYvHmzTa5vDTUq7T179uDvf/+7OhmqwY4dO9C3b180a9YMPj4+6NKlCxYuXFhr+rlz50KSJEyePLnB8qSWqqZ+azdbYx8/0e+2b9+OM2fO4Kuvvqq2HrZGo8H06dMRGRmJ7du3Y8CAAfbJpIuqNAh88p/TWJ16AaVlf6w7Htm7KaaO74TmzRpmCe8zZ86gb9++aNy4MRITExEeHo6Kigps2LAB48ePx7Fjxyw6b3l5Oby8vFTObcNo0aJFg57f19cXzz//PHr06AFfX1/s2LEDzz77LHx9fav9w2FOuHeyHN/4iX6XlZUFANUWqapStb8qHalDCIHZC49heXKmSaUPAD/vy8U/ph5AQWHDrAYYFxcHSZKwe/duPPjgg+jUqRO6d++OF198Ebt27TKmO3fuHGJiYuDn5we9Xo+HHnoIOTk5xt/PmjULt99+Oz799FOTKWb5+fl45pln0KJFC+j1evzlL3/BoUOHjMcdOnQIAwcOhL+/P/R6Pe644w7s3bvX+PsdO3YgKioKPj4+CA4OxsSJE1FSUgIAGDBgAM6ePYsXXngBkiTVOtJdCIFZs2ahXbt20Ol0aN26NSZOnGj8/Z9bDZYuXWo815+3P8eF//TTT9G1a1d4e3ujS5cuSEpKqvMe9+zZE48++ii6d++OkJAQPPbYYxg8eDC2b99uku7P4d6bNGlS5zkdhaSRVNlsjRU/0e+CgoIAABkZGTX+vmp/VTpSx+HjRdi47RJqWlHEIAOXrpRh5Te1R/O0VG5uLr7//nuMHz8evr6+1X7fuHFjAIAsy4iJiUFubi62bduGjRs34rfffsPDDz9skv7kyZNYvXo1kpOTcfDgQQDA6NGjcenSJaxfvx779u1Dr169cO+99yI3NxcAMGbMGLRt2xZ79uzBvn37MG3aNHh6egIATp06hfvvvx8PPvggfvnlF/z3v//Fjh078PzzzwO4MR6lbdu2eP3115GVlVXrP6SrV6/GwoUL8dFHH+HEiRNISUlBeHh4jWkffvhh47mysrLw1VdfwcPDA3379gUAfPnll/jXv/6F2bNn4+jRo5gzZw7++c9/4vPPPzeeY8CAAXjiiSdqve8HDhzAzp070b9/f5P9fw737iwkrUaVzdbY1E/0u6ioKISEhGDOnDlISUkxae6XZRkJCQkIDQ1FVFSUHXPpetZvzoZWK8FgqHktMVkG1m7IwjOPhap63ZMnT0IIgS5dutSZbvPmzUhPT8fp06cRHBwMAPjiiy/QvXt37NmzB7179wZwo3n/iy++MDad79ixA7t378alS5eM0Ubnz5+PlJQUrFq1Cn//+99x7tw5xMfHG/MQFhZmvG5CQgLGjBlj7OsOCwvDokWL0L9/fyxevBhNmzaFVquFv78/WrVqVWv+z507h1atWmHQoEHw9PREu3btcNddd9WY1sfHx7gA06lTpzB+/HjMmTMH0dHRAICZM2diwYIFGDlyJAAgNDQUR44cwUcffWSMB9+uXbsa/zlu27YtLl++jMrKSsyaNctk2faqcO979uyp66NwOKpM5wPf+InsRqvVYsGCBUhNTUVsbKzJqP7Y2FikpqZi/vz5nM+vsstXy2qt9Kvk51eoHgNA6fmOHj2K4OBgY6UPAN26dUPjxo1x9OhR47727dub9JcfOnQIxcXFaNasGfz8/Izb6dOncerUKQDAiy++iGeeeQaDBg3C3Llzjfurjl+6dKnJsYMHD4Ysyzh9+rTico4ePRrXr1/HLbfcgr/97W9Ys2YNKisr6zymoKAAw4cPx7BhwxAfHw8AKCkpwalTp/D000+b5OnNN980yfcXX3xhjNXyZ9u3b8fevXvx4Ycf4p133sFXX30F4I9w719++aXicO9kHb7xE/3JyJEjsWrVKkyZMgWRkZHG/aGhoVi1apXxTYfU07SxF7QaCQa59opY7++h+mptYWFhkCTJ4gF8N7u5u6C4uBhBQUHYunVrtbRV3QizZs3C//3f/+G7777D+vXrMXPmTKxYsQIPPPAAiouL8eyzz5r0x1dp166d4nwFBwfj+PHj2LRpEzZu3Ii4uDgkJiZi27Ztxm6FPzMYDHj44Yeh1+vx8ccfm5QHAD755BPcfffdJsco+Wc4NPRGi014eDhycnIwa9YsPProo6qEe7cXSeLKfUQuYeTIkYiJieHKfTYyeGAgUjdm1/p7jQYYdp/64yqaNm2KwYMH44MPPsDEiROrVdz5+flo3LgxunbtiszMTGRmZhrf+o8cOYL8/Pw6g4316tUL2dnZ8PDwQEhISK3pOnXqhE6dOuGFF17Ao48+iiVLluCBBx5Ar169cOTIEXTs2LHWY728vBRNL/Xx8cGIESMwYsQIjB8/Hl26dEF6erpJZVvlhRdeQHp6Ovbu3WvyBh4YGIjWrVvjt99+w5gxY+q9Zl1kWUZZWRkAdcK924ukhdVN/ZIdouWw4ieqgVar5ZQ9G7n91gD0vasZdu65Wm2An1YjIUDvgYf+2qZBrv3BBx+gb9++uOuuu/D666+jR48eqKysxMaNG7F48WIcPXoUgwYNQnh4OMaMGYN33nkHlZWViIuLQ//+/XHnnXfWeu5BgwYhIiICsbGxmDdvHjp16oSLFy/iu+++wwMPPIDu3bsjPj4eo0aNQmhoKM6fP489e/bgwQcfBAC8/PLL6NOnD55//nk888wz8PX1xZEjR7Bx40a8//77AG6MyP/xxx/xyCOPQKfToXnz5tXysXTpUhgMBtx9991o1KgRli1bBh8fH7Rv375a2iVLliApKQlr1qyBJEnIzr7xD1lVs/5rr72GiRMnIiAgAPfffz/Kysqwd+9e5OXl4cUXXwRQPTT7Bx98gHbt2hnHMfz444+YP3++sSVDSbh3UhcrfiKyK0mS8PrL3fDuxyfx3aZsk/7+bp398eqLXdC8acPM47/llluwf/9+zJ49G1OmTEFWVhZatGiBO+64A4sXLzbmb+3atZgwYQL69esHjUaD+++/H++991695Vq3bh1eeeUVPPnkk7h8+TJatWqFfv36ITAwEFqtFlevXsXYsWORk5OD5s2bY+TIkXjttdcAAD169MC2bdvwyiuvICoqCkIIdOjQwWQ2weuvv45nn30WHTp0QFlZWY3jFho3boy5c+fixRdfhMFgQHh4OL799ls0a9asWtpt27bBYDDgr3/9q8n+mTNnGgfkNWrUCImJiYiPj4evry/Cw8NNFtu5OTS7LMuYPn06Tp8+DQ8PD3To0AFvvfUWnn322fo/IAenxsp7kmBY3hoxLC+RY6sKy1tTmFRz5BWUY9+hfFRUyOjc0R+3tK8+zY6oru+bLcPybr3nLvh5WPf+XFxZiQE7djMsLxG5pyYBXhjUr6W9s0Hk0ljxExERWUCNlffssXIfK34iIiILqLKAjx36+LmADxERkRvhGz8RqcYJxgqTC3CU7xmb+onIbVUtslJeXm5c652ooZSXlwNQtmJgQ5IkDSSNdQ3nksQgPUTkhDw8PNCoUSNcvnwZnp6eJvO4idQkyzIuX76MRo0awcPKqXTW4hs/EbktSZIQFBSE06dP4+zZs/bODrk4jUaDdu3aqR6/wV2w4iciVXh5eSEsLMzYDEvUULy8vByiVUmVUf0M0kNEzkyj0TC0KrkNZ23qt/+/TERERGQzfOMnIiKygKRRYVS/HbosWPETERFZgE39RERE5PD4xk8uwWAwYPv27cjKykJQUBCioqLsvrgHEbk2Z33jZ8VPTi85ORlTpkzBmTNnjPtCQkKwYMECjBw50n4ZIyKX5qwVP5v6yaklJydj1KhRCA8PR1paGoqKipCWlobw8HCMGjUKycnJ9s4iEZFDkYSjRDuoQ2FhIQICAlBQUAC9Xm/v7JCDMBgM6NixI8LDw5GSkmKyoIcsy4iNjUVGRgZOnDjBZn8iN2GL+qLqGvtHD4Kfp6dV5yquqECvlZtsWr/xjZ+c1vbt23HmzBnMmDGj2ipeGo0G06dPx+nTp7F9+3Y75ZCIXJmkkYyr91m6sY+fyAxZWVkAgFtvvbXG31ftr0pHRKQm9vET2VhQUBAAICMjo8bfV+2vSkdERKz4yYlFRUUhJCQEc+bMgSzLJr+TZRkJCQkIDQ1FVFSUnXJIRK6sauU+azdbY8VPTkur1WLBggVITU1FbGysyaj+2NhYpKamYv78+RzYR0QNoqqp39rN1tjHT05t5MiRWLVqFaZMmYLIyEjj/tDQUKxatYrz+ImIbsKKn5zeyJEjERMTw5X7iMim7DG4LyQkBGfPnq22Py4uDh988IGic7DiJ5eg1WoxYMAAe2eDiNyIPaLz7dmzBwaDwfhzRkYGoqOjMXr0aMXnYMVPRERkZ4WFhSY/63Q66HS6aulatGhh8vPcuXPRoUMH9O/fX/G1OLiPiIjIAmoO7gsODkZAQIBxS0hIqPf65eXlWLZsGZ566ilIkvIuA77xk6oYJY+I3IWaTf2ZmZkmS/bW9LZ/s5SUFOTn5+OJJ54w65qs+Ek1jJJHRGQZvV5v9lr9//73vzFkyBC0bt3arOPY1E+qYJQ8InI7kqTOZoGzZ89i06ZNeOaZZ8w+lm/8ZDWDwYApU6Zg+PDhJlHy+vTpg5SUFMTGxuKll15CTEwMm/2JyGVIkgrT+Sys+JcsWYKWLVti2LBhZh/LN36yGqPkEZE7steSvbIsY8mSJRg3bhw8PMx/f2fFT1ZjlDwiItvZtGkTzp07h6eeesqi49nUT1b7c5S8Pn36VPs9o+QRkSuyV1je++67D0IIi6/JN36yGqPkEZE7YnQ+cluMkkdE5DzY1E+qYJQ8InI3ksaypvqbz2FrrPhJNYySR0TuxF59/NZixU+qYpQ8IiLHxoqfiIjIEhrNjc3ac9gYK34iIiILSJJk8cp7fz6HrbHiJ7ICoxESkbNhxU9kIUYjJHJvaobltSWrrjh37lxIkoTJkyfXmW7lypXo0qULvL29ER4ejnXr1llzWSK7YzRCIqoa1W/tZmsWV/x79uzBRx99hB49etSZbufOnXj00Ufx9NNP48CBA4iNjUVsbKxxGVciZ3NzNMI+ffrAz8/PGI1w+PDheOmll2AwGOydVSJqSJLmjwF+lm52mMhv0RWLi4sxZswYfPLJJ2jSpEmdad99913cf//9iI+PR9euXfHGG2+gV69eeP/992s9pqysDIWFhSYbkaNgNEIicmYWVfzjx4/HsGHDMGjQoHrTpqWlVUs3ePBgpKWl1XpMQkICAgICjFtwcLAl2SRqEIxGSEQAADWa+Z2hqX/FihXYv38/EhISFKXPzs5GYGCgyb7AwEBkZ2fXesz06dNRUFBg3DIzM83NJlGD+XM0wpowGiGRe5AkjSqbrZl1xczMTEyaNAlffvklvL29GypP0Ol00Ov1JhuRo2A0QiJyZmZV/Pv27cOlS5fQq1cveHh4wMPDA9u2bcOiRYvg4eFR42CmVq1aIScnx2RfTk4OWrVqZV3OieyE0QiJCMCNZno1Nhszax7/vffei/T0dJN9Tz75JLp06YKXX365xj90ERER2Lx5s8mUv40bNyIiIsKyHBM5AEYjJCJnncdvVsXv7+9fbUCTr68vmjVrZtw/duxYtGnTxjgGYNKkSejfvz8WLFiAYcOGYcWKFdi7dy8+/vhjlYpAZB+MRkhEzkj1lfvOnTtnMsUpMjISy5cvx6uvvooZM2YgLCwMKSkptY6IJnImjEZI5L7cNizv1q1b6/wZAEaPHo3Ro0dbeykiIiLHIUnWL8BjhyA9tu9cICIiIrthkB5yaOXl5UhKSsKpU6fQoUMHxMXFwcvLy97ZIiJy36Z+ooYydepULFq0CGVlZcZ906ZNw8SJEzFv3jw75oyICH+st2/tOWyMTf3kkKZOnYrExERER0ebzJOPjo5GYmIipk6dau8sEpGbkyRJlc3WWPGTwykvL8eiRYswfPhwrF271iT63dq1azF8+HC89957KC8vt3dWiYicDit+cjhJSUkoKyvDK6+8UmP0uxkzZqC0tBRJSUl2yiEREZw2LC/7+MnhnDp1CkD90e+q0hER2YOzDu7jGz85nA4dOgCoP/pdVToiIlKOFT85nLi4OOh0OsyePbvG6Hdz5syBt7c34uLi7JRDIiLcaKZXY7MxVvzkcLy8vDBx4kSkpqYiJibGZFR/TEwMUlNTMWHCBM7nJyL7cofofES2UjVPf9GiRUhNTTXu9/b2Rnx8POfxExFZiBU/Oax58+bhzTff5Mp9ROSQJEkDycqmemuPtwQrfnJoXl5emDx5sr2zQURUnRpN9RzVT0RERA2Jb/xEREQWkDQaSFautW/t8ZZgxU+KXNp9EJ+++jouXL4Ezzu7I2HRO/Dx8bF3thqMwWDA9u3bkZWVhaCgIERFRUGr1do7W0QOQe3nw2mfN0m6sVl7DhtjxU91Kjp6CquiRqJlQSluA3AbgPL0HzBxaSiuDLkba75Za+8sqi45ORlTpkzBmTNnjPtCQkKwYMECjBw50n4ZI3IAaj8fTv28aSQVovOxj58cyLUz5/G/O4ajWf51k/1ekgYxCEDodz8jNjbWPplrIMnJyRg1ahTCw8NN1g8IDw/HqFGjkJycbO8sEtmN2s8Hnzf7kIQQwt6ZqE9hYSECAgJQUFAAvV5v7+y4jYP/eBXn/v01tKj9P9LJOI9fCq+4RLO/wWBAx44dER4ejpSUFJMAQbIsIzY2FhkZGThx4oRzNEMSqUjt56Ohnjdb1BdV18haPB16H2/rznW9FEHPJdi0fuMbP9VIGAw4t3R1nZU+tBr0kxshPj7edhlrQNu3b8eZM2cwY8aMGqMCTp8+HadPn8b27dvtlEMi+1H7+XCF561qcJ+1m62x4qcaGa5dh9Yg15uuKTxw4sQJG+So4WVlZQGoPypgVToid6L288HnzX5Y8VONtL6NUOlRf/PaVVQiLCzMBjlqeEFBQQDqjwpYlY7Inaj9fLjE88YgPeRKJI0GIU+NhgF1DAExyNiquYbExETbZawBRUVFISQkBHPmzKkxKmBCQgJCQ0MRFRVlpxwS2Y/az4dLPG+SCgF6zJzOd+HCBTz22GNo1qwZfHx8EB4ejr1795p1Dlb8VKvOM+JQ5uUBQw3jPwWAdXI+egyLdomBfQCg1WqxYMECpKamIjY21mSUcWxsLFJTUzF//nwO7CO3pPbzwefNfHl5eejbty88PT2xfv16HDlyBAsWLECTJk3MOg/n8VOtvNsEYlj6BiyL/CvaXL1m3H9dyFgrFaBoeARSUlLsl8EGMHLkSKxatQpTpkxBZGSkcX9oaChWrVrl+POKiRqQ2s+Hsz9vagbpKSwsNNmv0+mg0+lM9r311lsIDg7GkiVLjPtCQ0PNvyan85ESV9OPIWnav5CZkwWfO27F3Hfedpk3/Zo47UpiRDbgyCv32XI6X85nr0HfyMrpfNdKEfjUzGr7Z86ciVmzZpns69atGwYPHozz589j27ZtaNOmDeLi4vC3v/3NrGuy4iciIpfhrBV/ZmamSX5reuP39r5xrRdffBGjR4/Gnj17MGnSJHz44YcYN26c4muyqZ+IiMgSaozK//14vV5f7z8qsizjzjvvxJw5cwAAPXv2REZGhtkVPwf3ERERWaIqSI+1m0JBQUHo1q2byb6uXbvi3LlzZmWbb/ykiNp9evm/HMOe/6Ygv6QIzf8SgX7DhtR4Pva1E5HD0mhUCNKj/Pi+ffvi+PHjJvt+/fVXtG/f3qxLsuKneqkZPavk1Dn8EPMMNMfPAgAaASh4fyWm+U1GxMdzMPKhhxrkukREzu6FF15AZGQk5syZg4ceegi7d+/Gxx9/jI8//tis87Cpn+qkZvSs0os52HJ3LMSxMyb7PSUJ/Uu02PvoZCSvXq36dYmIGoSNV+7r3bs31qxZg6+++gq33nor3njjDbzzzjsYM2aMednmqH6qjdrRsw6/NAen3l1aZ+CfBS0r8f3po+jcuTOj5BGR2Ww6qv/Lt9QZ1T/mZUbnI8egdvSsM/9eWW+0v67ZxUhKSnL6qF1ERI6KffxUKzWjZwmDASi+Vncig4wm8MCpU6dUuy4RUYORJBWm85m3Vr8a+MZPtVIzepak1QL+vnUn0mpwFZXo0KGDatclImowNp7OpxZW/FQrtaNnhf79kXqj/R0J8kVcXJzzR+0iInJQrPipVmpHz+rw4tPQNA2oNdrfD3IhJi2aDy8vL0btIiLHVzWP39rN1tm2+RXJqVRFz0pPT0dkZCT0ej0iIyORkZFhdvQsXctmuHfvN8BtnUz2lwoZG/0N6LtikfF8al6XiKhBOGlTP6fzkSJqr6BXdOIMfv7vGuQVF6J5v7vRb3A0V+4jIqvZdDrf129D38i6KKWF164j8KEXbVq/cVQ/KaLVajFgwADVzucfFoJBr75g8+sSEalGxSA9tsSKn4iIyBKSCn30rPiJiIichBp99Hbo42fF38Ds1Uet9LrsQyeyHT5v5AhY8Tcge0WXU3pdRr8jsh0+by7ISfv4OZ2vgdgrupzS6zL6HZHt8HlzUZzO13CcbTqf2lHt1L7usWPHGP2OyEbs9ffAXdl0Ot+aJOh9rZzOV3IdgQ/EMTqfs1M7qp3a12X0OyLbsdffA7IBJ125j338DUDNqHYNcV1GvyOyHXv9PaCGJyQJwsqmemuPtwTf+BuAmlHtGuK6jH5HZDv2+ntAVBv28TcA9vETURX28duWLfv4s7/9GHrfRtadq+QaWo34O/v4nZ3aUe3Uvi6j3xHZjr3+HpANVE3ns3azMfbxN5Cq6HJTpkxBZGSkcX9oaGiDRpdTel175Y/IHfF5I0fCpv4GxpX7iKgKn7eGZ8um/qzv/q1KU3/QsKcZnc+V2Cu6nNLrMvodke3weXMxTrpyHyt+IiIiSzhpkB4O7iMiInIjfON3c+Xl5UhKSsKpU6fQoUMHxMXFwcvLy+J0jj6mgYhINWqsvMeV+8iWpk6dikWLFqGsrMy4b9q0aZg4cSLmzZtndjpHj0ZIRKQmt1i5b/HixejRowf0ej30ej0iIiKwfv36WtMvXboUkiSZbN7e3lZnmqw3depUJCYmIjo62mRecXR0NBITEzF16lSz0jl6NEIiIrrBrOl83377LbRaLcLCwiCEwOeff47ExEQcOHAA3bt3r5Z+6dKlmDRpEo4fP/7HBSUJgYGBZmXSmafzOaLy8nLo9XpER0dj7dq11VYSi4mJwaZNm3D58mU0b9683nS5ubno1q2bw65UyBXRiNyHLafzXdz4pSrT+VpHj3HclftGjBiBoUOHIiwsDJ06dcLs2bPh5+eHXbt21XqMJElo1aqVcVNS6ZeVlaGwsNBkI/UkJSWhrKwMr7zySo3RwmbMmIHS0lI8/vjjitLFx8c7dDRCRj0jooYgJI0qm61ZfEWDwYAVK1agpKQEERERtaYrLi5G+/btERwcjJiYGBw+fLjecyckJCAgIMC4BQcHW5pNqoHS6HxK0504cUJROntFI2TUMyKiP5hd8aenp8PPzw86nQ7/+Mc/sGbNGnTr1q3GtJ07d8Znn32GtWvXYtmyZZBlGZGRkTh//nyd15g+fToKCgqMW2ZmprnZpDoojc6nNF1YWJiidPaKRsioZ0TUIKrm8Vu72Trb5i7ZW15ejnPnzqGgoACrVq3Cp59+im3bttVa+f9ZRUUFunbtikcffRRvvPGG4muyj19d7OMnIldlyz7+85u/ht7Pyj7+4mtoe+9DjtvHDwBeXl7o2LEj7rjjDiQkJOC2227Du+++q+hYT09P9OzZEydPnjQ7o6QeLy8vTJw4EampqYiJiTEZDR8TE4PU1FRMmDABfn5+itL5+Pg4dDRCVvpE1CCc9I3f6nn8siybzO+ui8FgQHp6OoYOHWrtZclKVfPvFy1ahNTUVON+b29vxMfHG3+vNJ2jRyMkIqIbzGrqnz59OoYMGYJ27dqhqKgIy5cvx1tvvYUNGzYgOjoaY8eORZs2bZCQkAAAeP3119GnTx907NgR+fn5SExMREpKCvbt26eoa6AKm/obDlfuIyJXYtOm/i2roPfzte5cxSVoO3CU40bnu3TpEsaOHYusrCwEBASgR48exkofAM6dO2fSz5qXl4e//e1vyM7ORpMmTXDHHXdg586dZlX61LC8vLwwefJk1dI5ejRCIiK1OOvKfWYP7rMHvvETEZEStnzjz9y6WpU3/uABDzruGz8RERH9TtLc2Kw9h42x4m9gavY9CyFwZdcBfPPBJ8jKuwr/qDvx3IuTa+xrV0rtvnu1+9qV5s9VqH3/srKv4es1u5GXl4/bujfGX4fXfL7rpRXYe/AI8vPzoff1xD2Rd3OMBFE9BCQIWNnUb+XxlmBTfwNSM2pcwYEj+H7oOPhd+WP54jIh4xtNIVpOGot5iYlm56+mqHs6nc7iqHtqR8lTmj9Xoeb9KyyuwKRpW/DrGU9Iv79RCCFQWnQALz4bgjH/9wAAoNIgsGPvCXj7N4dGc6OiF7KM/Xu2I6ixhNiYEeoUjshGbNnUf25biipN/e36xzr2PH5SRs2ocUVHT2Fb31HwuVxgsl8naTBKNEb+258bo+QppXbUPbWj5CnNn6tQ8/6VV8h4YvyP+PW0h7HSB27EzfDR3475H+Xjv18nQxYCaYcyofNtZqz0AUDSaHD7nfegzCMQa9asVbWcRK7EWdfq5xt/A1B7Rbm9j0zCxdXroa2lSUgAGK+9gBOFuYqawZWu3Kd0Rb5jx46hc+fOqpVXaf4KCgpcotlf7e/Ld5suIuHdE3WkEMi/+Dk2b/wAZy9V1J5KCCxZPBcfLJzNZn9yGrZ84z+7PVWVN/72UcMV5XfWrFl47bXXTPZ17twZx44dM+uafONvAGpGjassLkH2mg21VvrAjTe0yHIdkpKSFOVPaXQ+pVH3kpKSVI2SpzR/Ssvr6NSOMvjV6l8hhKGOFBK0Pnfh0JEzMBgq6zxX5IChjG5I5EC6d++OrKws47Zjxw6zz8HBfQ1AzahxFXmFkOS6G2UkrQaNKz2M0fTqo3bUPaXnUxolz9zogc5O7SiDeQUGSFLdj7aXd3NA8oBWW3s6SZLQomUrZGXuU3RdIndjj3n8Hh4eaNWqlVXX5Bt/A1AzapxXs8YQmro/JmGQcVVUGqPp1UftqHtKz6c0Sp650QOdndpRBps11kLItb/xSxJQdv0ShFwBQ2Xtb/xCCFzKvsjohkS1ULOPv7Cw0GSrbSn8EydOoHXr1rjlllswZswYnDt3zux8s4+/AajdZ7vv8RdxYUVqnX38z2kv4BT7+J2S2t+X73/IwpsLf60jhUDehSXYsulDnLlUXnsqIfDp+7Px4aK57OMnp2HLPv7TO79XpY8/NPL+avtnzpyJWbNmmexbv349iouL0blzZ2RlZeG1117DhQsXkJGRAX9/f8XX5Bt/A1A7alyXmZMg6zxhqOV/tFVyLh6dqHx+u9LofEqj7nl5ealaXqX5c4VKH1D/+zKoXyBat6yopZ9fRnH+r5g5LQYtmnijrCQPBkP1dLLBgBPH0jFkUF9W+kQ2kJmZiYKCAuM2ffr0ammGDBmC0aNHo0ePHhg8eDDWrVuH/Px8fP3112Zdi2/8DaimedmhoaGYP3++2fOyi46ewrf3P4aAi7nGfcXCgGRtIdpPHKfaPH5vb29MmDCh3nn8NZVDzfKakz9Xoeb9u3bdgBde2YSMXz2M/f1CrsT1wt2IH98Fjz5yYx6/QRbY9vNRePu1hIen5419hkrs2r4RIa0a4YHYv6pTOCIbsekbf9r/4G/lG39RcQlCI+6zOL+9e/fGoEGDjMHxlGDF38DUXokt95djWP1uEi5cvYwmfe/Ac5MmcuU+F6L2/buaW4qvk3chNy8Pt3VrgiH313y+svJK7N73C3Lz8hDgp0NU3wi+6ZNTsmXF/1vaRlUq/lsioi3Kb3FxMdq1a4dZs2Zh4sSJio9jxU9ERC7DlSv+l156CSNGjED79u1x8eJFzJw5EwcPHsSRI0fQokULxdfkdD4iIiILqLHynjnHnz9/Ho8++iiuXr2KFi1a4J577sGuXbvMqvQBVvxERESWkXBjfqy151BoxYoV1l3rd6z43Zy9+u7JsRSePoeVs+YiJ/sS9Hf3wN9fneZQYylyLpdg3tsrkZ19GZ07+mFa/NMOlT8iZ8KK343ZK+oeOY6KgiIsi/wrmv96Aa0goRUAsfkXJCR8gvJnR2L2++/aNX9lZQY8+vRy5OS1hqQJBRCKs1eAVQM/xMC7ruDdha/bNX/k3gQ0EFbOirf2eEtwHr+bslfUPXIccnk5Vt0ajWbHL0Dzp/ZGSZLQS2qE4A/XYtrkF+2XP1ngwXHJyMlvA0lj+o6ibxqOnenheOHFV+yUO6I/luy1drM1jup3Q0pXilN7RT5yLGeXpSDjyZdr/b0A8G9NLv5bdMEuzeo791zC1NeP1pFCxsXfluPYgQ/Y7E9GthzVf2L3Vvj7+Vl1rqLiYoTdNcCm9Rvf+N2Q0mhwakfdI8fyc8J7ta4GCdwYczTQ0MhuURDf//gnyHJd0QM1aBZ0n8tEaSTno+Za/bbEit8NKY0Gp3bUPXIs8uU8aOtpZmwK5VEf1ZabXwGNpu5hSJ66Ji4TpZGcj4CkymZrrPjdkNJocGpH3SPHomnZtM43fkgSrkB51Ee1NWvsUc8bP1BeetVlojSS8+EbPzmNqKgohISEYM6cOZBl2eR3siwjISEBoaGhiIuLU5QuKirKltknlUS8OqnON34hBH7QXkNcXJwNc/WHSc9F1fPGL+Nq1ga75Y/IWbHid0NKo8GpHXWPHEubUUOQ36ZZjW/9sgT8JkrRbfxYuw2c692zOZr6ZUMIuYbfyrhekoUHhrTiwD6yG2cd1c+K302NHDkSq1atQnp6OiIjI6HX6xEZGYmMjAysWrXKOD9faTpyPhoPDzx8eBMuhbdHJf6o/A1C4CeUICtuJOa+vcBu+ZMkCau/GI3Wzc5ANpQb9wshI//yz4i6/SjeXjDHbvkjctY+fk7nc3NcuY8AoPhiDr6aOQfZWdlofFcPPDst3qHepHPzruGtBStw8WIOunbS46UX/+ZQ+SPHYcvpfEf2pakyna/bHRE2rd9Y8RMRkcuwZcV/eP/PqlT83XvdbdP6jUv2EhERWUCNpnpO5yMiIqIGxTf+PxFC4OqOvTiwfhPyy0vRPLov+g2616q+bKV94+Xl5UhKSsKpU6fQoUMHxMXF2aQPk333tuEq91np99Re5VV7zIra5XCV7wHdIGD9PHx7BOmBcAIFBQUCgCgoKGiwa1z5cbf4JjhSpHp0Mm7/1XYQTze7Raxetcqic65evVqEhIQI3Fj2XAAQISEhYvXq1Sbp4uPjhU6nM0mn0+lEfHy8GkWzOn9kHVe5z0q/p/Yqr9Lrqp1O7fyRdWxRX1Rd45f9+8TpE8et2n7Zv6/B83szNvUDyPv5ENLuGwdcvGyy31fS4oECD3z90N/NjkKnNKrd1KlTkZiYiOjoaJN00dHRSExMxNSpU1UrpyX5I+u4yn1W+j21V3nVjjapdjlc5XtAroGj+gGkDRqLy9t2QVvLIAuDBMwIqsCh35RFoVMa/e7w4cNo0qQJoqOjsXbt2mrpYmJisGnTJhQUFKja7K80f4y6Zx1Xuc/l5eXQ6/X1fk9zc3PRrVs3m5dX7WiTakeldJXvgbOw5aj+Qwf2w9/f36pzFRUV4baevWw7a81mbQtWaMimm+vns02a92vcPDuLIVKA2LJli6JzbtmyRQAQaWlpNf5+586dAoAYP368onQLFy60sHTW5U9pealmrnKfFy5cqOr3We3yKr3PSsuhNJ3afw8c/XvgLGzZ1H/wwAFx6uRJq7aDBw7YvKnf7Qf3leVcqTeNpNWiicFDcRQ6pdHvTpw4oSid2tHHlOaPUfes4yr3WWmURqXfZ7XLq3a0SbWjUrrK94CqU2PJXS7Zawe6oBb1phEGA66KSsVR6JRGvwsLC1OUTu3oY0rzx6h71nGV+6w0SqPS77Pa5VU72qTaUSld5XtAroN9/AB23f8kLm3+qfY+fo2E6UHl+OUU+/hJOVe5z+zjZx+/M7FlH//+A4dU6ePv1fM29vHfrKH7bPL3Hxbf+nQTa7VhNfbxP6BpYvaUm9WrVwtJksSIESPEzp07RWFhodi5c6cYMWKEkCTJeL74+HgBQAwfPtwk3fDhwwWABpvSpzR/ZB1Xuc9Kv6f2Kq/S66qdTu38kfVs2ce//0C6+PXkGau2/QfSbd7Hz4r/d3m7D4lvOvY3qfCXaW8Rj7XooOq83dDQUEXz+L29ve0yj7+m/JF1XOU+K/2e2qu8Sq+rdjq180fWYcVfPzb13yTvwGHsS92A3PLraNG/D/oNHMCV+8hqrnKfuXIfV+5zdLZs6t93IAN+Vjb1FxcV4Y6etzI6380YnY+IiJSwZcW/98BhVSr+O3t2t2n95vaj+omIiNyJ28/jJyIisoSzhuVlxd+AhBDITTuA/d9tQH7pdTQf1Bf97hvk0mMGyLXZq486r6AE36zfhqLiEhTmXsQLE/4OHx8fi893/fp1xMfH48SJEwgLC0NiYqJV5yP35KwVP/v4G0jez4ew45HnoTl/ybjvupCxKUDGfR/Pw8gHHzT7nMnJyZgyZQrOnDlj3BcSEoIFCxZg5MiRxn1Tp07FokWLUFZWZtyn0+kwceJEzJs3z7ICkdtT+v1TU2WljP/tPI5mLYIg/WmFs6LCfKz+z7tIeu9ts88ZGxuLdevWoaKiwrjP09MTQ4cORUpKihrZJjuyZR//7gNHVenjv6tnV/bxO7vCQ8fw08D/g8jMMdnvI2kwotADax/6h8tF+yPXZo/ocrIsY8fBC9UqfQDw8w/A4/94BU8+/axZ54yNjcXatWsxePBgk3IMHjwYa9euRWxsrIolIFcnhKTKZmt8428Au2OeRfa6LbWuBCgD+GfrCuxzkWh/5NrstfLc2ewi5OTLtf5eCIGDe3di7KiBiprpr1+/joCAAGMlX9PzsWHDBhQUFLDZ34nZ8o1/1/7jqrzx9+nVmW/8zqz8ah4ur99Wa6UPABqNhFsy87F9+3ZF59y+fTvOnDmDGTNmmPyxunEuDaZPn47Tp08jPj4eZWVleOWVV2pMN2PGDJSWliIpKcn8gpHbUvr9U/p9Vurk2Suo671EkiT06HU34uPjFZ0vPj4eFRUVdT4fFRUVis9HVNXHb+1ma6z4VVZ+JQ+opxFF0mrRWNK6TLQ/cm32ii6n9fSq1sR/M41Ga/ze10fp86H0fETOihW/ynQtmwH1/LESla4V7Y9cm72iyxkqyup84xdCwGAwGL/39VH6fCg9H5GzvvGzj78B7HkwDlnfbKq9j18CXgmqwAH28ZMTsFcf/7mcImTn1d3Hv2/Xj3jykWj28ZORLfv4f9p/En5+VvbxFxehb6+O7ON3dl3eeBEabx0MtfxPtdxwFbMWzlf8R1Kr1WLBggVITU1FbGysyWjk2NhYpKamYv78+fDx8cHEiRORmpqKmJgYk3QxMTFITU3FhAkTWOmTWZR+/9Sez9+2hS+KCvJqfOsXQsBQWYmff/xGcSXt4+ODoUOH1vl8DB06lJU+uTy+8TeQwkPHsO3h8dCcOv/HPmHA/5oAIz58S7V5/KGhoZg/f3698/i9vb0xYcIEzuMniyn9/qmpUpbx3Q/paNWmvbG/XwiB3KuXkPyfRfjko/fNPifn8bs2W77xb99/SpU3/qheHRik52bOWPFXyf/lGPauXYfc0mtoMaAP+v1lIFfuI6dlr5X7CopK8N/kDSgsLERxfjZefmkSV+6jGtmy4v9x/2+qVPz9et3Civ9mzlzxExGR7bDirx/X6iciIrKAGivv2WPlPlb8REREFhCwPsiOPZrc3abiV9o3aa8+TKWU9t27SnmLr1XgwC9HkJeXB30jD0TdE2FV/tS+f0qdOlOA1P/tRX5+Pvy9CvB83GM1XvdaaQX2HTyC/Px86Bt54J6+fZxyDMfZ8wVYunwTCgsLgYpLeHPWxBr70EvLKrDnwGHk5xdA7+uFeyLvqrG8OZdLMO/tlcjOvozOHf0wLf5pm3xuSpWVV2L3vgzkFxZC76vDPRF3OuXzpngMUUUlft6bjoLCIuj9vBF5dy94eLhNdeIw5s6di+nTp2PSpEl45513lB8onEBBQYEAIAoKCiw6fvXq1SIkJOTGP2e/byEhIWL16tUWpbOX+Ph4odPpTPKn0+lEfHy8STpXKG9pmUH8uPe0+PlovnHb8csl8Ubix2J1crJF51T7/ilx6Uqp+E/Kr2LXkTxjOdIO54l3/r1LxL8805iuvMIgtu4+IXYdyf1Tulzxzkdfi+Q1ay0qhz0UFleIxf/ZL9IO55l8dp9+nS4eHfMPY7pKgyx+2HlE7My4YpLuk+Xfi5S1qcZ0paWV4oExX4jIoZtE3+FbjVt45Lti4uR/mlzbHt9ngyyLTTsOiR2HLpmU48uU7WLtt+vtnj9zKMmfLMvif1v3iq37L5iUN3nDfvHtuo12zP0frK0vzLnGlr1nxJ5juVZtW/aesSi/u3fvFiEhIaJHjx5i0qRJZh1r1jz+xYsXo0ePHtDr9dDr9YiIiMD69evrPGblypXo0qULvL29ER4ejnXr1plzSaspjSpmj+hj5lAadc8VyltRKWP/8SvQ6kwHzXh6emHQ0FH4LavU7Pypff+UKCqpxO4juejQsYXJ0rMajYS7+3RGr6jHET91OgyywO6MLHj6NIEkaf6UToO7+96Lggp/JK9ZY1Y57KGyUkbq1rO4vVcoNBrT5s9u3dpizLP/xOiHn4AQAj/tPwNvfSC0WtO3xO49egO+7bAm5RvIssCD45KRk98GksY0nb5pOHamh+OFF18BYL/v87afj8O3STA8b2p9uKVjN/g074y1366za/6UUpq/zTsOISCwI3x8fE2OD2rbHgGtw/Htuo32yL7d2GvlvuLiYowZMwaffPIJmjRpYvbxZo3q//bbb6HVahEWFgYhBD7//HMkJibiwIED6N69e7X0O3fuRL9+/ZCQkIDhw4dj+fLleOutt7B///5a18uuiaWjNJWuOHbs2DF07tzZ5iuTKVVeXg69Xl/viny5ubno1q2b05f3bM41XLxSWue1Z8U/hW9TvlaUP7Xvn9L7sm5rFpoF+tS53nzinIVYOP8lXLhaWWe69xNfwUfvJzr0yozbduXAp7F3rb+XZYEvv0jBjCkPIvNq7SvyybKMr/+ThJGxT2Pam8fruKKMi78tx+G9i1T93JQqKinH0czrtf7eYDBg0/pVeHniEw79vCn9O5mecRS/nC6u9s+aMa3BgEP70/DM/91v1+4LW47q37znHPz8rLtGcXEh7u3dDpmZmSb51el00Ol0NR4zbtw4NG3aFAsXLsSAAQNw++23m9XUb9Yb/4gRIzB06FCEhYWhU6dOmD17Nvz8/LBr164a07/77ru4//77ER8fj65du+KNN95Ar1698P77dS+6UVZWhsLCQpPNEkqjiiUlJdkl+phSSUlJiqLuxcfHu0R5s69cq/MPhxACPe8eoDh/at8/pdetrGfYjiwL3D9iFH45erbeNen7RA12+OiLZy7mwWCoK5oecN+QaGzYkobKyso60kmIuncE3lr4P8hy7ekADZoF3af656bUL8fOorKyotbfa7Va9PvLcId/3pT+nUzdsK3Of041Wi1uuyMS23ekNXSWXVJwcDACAgKMW0JCQo3pVqxYgf3799f6eyUsHo1hMBiwcuVKlJSUICIiosY0aWlpePHFF032DR48uN7VsRISEvDaa69ZmjUjpVHFqqLV2Tr6mFJK82dudD5HLK8QAtDU/bWUJAnNmgcqzp/a90/pdX19Pev+Q6mR0LSpHl66ymp/cP9MkiS0aBnk8NEXfX19oNXWXl5JkqDXe6Mg17vOgWCSJKFpsxYoKBLQ1PNd8NQ1Uf1zU6q0rBKNvOtupvVp5Iuz5zLtkj+llP6dLLlWCoPBAI2m9n/KNRoNruTmqZ9JByUA1N52pfwcAGp8479ZZmYmJk2ahI0bN8Lbu/bWtfqYvVZ/eno6/Pz8oNPp8I9//ANr1qxBt27dakybnZ2NwMBAk32BgYHIzs6u8xrTp09HQUGBccvMzDQ3mwCURxWrilZn6+hjSinNn7nR+RyxvJIkAXW+5d345+ByzkXF+VP7/im9bnFxOWS59jdgg0HgyuV8lJVeg8FgqDWdEALZWecdPvpicfG1Ot/4ZVkgP/86Ksqu1fmmLITAlUvZCPBHPW/8QHnpVdU/N6W8ddo6W2oA4FpJMdq3C7ZL/pRS+neykY+u1mb+KrIso3nTxqrmz5FVzeO3dgNgHDtXtdVU8e/btw+XLl1Cr143ZlF4eHhg27ZtWLRoETw8POr8O/JnZlf8nTt3xsGDB/Hzzz/jueeew7hx43DkyBFzT1MnnU5X7SZYIioqCiEhIZgzZw5k2fT/MlmWkZCQgNDQUMTFxSlKFxUVZXGZrBEXFwedTofZs2fXmL85c+bA29sbiYmJLlHeoBaN6vwCS5KE/T9vVZw/te+f0ut6abR1RmjWaiWs//Zr3N4tpN43/l3bNyAxMVFROeLi4hTlT223BDet840fADZ89z2GDOoLDw/PWtMIIbB987d45aX763njl3E1a4Pqn5tSt3UNqbMcssGAbZu+cfjnTenfyb8OGQBZrv25lA0G7N/9I6LuiWzoLLute++9F+np6Th48KBxu/POOzFmzBgcPHhQ8dgKsyt+Ly8vdOzYEXfccQcSEhJw22234d13360xbatWrZCTk2OyLycnB61atTL3shZRGlXMy8vLLtHHlPLy8lIUdc/Hx8clyhvU1BvCUF5jP7AQMv63bjWefWas4vypff+UXrd/7+bIzi6p8S1YlgWOHctCxzaVCGrui4rSIhhqKK8syzi0bxce/Ot9Dh99se8dLXD8eE6NrRwGg0BOTjEund2KwGZ+uF50ucZKRDYYcP7cb+gfeRvuvqMlmvplQ4iaGlNlXC/JwgNDWqn+uSnl18gLxXkXasyfwWBAXt4V3NY12OGfN6V/Jxv56FCSe7bGc8iyAWVlpWjbwtuh1iVoaLYe1e/v749bb73VZPP19UWzZs3MGjBv9Tz+gQMHinHjxtX4u4ceekgMHz7cZF9ERIR49tlnzbpGQ8zjDw0NVTSvvaZ09lLT/G1vb29F89Cdrbxl5QaxdfdJk3nt2/ZfFK+88Y5YvVq9efzW3D8lcgvKxGcrj5jMa/8pPVckvL9FxE99xZiuolIWP6QdFTszrv6R7pfLIuGdJSI5eY1F5bCHa9crxTufpomf0nNN1i14//M94qFHnjKmMxhksWlHusn897TDueK9fyeLNSnfGNOVlxvEqLGfiYgh/zPO4Y8c9oPofneCmPTCqybXtsf3WZZlsfHH/dXmtX/61QaR8s13ds+fOZTkT5Zl8f0PP4uNu0zX2Fi+9ifxzXcb7Jj7P9hyHv+Gny+IHYeLrNo2/HzBqvz279/f7Hn8Zk3nmz59OoYMGYJ27dqhqKjIOD1vw4YNiI6OxtixY9GmTRvjaMOdO3eif//+mDt3LoYNG4YVK1Zgzpw5NpvO92euspKdu63cd620AvsOZCA39yoC/LwQdU9fp1y573xWEVam/IS8vFw0blSM5+OeqPG6pWUV2LM/A7m5uQjw09W6UqGjr9x3MacQiz/9Fvn5BdCKK0h4I77GlfvKyivx875fkJeXj8Z+ulpXKszNu4a3FqzAxYs56NpJj5de/JtDrdxXXlGJXXt+QX5+PgL8vXFP5N1O+bwpzV9FZSXSdh9Cfn4BAvSNcE9Eb4cphy2n8234+QJ8rZzOV1JciMF3t3Hc6HxPP/00Nm/ejKysLAQEBKBHjx54+eWXER0dDQAYMGAAQkJCsHTpUuMxK1euxKuvvoozZ84gLCwM8+bNw9ChQ83KJKPzERGREras+L//+aIqFf/9d7d23IrfXljxExGREras+NftUqfiH9rHthW/2YP7iIiIyHkxnNJNHL0Pjqzj6GMflF5XaRQ/pee7XlqBvVXn8/W0WR81n7ea8b44B0vX2r/5HDZn0TBCG7PFKE0hHD96FlnH0aMWKrluRaVBbPn5V5F22DSK36JPVlWL4qfsfLLYsuu4SDv8x2yCXYdzRdLStSaj6xvivvB5qxnvi3VsOao/NS1bbEm/ZtWWmpZtk/rtz9jU/ztHj55F1nH0qIVKrivLArvSL8KrUVOTBX80Gg16RwxEiWiC5DUpys8nBNIOZULn28xkGVZJo8Htd96DMo9ArFmztkHuC5+3mvG+OBch1NlsjYP7oDw6lb2iZ5F1HD1Ko9L8/bQ7A+cul9e6/r8QAh++MwsfvTdPUTnS9mbg7KW6l85dsnguFs1/XdX7wuetZrwv6rDl4L5vd2arMrhvRGQrDu6zNaXRqewVPYus4+hRGpXm7/CJ89WWVL1ZRL/7FZfj0JEzMBjqXgs/csBQ1e8Ln7ea8b44HxmSKputseKH8uhU9oqeRdZx9CiNSvOn0XrV+aZ3I4pfK8XlgORRZ9AVc8+n9L7weasZ74vzUTNIjy2x4ofy6FT2ip5F1nH0KI1K8ydXlimI4ndBcTmEXFFjfIA/n+9S9kXV7wuft5rxvpCtsI8f7Ftzda7Sx79zTwbOXa69Tx4APpj/Kj5JWqCoHLv2HsaZS+W1nksIgU/fn40PFs5mH78N8L6ow5Z9/Gt2XFKlj/+Be1qyj9/WlEan4sPmnBw9SqPS/LVs4oOyawU19svLsgEZh/YiZuhfFJejRRNvlJXk1diKIBsMOHEsHUMG9VX9vvB5qxnvi/OxdXQ+9TLuBOw5j9+RomeRdRw9aqGS61ZWyuKHtCNiZ8aVP0X7uyLmvfcfkbwmxfzzGWSxeedh8dMvl43n25lxRby9+CtF6wJYc1/4vNWM98U6tpzHn7zjsthwsMyqLXnHZZvP42dT/024YpZrc5WV+25E8UtHbm4eAvx1iOpbcxQ/pecrK6/E7n2/IDcv70ZUQCvPp3Z53Q3vi+Vs2dS/avtlVZr6R0W1YJCemzFIDxERKWHTiv/HK2hkZcV/rbgQo/o1Zx8/ERERNQwG6SEiIrKAGkvu2qPNnRU/uZWS6xXYf+gI8vPy4O/rUWtfdnl5OZKSknDq1Cl06NABcXFx8PLyqpbOXn2xaudPaTpHvy/u1jdut+9fRSV+3puOgsIi6P28EXl3L3h4uF91osbKe/ZYuY+j+sktlJUbxLY9vxlHrleNhk94Z4lITl5jkjY+Pl7odDqTUdU6nU7Ex8ebpLNXFDW186c0naPfF3eLameP8sqyLP63da/Yuv+CybOUvGG/+Hbdxga7rjlsOap/xdar4pu9FVZtK7ZeZXQ+IrVVGGTsPXoJHt6mA2c8PDwwIDoG53NhjHo2depUJCYmIjo62mQedXR0NBITEzF16lQA9ouipnb+lKZz9PviblHt7FXezTsOISCwI3x8fE32B7Vtj4DW4fh23cYGuS6pi6P6yeWdv3Qd5y9fh6aOJtA5r8bhq/98iiZNmiA6Ohpr166ttnJaTEwMNm3ahNzcXHTr1s3mK6yVl5dDr9erlj+lKxUePnzYoe+Lu614Z6/ylpZV4MDJwlrjO8gGAw7tT8Mz/3e/Xe+zLUf1f7UlV5VR/Y8ObMpR/URqOn+5qM5KXwiBO/oMRHx8PMrKyvDKK6/UGB1txowZKC0tRXx8vF2iqCUlJamaP6VR9xz9vrhbVDt7lXfvoV9rDQkNABqtFrfdEYntO9JUva4jk4U6m62x4ifXJ9U96EiSJLQIDMKJEycA1B8dTWk6taOoKY2SpzR/ap/PXvfF3aLa2au8JdfqDhIF3PjH40punqrXJfWx4ifXJ1eirh4tIQRysi4gLCwMQP3R0ZSmUzuKmtIoeUrzp/b57HVf3C2qnb3K69vIq84wzsCNrobmTRurel1HVjWdz9rN1tjHTy7v/OXf+/g1tTf3vzn9Wfx3+RKH7stmH3/N2Mdvqz7+Suw/kQ8PD88afy8bDNi/ZzuefXy42/Tx/2dznip9/I/f24R9/ERqatXUG4aKMlTWEHtelmX8+MN6PPH4Q/Dx8cHEiRORmpqKmJgYk9HSMTExSE1NxYQJE+Dj42OXKGpeXl6q5k9p1D1Hvy/uFtXOXuX11nmgJPdsjb+TZQPKykrRtoW3y9xnl2aziYNW4Dx+slZ5hUFs/flXkXY41zj3+MeD2WJmwgdidXKySdqa5qt7e3srmq9uiyhqaudPaTpHvy/uFtXOHuWVZVl8/8PPYuOu0ybz+Jev/Ul8892GBruuOWw5j//zzXli5S6DVdvnm/MYna8mbOontVwvrcDeAxnIzc1FgJ8Xou6JdMoV6rhyX824cp9tyltRWYm03YeQn1+AAH0j3BPR22Husy2b+pduykMjXyub+ksK8cQg2zb1s+InIiKXwYq/fu63uDIREZEKGKSHiIjIjchCgiysDNJj5fGWYMVPqnL0Pla185d9pRApqZuRl5eLsyd+wfx5s+Hn5+cw+VP7utfLKrD3wBHk5+dD7+uJeyLvdqjPl8iW+MZPbi85ORlTpkzBmTNnjPtCQkKwYMECjBw50n4Z+52a+SsprcSuXy7AX98Yvfr8BQAg7n8QG3edwgdvvYxNG7+3a/7Uvq7BIPDjnl/ho28BXeMQBDa+ke7T5d8jUC8QGzO8wfJHROriPH5ShaNHR1Mzf+XlMg6dLICff4DJfkmS0LpNe8yY8wkiIyPtlj+1ryuEwM5D5+Dt37zaIkg9ekWgUheENSlrGyR/RI6MK/c1II7qd2yOvnKa2vk7cqYARddFnQFLvvxsEWb/6wVFzf72un9Kr7tr72GcuVRe63mELOM/n76NdxNnsdmf7M6Wo/o/Xp8PHytH9V8vKcTfhzTmyn3kXBw9Opra+csvrqjz90II3P/Xh/H444/bJX9KKb3u/oxTMBiqr3poJEnoO3CYy0S/I3J17OMnqzl6dDS186fVetT5ti9JEnx9/Y3R72ydP6WUXheSts7gLJIkoVnzQGSd2aVq/ogcnRAShJWj8q093hJ84yerOXp0NLXzZ6isP9pfUVGhMfqdrfOnlNLrQq6EoYY4B1WEELicc9Flot8RKeWsffys+MlqUVFRCAkJwZw5cyDLssnvZFlGQkICQkNDERUV5RL5a+Jfc3SyKpIkITV5Gf7zn//YJX9KKb1urx4dofWou3Fwxw+pdvt8icg8rPjJao4eHU3t/HVo64/Kyooa3/qFECjIz8WBXZsVz+e31/1Tet0Wjb1RWpwLg8FQ7RyywYDfThzFfQM5n5/cjyzU2WyNo/pJNTXNBw8NDcX8+fMddh6/pfm7Xm7Aj3t/Q+MmLYz9/UIInD55DB8umIGtW3+wa/7Uvq4sC2zddQQ6/5bw9LwRlMdgMGD3T5vRrqUOD8T+tcHyR2QOW47q/+DbAlVG9Y8fYdv6jRU/qcrdVu67nFuIL7/+FlevXEHmb4fx/qK3XXrlvrLySuze9wty8/LR2M8L9/SNcKjPl4gVf/1Y8RMRkcuwZcX//jfqVPzP/1VZfhcvXozFixcbW+e6d++Of/3rXxgyZIhZ1+R0PiIiIguo0UdvzvFt27bF3LlzERYWBiEEPv/8c8TExODAgQPo3r274vOw4iciIrKArYP0jBgxwuTn2bNnY/Hixdi1axcrfnI/aveNKz2fvfrkr5VWYN/B36PkNfLAPX37sK+dbMbRx/I4o8LCQpOfdToddDpdrekNBgNWrlyJkpISREREmHUtVvzk9NSOaqf0fPaIpldpkLFj3yl4+zU3RsmTZRlJS1LQtrknR9dTg3P0KJy2JMs3NmvPAQDBwcEm+2fOnIlZs2ZVS5+eno6IiAiUlpbCz88Pa9asQbdu3cy6Jufxk1NTO6qd0vPZI5qeLAvsSr8Ir0ZNTdbW12g06B0xECWiCZLXpKh+XaIqjh6F09bUXLkvMzMTBQUFxm369Ok1XrNz5844ePAgfv75Zzz33HMYN24cjhw5Yla+OaqfnJbaUe2Unu/YsWPo3LmzzaPp5eSW4kxOaa1xAoQQ+PCdWfg0aQGbXUl1jh6Fs4otR/W/vVqdUf0vPmh5fgcNGoQOHTrgo48+UnwM3/jJaakd1U7p+ZKSkuwSTe+381erLa17s4h+9zNKHjUIR4/CaQ+OsFa/LMsoKysz6xj28ZPTUjuqndLzVUXds3U0PVlo4FnHm5QkSWjRshWyso6qel0iwPGjcNqDDBWm85mRdvr06RgyZAjatWuHoqIiLF++HFu3bsWGDRvMuibf+MlpqR3VTun5qqLu2TqankaSa1wvv4oQAtlZFxgljxqEo0fhdAeXLl3C2LFj0blzZ9x7773Ys2cPNmzYgOjoaLPOwz5+clru1sd/Ka8UZ3LqbtL7YP6r+Oyjd9jHT6pjH3/1a8xbmQ+fRlb28V8rxNTRjW1av/GNn5yW2lHtlJ7Py8vLLtH0mgfoUHatAAZDZbXfybIBGYf2ImboX1jpU4Nw9Cic9uAIffyW4Bs/OT21o9opPZ89oukZDAI/7jkGb/+W0GpvDNGprKzET1vXo2NbfzwQG9Mg1yWq4uhROG35xv/W1+q88b/8kG3f+Fnxk0twt5X7SssqsGd/OnJz8xDgr0MUo+SRDTnyyn22rPjnrsiHt5UVf+m1Qkx7xLYVP0f1k0vQarUYMGCAzc+n9nWV8tZ5Iiqil82vSwTY73vvaGy9Vr9aWPETERFZwNbR+dTCwX1ERERuhG/8LkrtPriia+U4+Msx5OVdhb6RB6LuiXSYPj1AeXlLrldg/6EjyM/Lg7+vR619447ch9kQLmQVYcG7ycjJyUG3Tn6In/IMvLy87J0tI3f7PMg5sKmfHIaa0bOulxmw9/AF6BoFQNe4PVo1bo/ysjLMmvsBenYNxsiRD6ice/MpKW95hYxdh87C26/p71HtQlBZWYnE9/+Dzu0a44EHYs06n6soLqnEmL+txJXCVpCkEAAhOHNZ4Ku1CxEdWYSFb79p7yy61edBzkXIAsLKtnprj7eEWU39CQkJ6N27N/z9/dGyZUvExsbi+PHjdR6zdOlSSJJksnl7e1uVaaqdmtGzysplHDyZB62Xr8l+L50Ow0c+jkO/5tg9GpeS8lYYZOw9egke3qYjZj08PDAgOgbnc2HXqHv2UlEhY9QTqbhSEAhJ+uNPgSRJaNziLmzb3wlTXqo5QpituNPnQWQrZk3nu//++/HII4+gd+/eqKysxIwZM5CRkYEjR47A19e3xmOWLl2KSZMmmfyDIEkSAgMDFWeS0/mUUXtlrd+ySpBztRRaj9obhqbGPYTNG9fZpdlVaXm3pqXj4pUyaOrI45xX4/D18iV2WZHPXtZvvojZ75yoI4XAuWNJOHl4mV2a/Z1lpThyLLaczvfaF3mqTOebObaJ467c9/333+OJJ55A9+7dcdttt2Hp0qU4d+4c9u3bV+dxkiShVatWxq2+Sr+srAyFhYUmG9VPzehZQghczi+vs9IXQuC2O6PsFo1LaXnPXMyvs9IXQuCOPgPtFnXPXj79Yh+EXPva/4CEpkHRSEpKslme/ozR4MjROevKfVaN6i8oKAAANG3atM50xcXFaN++PYKDgxETE4PDhw/XmT4hIQEBAQHGLTg42Jpsug01o2fJMkyaf2siSRKatQi0WzQupeX18NTVeR5JktAiMMhuUffspaBIQNLU/abspWtuvC+2xmhwRA3D4opflmVMnjwZffv2rfXBBIDOnTvjs88+w9q1a7Fs2TLIsozIyEicP3++1mOmT5+OgoIC45aZmWlpNt2KmtGzNBrU8zb4e6vApSy7ReNSWt7K8uuoq0dLCIGcrAt2i7pnLwH+9X/G5aWXjPfF1hgNjhydLAtVNluzeMne5557DuvXr8eOHTvQtm1bxcdVVFSga9euePTRR/HGG28oOoZ9/Mqo3Sd6OusasnOvG9eEr8mUZx/E1h82OHQf/7a0dFy4WgZNHW+3b05/Fqv++4Vb9fH/b2sWXl/wax0pBM4efQ+njnzFPn5yGrbs4//nZ7mq9PG/8VRTx+3jr/L8888jNTUVW7ZsMavSBwBPT0/07NkTJ0+etOTSVAe1o2e1ae4NCBmVldWjwQkhkLziM7wwKc5uf3SVljeoeSMYKspqLIcsy/jxh/V44vGH7BZ1z17+EtUK+kZXIURNb/0yigtO4qHYMLvN52c0OKKGYVbFL4TA888/jzVr1uCHH35AaGio2Rc0GAxIT09n81wDGTlyJFatWoX09HRERkZCr9cjMjISGRkZWLVqlVnznr08NejZqRkqS00HV14rKcbq5R/hrh7t7T6PWkl5PbQS7uoeiIpruZBl2XhsWVkpvv/mK9wSpDOWQ8375+g8tBJWfx6DwMYXIMsVxv1CNuBq9jb8pfdvWDB/rh1z6F6fBzkfZx3cZ1ZTf1xcHJYvX461a9eic+fOxv0BAQHw8fEBAIwdOxZt2rRBQkICAOD1119Hnz590LFjR+Tn5yMxMREpKSnYt28funXrpui6bOo3n9ornZVcr8D+gxm4evUKGvvrEHVPX4d601Ja3uulFdh7IAO5ubkI8POqdQVCd1sp7vKVEiQu/C+ysrPRrZMeU174O1fuI6dky6b+GZ9eVaWpf84zzRw3LK8kSTXuX7JkCZ544gkAwIABAxASEoKlS5cCAF544QUkJycjOzsbTZo0wR133IE333wTPXv2VJxJVvxERKSELSv+6R+rU/En/N22Fb9ZS/Yq+R9h69atJj8vXLgQCxcuNCtTRERE1DC4Vj8REZEFBISiF+L6zmFrrPhdlLv1iRYWl+LbdRuRlXURPp4Cf3vmKYfqoyYi1yPkG4udWXsOW2PF74LcKZpZWYWMjTvS0TIoBGE9+iGsB1BZUYHX532EypIszE2YY+8sEhE5FKuW7CXH407RzCoqZaT9cgFNW5iuJeHh6YnhIx9DYEhPTJ061U65IyJXJ4RQZbM1VvwuxGAwYMqUKRg+fDhSUlLQp08f+Pn5oU+fPkhJScHw4cPx0ksvwWCoe5lWZ3HxynXovBvBo4ZAQhqNBn3734cdu/ajvLzcDrkjIlcnC3U2W2PF70LcLZrZueyCOpcTFkIgeugou0WXIyJyROzjdyHuFs3M09O7zt9LkoTmLVrh14ObbZQjInInQhYQVr6yW3u8JfjG70LcLZpZRUVpnb8XQuBS9gW7RZcjItfmrEv2suJ3IVFRUQgJCcGcOXNM1qQHbgSjSUhIQGhoKKKiouyUQ3W1Dwqoc7yCJEn437pViIuLs2GuiIgcGyt+F+Ju0cxaN/fB9ZLCWqPu/fC/tejftzfn8xNRg5Blocpma6z4XYw7RTPz0GpwT692uHTxN4g/tXCUll7Hyi8/Rt7FI5g3b54dc0hErsxZp/NxcJ8LGjlyJGJiYtxi5T4vDw1i7+uN4pJSJK9dh4sXL8DXW4OEmS/wTZ+IGpSQrV95jyv3kWq0Wi0GDBhg72zYjJ+vN8b+n+u0ZhARNRRW/ERERBaQhYBsZVO9tcdbghU/ERGRBdToo2cfvxNxleh3rlKOgsO/YvfyZOQXF6H5gLvR76/DnLIc9uIq3wMiqh8rfgu4SvQ7VyjHtbMXsPmvT0Nz5DQAoBGAwg9W4lXfF9H7o9kY+cjD9s2gE3CF7wGRPagxHY/T+ZyAq0S/c4VylF3OxQ93xUIc/s1kv4ckIfKaFumPTUHy6tV2yp1zcIXvAZG9OOvKfZKwRweDmQoLCxEQEICCggLo9Xq75cNgMKBjx44IDw9HSkqKSSAcWZYRGxuLjIwMnDhxwqGbSV2lHMf+uRC/zl0MLaRa07zXohLfZf7q0OWwF1f5HhD9mS3qi6pr/OOtC9D5WHeNsuuF+PDlNjat3/jGbwZXiX7nKuX47ZOv6qz0odWgW06Jw5fDXlzle0BkL0IIY6AeizcO7nNsrhL9zlXKIecX1VXtAwYZTeHh8OWwF1f5HhDZi1BhOp89Kn6+8ZvBVaLfuUo5NE3qaRbTanAFlQ5fDntxle8BEZmHFb8ZXCX6nauUo8Nzj0FGHf8tG2QcDvR1+HLYi6t8D4jsxepm/t83W2PFbwZXiX7nKuUIff5xoGVTGGpoKhMAfhJFeO69eQ5fDntxle8Bkb3YuuJPSEhA79694e/vj5YtWyI2NhbHjx83O9+s+M3kKtHvXKEcXk0bI3rvN8CdXSH+9OZfJmRs8TPgzuXvYOSDD9oxh47PFb4HRPYiC3U2pbZt24bx48dj165d2LhxIyoqKnDfffehpKTErHxzOp+FXGWlM1cpR/Fv57Br+WrkFRWieb+70O/++5yyHPbiKt8DIltO53vq9bPw8rbuGuWlhfjsX+2RmZlpkl+dTgedTlfnsZcvX0bLli2xbds29OvXT/E1OarfQq4S/c5VyuF3SzsMevUFe2fDabnK94DIltToo686Pjg42GT/zJkzMWvWrDqPLSgoAAA0bdrUrGuy4iciIrKAmkF6anrjr4ssy5g8eTL69u1b65Tc2rDiJyIisjO9Xm9W18T48eORkZGBHTt2mH0tVvxEDqS8vBxJSUk4deoUOnTogLi4OHh5eVl8PvbdEzUcWbY+yM5NM2kVef7555Gamooff/wRbdu2Nft4VvxEDmLq1KlYtGgRysrKjPumTZuGiRMnYt68eWafj1H3iBqWmk39StNOmDABa9aswdatWxEaGmrRNTmdj8gBTJ06FYmJiYiOjjaZTx8dHY3ExERMnTrVrPMx6h6R6xk/fjyWLVuG5cuXw9/fH9nZ2cjOzsb169fNOg+n8xHZWXl5OfR6PaKjo7F27dpqUfJiYmKwadMmFBQUKGr2Z9Q9cme2nM732IxT8PL2t+pc5aVFWDang6L8SlLN0UmWLFmCJ554QvE1+cZPZGdJSUkoKyvDK6+8UmOUvBkzZqC0tBRJSUmKzseoe0S2YeuV+6q6Fm7ezKn0AVb8RHZ36tQpAPVHyatKVx9G3SOiurDiJ7KzDh06AKg/Sl5Vuvow6h6Rbci4EZbXqq2uQGMNhBU/kZ3FxcVBp9Nh9uzZNUbJmzNnDry9vREXF6fofIy6R2QbjM5HRBbx8vLCxIkTkZqaipiYGJNR+DExMUhNTcWECRMUz+dn1D0i26itz93czdY4j5/IAVTN01+0aBFSU1ON+729vREfH2/2PP6qqHtTpkxBZGSkcX9oaCij7hG5OU7nI3IgXLmPyDq2nM730JRj8NRZN52voqwIXy/oYtP6jW/8RA7Ey8sLkydPVu18jLpH1HDUjM5nS+zjJyIiciN84yciIrKArdfqVwsrfiIiIgsIWYawJLzeTeewNTb1ExERuRG+8RMREVlAlgVkKwfnWXu8JVjxExERWcBZ+/jZ1E9ERORG+MZPRERkAWedx8+Kn4iIyAKs+ImIiNyIDBmysG46ngxO5yMiIqIGxDd+IiIiCwjZ+qZ6KxsMLMKKn4iIyALO2sfPpn4iIiI3wjd+IiIiCzjrAj6s+ImIiCwgyzJkK4PsWHu8JVjxuzmDwYDt27cjKysLQUFBiIqKglartXe2iIiogbDid2PJycmYMmUKzpw5Y9wXEhKCBQsWYOTIkfbLGBGRE3CLwX0JCQno3bs3/P390bJlS8TGxuL48eP1Hrdy5Up06dIF3t7eCA8Px7p16yzOMKkjOTkZo0aNQnh4ONLS0lBUVIS0tDSEh4dj1KhRSE5OtncWiYgcmhCyKputmVXxb9u2DePHj8euXbuwceNGVFRU4L777kNJSUmtx+zcuROPPvoonn76aRw4cACxsbGIjY1FRkaG1ZknyxgMBkyZMgXDhw9HSkoK+vTpAz8/P/Tp0wcpKSkYPnw4XnrpJRgMBntnlYiIVCYJK4YUXr58GS1btsS2bdvQr1+/GtM8/PDDKCkpQWpqqnFfnz59cPvtt+PDDz+s8ZiysjKUlZUZfy4sLERwcDAKCgqg1+stzS79buvWrRg4cCDS0tLQp0+far9PS0tDZGQktmzZggEDBtg+g0REFiosLERAQECD1hdV1xg0Zic8vfysOldFeTE2fRlp0/rNqnn8BQUFAICmTZvWmiYtLQ2DBg0y2Td48GCkpaXVekxCQgICAgKMW3BwsDXZpJtkZWUBAG699dYaf1+1vyodERHV4Pc+fms2OHof/5/JsozJkyejb9++tVYgAJCdnY3AwECTfYGBgcjOzq71mOnTp6OgoMC4ZWZmWppNqkFQUBAA1NrdUrW/Kh0REVUnC1mVzdYsrvjHjx+PjIwMrFixQs38AAB0Oh30er3JRuqJiopCSEgI5syZU20OqSzLSEhIQGhoKKKiouyUQyIiaigWVfzPP/88UlNTsWXLFrRt27bOtK1atUJOTo7JvpycHLRq1cqSS5MKtFotFixYgNTUVMTGxpqM6o+NjUVqairmz5/P+fxERHWwtplfjemAljCr4hdC4Pnnn8eaNWvwww8/IDQ0tN5jIiIisHnzZpN9GzduREREhHk5JVWNHDkSq1atQnp6OiIjI6HX6xEZGYmMjAysWrWK8/iJiOohhAwhW7nZoanfrAV8xo8fj+XLl2Pt2rXw9/c39tMHBATAx8cHADB27Fi0adMGCQkJAIBJkyahf//+WLBgAYYNG4YVK1Zg7969+Pjjj1UuCplr5MiRiImJ4cp9RERuxKyKf/HixQBQbYrXkiVL8MQTTwAAzp07B43mj4aEyMhILF++HK+++ipmzJiBsLAwpKSk1DkgkGxHq9Vyyh4RkQWcdeU+syp+JVP+t27dWm3f6NGjMXr0aHMuRURE5NDUWHnP4VfuIyIiIufGID1EREQWkGVAtrKp3g5ReVnxExERWaJqZL6157A1NvUTERG5Eb7xExERWcAtRvUTERHRDRzVT0RE5EbssWTvjz/+iBEjRqB169aQJAkpKSlm55sVPxERkZMoKSnBbbfdhg8++MDiczhFU3/VwkGFhYV2zgkRETmyqnpCyYJz1qosL7J6VL6hsgRA9fpNp9NBp9NVSz9kyBAMGTLEqms6RcVfVFQEAAgODrZzToiIyBkUFRUhICCgQc7t5eWFVq1aYe/mh1Q5n5+fX7X6bebMmZg1a5Yq57+ZU1T8rVu3RmZmJvz9/SFJkr2zY1RYWIjg4GBkZmZCr9fbOzsWYzkcC8vhWFgOx1JfOYQQKCoqQuvWrRssD97e3jh9+jTKy8tVOZ8QolrdVtPbvlqcouLXaDRo27atvbNRK71e79QPUhWWw7GwHI6F5XAsdZWjod70/8zb2xve3t4Nfp2GwMF9REREboQVPxERkRtxiqZ+R6XT6TBz5swG7YuxBZbDsbAcjoXlcCyuUg5LFRcX4+TJk8afT58+jYMHD6Jp06Zo166donNIwhZzHoiIiMhqW7duxcCBA6vtHzduHJYuXaroHKz4iYiI3Aj7+ImIiNwIK34iIiI3woqfiIjIjbDiJyIiciOs+BWYO3cuJEnC5MmTa02zdOlSSJJksjnCqk6zZs2qlq8uXbrUeczKlSvRpUsXeHt7Izw8HOvWrbNRbmtnbjkc9fMAgAsXLuCxxx5Ds2bN4OPjg/DwcOzdu7fOY7Zu3YpevXpBp9OhY8eOikfvNiRzy7F169Zqn4kkScjOzrZhrk2FhITUmKfx48fXeowjPh/mlsNRnw+DwYB//vOfCA0NhY+PDzp06IA33nij3oA7jvh8ODLO46/Hnj178NFHH6FHjx71ptXr9Th+/LjxZ0eJK9C9e3ds2rTJ+LOHR+0f+86dO/Hoo48iISEBw4cPx/LlyxEbG4v9+/fj1ltvtUV2a2VOOQDH/Dzy8vLQt29fDBw4EOvXr0eLFi1w4sQJNGnSpNZjTp8+jWHDhuEf//gHvvzyS2zevBnPPPMMgoKCMHjwYBvm/g+WlKPK8ePHTZZabdmyZUNmtU579uyBwWAw/pyRkYHo6GiMHj26xvSO+nyYWw7AMZ+Pt956C4sXL8bnn3+O7t27Y+/evXjyyScREBCAiRMn1niMIz4fDk9QrYqKikRYWJjYuHGj6N+/v5g0aVKtaZcsWSICAgJsljelZs6cKW677TbF6R966CExbNgwk3133323ePbZZ1XOmXnMLYejfh4vv/yyuOeee8w6ZurUqaJ79+4m+x5++GExePBgNbNmFkvKsWXLFgFA5OXlNUymVDBp0iTRoUMHIctyjb931OfjZvWVw1Gfj2HDhomnnnrKZN/IkSPFmDFjaj3GEZ8PR8em/jqMHz8ew4YNw6BBgxSlLy4uRvv27REcHIyYmBgcPny4gXOozIkTJ9C6dWvccsstGDNmDM6dO1dr2rS0tGrlHTx4MNLS0ho6m/UypxyAY34e33zzDe68806MHj0aLVu2RM+ePfHJJ5/UeYwjfiaWlKPK7bffjqCgIERHR+Onn35q4JwqV15ejmXLluGpp56q9e3XET+LmykpB+CYz0dkZCQ2b96MX3/9FQBw6NAh7Nixo874887wmTgaVvy1WLFiBfbv34+EhARF6Tt37ozPPvsMa9euxbJlyyDLMiIjI3H+/PkGzmnd7r77bixduhTff/89Fi9ejNOnTyMqKgpFRUU1ps/OzkZgYKDJvsDAQLv2wwLml8NRP4/ffvsNixcvRlhYGDZs2IDnnnsOEydOxOeff17rMbV9JoWFhbh+/XpDZ7lGlpQjKCgIH374IVavXo3Vq1cjODgYAwYMwP79+22Y89qlpKQgPz8fTzzxRK1pHPX5+DMl5XDU52PatGl45JFH0KVLF3h6eqJnz56YPHkyxowZU+sxjvh8ODx7Nzk4onPnzomWLVuKQ4cOGffV19R/s/LyctGhQwfx6quvNkAOLZeXlyf0er349NNPa/y9p6enWL58ucm+Dz74QLRs2dIW2VOsvnLczFE+D09PTxEREWGyb8KECaJPnz61HhMWFibmzJljsu+7774TAMS1a9caJJ/1saQcNenXr5947LHH1Myaxe677z4xfPjwOtM4w/OhpBw3c5Tn46uvvhJt27YVX331lfjll1/EF198IZo2bSqWLl1a6zGO+Hw4Or7x12Dfvn24dOkSevXqBQ8PD3h4eGDbtm1YtGgRPDw8TAbR1Kbqv9U/B1NwBI0bN0anTp1qzVerVq2Qk5Njsi8nJwetWrWyRfYUq68cN3OUzyMoKAjdunUz2de1a9c6uy1q+0z0ej18fHwaJJ/1saQcNbnrrrvs/pkAwNmzZ7Fp0yY888wzdaZz9OdDaTlu5ijPR3x8vPGtPzw8HI8//jheeOGFOlteHfH5cHSs+Gtw7733Ij09HQcPHjRud955J8aMGYODBw9Cq9XWew6DwYD09HQEBQXZIMfKFRcX49SpU7XmKyIiAps3bzbZt3HjRkRERNgie4rVV46bOcrn0bdvX5OR1ADw66+/on379rUe44ifiSXlqMnBgwft/pkAwJIlS9CyZUsMGzasznSO+Fn8mdJy3MxRno9r165BozGtlrRaLWRZrvUYR/9MHJK9mxycxc1N/Y8//riYNm2a8efXXntNbNiwQZw6dUrs27dPPPLII8Lb21scPnzYDrn9w5QpU8TWrVvF6dOnxU8//SQGDRokmjdvLi5duiSEqF6On376SXh4eIj58+eLo0ePipkzZwpPT0+Rnp5uryIIIcwvh6N+Hrt37xYeHh5i9uzZ4sSJE+LLL78UjRo1EsuWLTOmmTZtmnj88ceNP//222+iUaNGIj4+Xhw9elR88MEHQqvViu+//94eRRBCWFaOhQsXipSUFHHixAmRnp4uJk2aJDQajdi0aZM9imBkMBhEu3btxMsvv1ztd87yfAhhXjkc9fkYN26caNOmjUhNTRWnT58WycnJonnz5mLq1KnGNM7wfDg6VvwK3Vzx9+/fX4wbN8748+TJk0W7du2El5eXCAwMFEOHDhX79++3fUZv8vDDD4ugoCDh5eUl2rRpIx5++GFx8uRJ4+9vLocQQnz99deiU6dOwsvLS3Tv3l189913Ns51deaWw1E/DyGE+Pbbb8Wtt94qdDqd6NKli/j4449Nfj9u3DjRv39/k31btmwRt99+u/Dy8hK33HKLWLJkie0yXAtzy/HWW2+JDh06CG9vb9G0aVMxYMAA8cMPP9g419Vt2LBBABDHjx+v9jtneT6EMK8cjvp8FBYWikmTJol27doJb29vccstt4hXXnlFlJWVGdM4y/PhyBiWl4iIyI2wj5+IiMiNsOInIiJyI6z4iYiI3AgrfiIiIjfCip+IiMiNsOInIiJyI6z4iYiI3AgrfiIiIjfCip+IiMiNsOInIiJyI6z4iYiI3Mj/A3ekaGDrUUQOAAAAAElFTkSuQmCC", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "bandwidth = 0.5\n", - "c = CoresetKDE(10, 2, bandwidth)\n", - "c.fit(X_iris)\n", - "coreset_points, coreset_weights = c.get_coreset()\n", - "\n", - "fig, ax = plt.subplots()\n", - "ax.scatter(X_iris[:, 0], X_iris[:, 1], c=\"white\", edgecolor=\"k\")\n", - "sc = ax.scatter(coreset_points[:, 0], coreset_points[:, 1], \n", - " c=coreset_weights,cmap=\"coolwarm\", edgecolor=None, label=f\"Coreset size:{c.sketch.get_num_retained()}\")\n", - "plt.colorbar(sc)\n", - "ax.legend()" - ] - }, - { - "cell_type": "markdown", - "id": "70dbe9d3", - "metadata": {}, - "source": [ - "We can visualise the two estimates as follows. First we defined a test grid over the input domain. Then we will build a coreset and fit the KDE over the coreset." - ] - }, - { - "cell_type": "code", - "execution_count": 34, - "id": "5b08682e", - "metadata": {}, - "outputs": [], - "source": [ - "buffer = 0.5\n", - "x = np.linspace(X_iris[:,0].min()-buffer, X_iris[:,0].max()+buffer, 100)\n", - "y = np.linspace(X_iris[:,1].min()-buffer, X_iris[:,1].max()+buffer, 100)\n", - "X_test, Y_test = np.meshgrid(x, y)\n", - "X_plot = np.c_[X_test.ravel(), Y_test.ravel()]\n", - "\n", - "\n", - "ests = kernel_density(X_iris, X_plot, bandwidth)\n", - "ests = ests.reshape(X_test.shape)\n", - "coreset_ests = c.predict(X_plot).reshape(X_test.shape)" - ] - }, - { - "cell_type": "code", - "execution_count": 35, - "id": "b5eefd9b", - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/var/folders/ts/39plpy691lg3xd9rvzndrmt40000gq/T/ipykernel_20006/3989765740.py:4: UserWarning: No data for colormapping provided via 'c'. Parameters 'cmap' will be ignored\n", - " ax_kde.scatter(X_iris[:, 0], X_iris[:, 1], c=\"white\", cmap=plt.cm.Set1, edgecolor=\"k\")\n" - ] - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "fig, ax = plt.subplots(figsize=(12,4),ncols=2)\n", - "ax_kde, ax_coreset = ax\n", - "ax_kde.contour(X_test, Y_test, ests)\n", - "ax_kde.scatter(X_iris[:, 0], X_iris[:, 1], c=\"white\", cmap=plt.cm.Set1, edgecolor=\"k\") \n", - "ax_coreset.contour(X_test, Y_test, coreset_ests)\n", - "ax_coreset.scatter(X_iris[:, 0], X_iris[:, 1], c=\"white\", edgecolor=\"k\")\n", - "sc = ax_coreset.scatter(coreset_points[:, 0], coreset_points[:, 1], \n", - " c=coreset_weights, cmap=\"coolwarm\", edgecolor=None, label=f\"Coreset size:{c.sketch.get_num_retained()}\")\n", - "plt.colorbar(sc)\n", - "ax_kde.set_title(\"KDE\")\n", - "ax_coreset.set_title(\"Coreset\")\n", - "ax_kde.set_xlabel(\"Sepal length\")\n", - "ax_kde.set_ylabel(\"Sepal width\")\n", - "plt.subplots_adjust(wspace=0, hspace=0)\n", - "\n", - "ax_coreset.get_yaxis().set_visible(False)" - ] - }, - { - "cell_type": "markdown", - "id": "30bc6ee9", - "metadata": {}, - "source": [ - "### Conclusion\n", - "\n", - "**Objective 1**: To understand exactly what function a kernel density estimate is approximating.\n", - "\n", - "We have seen that the KDE is a function evaluated over a finite sample from a distribution. \n", - "In practice this distribution is likely unknown so the KDE may not have the same scale as the distribution but it should resemble the shape of the distribution.\n", - "\n", - "\n", - "**Objective 2**: To understand the parameters that affecct the performance of a KDE.\n", - "\n", - "We have seen that the KDE converges quickly to the convolution function when the sample size increases. \n", - "When we know the distribution from which the data is sampled, we can also test how far the convolution form is from the true distribution and we saw that decreasing the bandwidth while increasing the sample size allows the KDE to approach the true distribution.\n", - "In practice, we will likely not know the distribution from which a fixed size sample is drawn so the bandwidth parameter must be evaluated to choose the best option." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.11.4" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/jupyter/density_sketch/2-density-sketch-visualization.ipynb b/jupyter/density_sketch/2-density-sketch-visualization.ipynb deleted file mode 100644 index 8e4145d4..00000000 --- a/jupyter/density_sketch/2-density-sketch-visualization.ipynb +++ /dev/null @@ -1,543 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "badd26a1", - "metadata": {}, - "source": [ - "# Visualising Species Distribution\n", - "\n", - "This is an example of how coresets can be used to generate the species distribution visualisation from [scikit-learn](https://scikit-learn.org/stable/auto_examples/neighbors/plot_species_kde.html#sphx-glr-auto-examples-neighbors-plot-species-kde-py).\n", - "Much of this code has been lifted from the relevant sklearn page and then adapted for use with a coreset." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "0624fa23", - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "from sklearn.datasets import fetch_species_distributions\n", - "from sklearn.metrics.pairwise import rbf_kernel\n", - "from sklearn.neighbors import KernelDensity\n", - "from datasketches import density_sketch\n", - "%matplotlib inline\n", - "# if basemap is available, we'll use it.\n", - "# otherwise, we'll improvise later...\n", - "try:\n", - " from mpl_toolkits.basemap import Basemap\n", - "\n", - " basemap = True\n", - "except ImportError:\n", - " basemap = False" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "66a143b3-dca2-435e-aa7f-0f0bca3bfa25", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "ff796ec0", - "metadata": {}, - "outputs": [], - "source": [ - "def construct_grids(batch):\n", - " \"\"\"Construct the map grid from the batch object\n", - "\n", - " Parameters\n", - " ----------\n", - " batch : Batch object\n", - " The object returned by :func:`fetch_species_distributions`\n", - "\n", - " Returns\n", - " -------\n", - " (xgrid, ygrid) : 1-D arrays\n", - " The grid corresponding to the values in batch.coverages\n", - " \"\"\"\n", - " # x,y coordinates for corner cells\n", - " xmin = batch.x_left_lower_corner + batch.grid_size\n", - " xmax = xmin + (batch.Nx * batch.grid_size)\n", - " ymin = batch.y_left_lower_corner + batch.grid_size\n", - " ymax = ymin + (batch.Ny * batch.grid_size)\n", - "\n", - " # x coordinates of the grid cells\n", - " xgrid = np.arange(xmin, xmax, batch.grid_size)\n", - " # y coordinates of the grid cells\n", - " ygrid = np.arange(ymin, ymax, batch.grid_size)\n", - "\n", - " return (xgrid, ygrid)" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "730603b1", - "metadata": {}, - "outputs": [], - "source": [ - "# Get matrices/arrays of species IDs and locations\n", - "# if fetch_species_distributions() call does not work you may need \n", - "# import ssl\n", - "# ssl._create_default_https_context = ssl._create_unverified_context\n", - "\n", - "data = fetch_species_distributions()\n", - "species_names = [\"Bradypus Variegatus\", \"Microryzomys Minutus\"]\n", - "\n", - "Xtrain = np.vstack([data[\"train\"][\"dd lat\"], data[\"train\"][\"dd long\"]]).T\n", - "ytrain = np.array(\n", - " [d.decode(\"ascii\").startswith(\"micro\") for d in data[\"train\"][\"species\"]],\n", - " dtype=\"int\",\n", - ")\n", - "Xtrain *= np.pi / 180.0 # Convert lat/long to radians" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "df7329d2", - "metadata": {}, - "outputs": [], - "source": [ - "# Set up the data grid for the contour plot\n", - "xgrid, ygrid = construct_grids(data)\n", - "X, Y = np.meshgrid(xgrid[::5], ygrid[::5][::-1])\n", - "land_reference = data.coverages[6][::5, ::5]\n", - "land_mask = (land_reference > -9999).ravel()\n", - "\n", - "xy = np.vstack([Y.ravel(), X.ravel()]).T\n", - "xy = xy[land_mask]\n", - "xy *= np.pi / 180.0" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "16348ec1", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " - computing KDE in spherical coordinates\n", - " - plot coastlines from coverage\n", - " - computing KDE in spherical coordinates\n", - " - plot coastlines from coverage\n" - ] - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# Plot map of South America with distributions of each species\n", - "fig = plt.figure()\n", - "fig.subplots_adjust(left=0.05, right=0.95, wspace=0.05)\n", - "\n", - "for i in range(2):\n", - " plt.subplot(1, 2, i + 1)\n", - "\n", - " # construct a kernel density estimate of the distribution\n", - " print(\" - computing KDE in spherical coordinates\")\n", - " kde = KernelDensity(\n", - " bandwidth=0.04, metric=\"haversine\", kernel=\"gaussian\", algorithm=\"ball_tree\"\n", - " )\n", - " kde.fit(Xtrain[ytrain == i])\n", - "\n", - " # evaluate only on the land: -9999 indicates ocean\n", - " Z = np.full(land_mask.shape[0], -9999, dtype=\"int\")\n", - " Z[land_mask] = np.exp(kde.score_samples(xy))\n", - " Z = Z.reshape(X.shape)\n", - "\n", - " # plot contours of the density\n", - " levels = np.linspace(0, Z.max(), 25)\n", - " plt.contourf(X, Y, Z, levels=levels, cmap=plt.cm.Reds)\n", - "\n", - " if basemap:\n", - " print(\" - plot coastlines using basemap\")\n", - " m = Basemap(\n", - " projection=\"cyl\",\n", - " llcrnrlat=Y.min(),\n", - " urcrnrlat=Y.max(),\n", - " llcrnrlon=X.min(),\n", - " urcrnrlon=X.max(),\n", - " resolution=\"c\",\n", - " )\n", - " m.drawcoastlines()\n", - " m.drawcountries()\n", - " else:\n", - " print(\" - plot coastlines from coverage\")\n", - " plt.contour(\n", - " X, Y, land_reference, levels=[-9998], colors=\"k\", linestyles=\"solid\"\n", - " )\n", - " plt.xticks([])\n", - " plt.yticks([])\n", - "\n", - " plt.title(species_names[i])" - ] - }, - { - "cell_type": "markdown", - "id": "7b84aedb", - "metadata": {}, - "source": [ - "This method uses the Haversine distance. We only have implemented the Euclidean distance so will use Euclidean distance for comparisons." - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "4442f401", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " - computing KDE in spherical coordinates\n", - " - plot coastlines from coverage\n", - " - computing KDE in spherical coordinates\n", - " - plot coastlines from coverage\n" - ] - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# Plot map of South America with distributions of each species\n", - "fig = plt.figure()\n", - "fig.subplots_adjust(left=0.05, right=0.95, wspace=0.05)\n", - "\n", - "for i in range(2):\n", - " plt.subplot(1, 2, i + 1)\n", - "\n", - " # construct a kernel density estimate of the distribution\n", - " print(\" - computing KDE in spherical coordinates\")\n", - " kde = KernelDensity(\n", - " bandwidth=0.04, metric=\"euclidean\", kernel=\"gaussian\", algorithm=\"ball_tree\"\n", - " )\n", - " kde.fit(Xtrain[ytrain == i])\n", - "\n", - " # evaluate only on the land: -9999 indicates ocean\n", - " Z = np.full(land_mask.shape[0], -9999, dtype=\"int\")\n", - " Z[land_mask] = np.exp(kde.score_samples(xy))\n", - " Z = Z.reshape(X.shape)\n", - "\n", - " # plot contours of the density\n", - " levels = np.linspace(0, Z.max(), 25)\n", - " plt.contourf(X, Y, Z, levels=levels, cmap=plt.cm.Blues)\n", - "\n", - " if basemap:\n", - " print(\" - plot coastlines using basemap\")\n", - " m = Basemap(\n", - " projection=\"cyl\",\n", - " llcrnrlat=Y.min(),\n", - " urcrnrlat=Y.max(),\n", - " llcrnrlon=X.min(),\n", - " urcrnrlon=X.max(),\n", - " resolution=\"c\",\n", - " )\n", - " m.drawcoastlines()\n", - " m.drawcountries()\n", - " else:\n", - " print(\" - plot coastlines from coverage\")\n", - " plt.contour(\n", - " X, Y, land_reference, levels=[-9998], colors=\"k\", linestyles=\"solid\"\n", - " )\n", - " plt.xticks([])\n", - " plt.yticks([])\n", - "\n", - " plt.title(species_names[i])" - ] - }, - { - "cell_type": "markdown", - "id": "109b8027", - "metadata": {}, - "source": [ - "Now we will define our own kernel function so that we can check the density sketch properly. The scikit-learn implementation uses a kernel defined as:\n", - "\\begin{align}\n", - "\\hat{f}(x^*) = \\frac{1}{2 \\pi^{d/2} h^d} \\cdot \\frac1n \\sum_{i=1}^n K\\left( -\\frac{||x^* - x_i ||^2}{2 h^2} \\right).\n", - "\\end{align}\n", - "\n", - "However, they actually use a tree-based implementation so that points far away from the test points are grouped by leaf to give a common contribution to the sum which reduces the total number of evaluations in the summation.\n", - "Unlike the tree-based implementation, this coreset implementation evaluates the full sum over the retained points." - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "4cb9e222", - "metadata": {}, - "outputs": [], - "source": [ - "def kernel_density(Xtrain, Xtest, bandwidth=1.):\n", - " \"\"\"\n", - " Returns the kernel density estimate between Xtrain and Xtest.\n", - " returns:\n", - " (1/n)*(1/bandwidth*sqrt(2pi))\\sum_{i=1}^n K( (x* - x_i) / bandwidth )\n", - " The bandwidth in scipy is in the numerator so we use 1./bandwidth\n", - " The mean function picks up the 1/n factor.\n", - " \"\"\"\n", - " for x in [Xtrain, Xtest]:\n", - " if x.ndim == 1:\n", - " x.reshape(-1, 1)\n", - " assert Xtrain.shape[1] == Xtest.shape[1] \n", - " d = Xtest.shape[1]\n", - " g = (1./bandwidth)**2\n", - " K = rbf_kernel(Xtrain, Xtest, gamma=0.5*g)\n", - " K /= (bandwidth*np.sqrt(2.*np.pi))**d\n", - " return np.mean(K, axis=0)" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "9b6dc25a", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " - computing KDE in spherical coordinates\n", - " - plot coastlines from coverage\n", - " - computing KDE in spherical coordinates\n", - " - plot coastlines from coverage\n" - ] - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# Plot map of South America with distributions of each species\n", - "fig = plt.figure()\n", - "fig.subplots_adjust(left=0.05, right=0.95, wspace=0.05)\n", - "\n", - "for i in range(2):\n", - " plt.subplot(1, 2, i + 1)\n", - "\n", - " # construct a kernel density estimate of the distribution\n", - " print(\" - computing KDE in spherical coordinates\")\n", - " kde = KernelDensity(\n", - " bandwidth=0.04, metric=\"euclidean\", kernel=\"gaussian\", algorithm=\"ball_tree\"\n", - " )\n", - " kde.fit(Xtrain[ytrain == i])\n", - " \n", - " my_kde = kernel_density(Xtrain[ytrain == i], xy, bandwidth=0.04)\n", - "\n", - " # evaluate only on the land: -9999 indicates ocean\n", - " Z = np.full(land_mask.shape[0], -9999, dtype=\"int\")\n", - " Z[land_mask] = my_kde \n", - " Z = Z.reshape(X.shape)\n", - "\n", - " # plot contours of the density\n", - " levels = np.linspace(0, Z.max(), 25)\n", - " plt.contourf(X, Y, Z, levels=levels, cmap=plt.cm.Blues)\n", - "\n", - " if basemap:\n", - " print(\" - plot coastlines using basemap\")\n", - " m = Basemap(\n", - " projection=\"cyl\",\n", - " llcrnrlat=Y.min(),\n", - " urcrnrlat=Y.max(),\n", - " llcrnrlon=X.min(),\n", - " urcrnrlon=X.max(),\n", - " resolution=\"c\",\n", - " )\n", - " m.drawcoastlines()\n", - " m.drawcountries()\n", - " else:\n", - " print(\" - plot coastlines from coverage\")\n", - " plt.contour(\n", - " X, Y, land_reference, levels=[-9998], colors=\"k\", linestyles=\"solid\"\n", - " )\n", - " plt.xticks([])\n", - " plt.yticks([])\n", - "\n", - " plt.title(species_names[i])" - ] - }, - { - "cell_type": "markdown", - "id": "766d889f", - "metadata": {}, - "source": [ - "This looks almost identical to the sklearn implementation. Now let's use a coreset and compare the two." - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "13f60986", - "metadata": {}, - "outputs": [], - "source": [ - "class CoresetKDE:\n", - " def __init__(self, k_, dim_, bandwidth_=1):\n", - " self.k = k_\n", - " self.dim = dim_\n", - " self.bandwidth = bandwidth_\n", - " self.normalisation_factor = np.sqrt(2.)*self.bandwidth\n", - " self.estimation_scale_factor = 1./(self.bandwidth*np.sqrt(2.*np.pi))**self.dim\n", - " self.sketch = density_sketch(self.k, self.dim)\n", - " \n", - " def fit(self, X_):\n", - " \"\"\"Fits the coreset to the data\"\"\"\n", - " for x_ in X_:\n", - " self.sketch.update(x_ / self.normalisation_factor)\n", - " \n", - " def predict(self, X):\n", - " \"\"\"Returns density estimates over array X\"\"\"\n", - " predictions = np.zeros((len(X)), dtype=X.dtype)\n", - " for i, x in enumerate(X):\n", - " predictions[i] = self.estimation_scale_factor*self.sketch.get_estimate( x / self.normalisation_factor)\n", - " return predictions\n", - " \n", - " def get_coreset(self):\n", - " \"\"\"Returns the weighted coreset\"\"\"\n", - " samples_weights = [pw for pw in self.sketch]\n", - " samples = np.zeros((self.sketch.get_num_retained(), self.dim))\n", - " weights = np.zeros((self.sketch.get_num_retained(),))\n", - " for i, pw in enumerate(self.sketch):\n", - " samples[i] = pw[0]\n", - " weights[i] = pw[1]\n", - " return samples*self.normalisation_factor, weights" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "8de799c7", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Coreset size: 81 of 926\n", - " - plot coastlines from coverage\n", - "Coreset size: 90 of 698\n", - " - plot coastlines from coverage\n" - ] - }, - { - "data": { - "image/png": "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DZVghVsleHh4aH0zFRkZiVOnTskFa9y4cdi4cSNMTU0FJyMidSusTe7u7lrfTF2/fh0nT56En58fgIItvX799VeYmZkJTkYVCRsqUookSXBwcEBycjIAoHfv3vD29mYzRUTC9evXT14cuXv37tiyZQubKdI4zqEipRU2UxMmTICfnx8qVaokOBERUcECpEDBhs4BAQGwsLAQnIgqIjZUpLIffviBE9CJSOssW7aME9BJGDZUWiI1NVV0hJfS9nxEVD60/W8/PT0dCoVCdAwiNlSitWnTBkDBwnOurq6IjY0VnKhAWFgY7O3t8d577+G9995Du3btAAB16tTBG2+8ITYcEZW7wtrk4uICFxcX3Lt3T3CiAufOnYODg4Ncm9q2bQuFQoGaNWuievXqouNRBcaGSrB9+/ahQYMGSEpKgp+fH37//XfRkQAUXDIdHByMiIgIRERE4MGDB6hatSp8fX3lzUaJSH/99ttvePvtt/HPP//A399faxbH3LRpE4KCguTadP/+fVhbW+PYsWOciE5C8V9GwRo2bIjr16+jSZMmePz4MfLz8zWeQZIk7N+/Xx4dy8nJwdGjRwEAAwcOxNixYwEA7733HmrUqKHxfESkefXr10dkZCRatmyJ+Ph4YbXp0KFDuH//PoCCpRwKP3S6urpiwoQJAABbW1vUrFlT4/mI/o0NlRawsrJC3759hW0/c+7cOQwbNqzY7b169cLOnTuFXTFz79493Lx5U6WfMTExQY8ePXgFIpEaWFpaom/fvsK2n7l69SoGDx5c7HZbW1vs2bMHVapUEZAKePDgAaKjo1X6GWNjY/To0QPm5ubllIpEY0NF8nIIADBmzBgAQIMGDTB//nxhzdS+ffswcuTI1/pU/M477+DUqVOcT0Gk40qqTfXq1cP8+fOFNVOHDx/GkCFD5IVPVdGqVSsEBQWhVq1a5ZCMRGNDRbJOnTphx44domPgzp07cjPVrFkzlS6DvnPnDq5fv47x48fD19e3HFMSkaa88847WlGbYmNj5WaqadOmsLKyUvpn7927h+joaIwdO1bebYL0CxsqLfP8+XNhr33p0iV4enpi586dwj79AUB0dDTy8/PRokULREVFwcjISOmfPXHiBPr27Ytjx47B0dERPj4+HKkiUgORten69etwc3PD7t27VWpi1O2vv/5CXl4eGjdujOjoaJUu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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# Plot map of South America with distributions of each species\n", - "fig = plt.figure()\n", - "fig.subplots_adjust(left=0.05, right=0.95, wspace=0.05)\n", - "\n", - "for i in range(2):\n", - " plt.subplot(1, 2, i + 1)\n", - "\n", - " # construct a kernel density estimate of the distribution using the coreset.\n", - " c = CoresetKDE(16, 2, bandwidth_=0.04)\n", - " c.fit(Xtrain[ytrain==i])\n", - " c_ests = c.predict(xy)\n", - " print(f\"Coreset size: {c.sketch.get_num_retained()} of {c.sketch.get_n()}\")\n", - " #coreset_points, coreset_weights = c.get_coreset()\n", - " # evaluate only on the land: -9999 indicates ocean\n", - " Z = np.full(land_mask.shape[0], -9999, dtype=\"int\")\n", - " Z[land_mask] = c_ests \n", - " Z = Z.reshape(X.shape)\n", - "\n", - " # plot contours of the density\n", - " levels = np.linspace(0, Z.max(), 25)\n", - " plt.contourf(X, Y, Z, levels=levels, cmap=plt.cm.Blues)\n", - "\n", - " if basemap:\n", - " print(\" - plot coastlines using basemap\")\n", - " m = Basemap(\n", - " projection=\"cyl\",\n", - " llcrnrlat=Y.min(),\n", - " urcrnrlat=Y.max(),\n", - " llcrnrlon=X.min(),\n", - " urcrnrlon=X.max(),\n", - " resolution=\"c\",\n", - " )\n", - " m.drawcoastlines()\n", - " m.drawcountries()\n", - " else:\n", - " print(\" - plot coastlines from coverage\")\n", - " plt.contour(\n", - " X, Y, land_reference, levels=[-9998], colors=\"k\", linestyles=\"solid\"\n", - " )\n", - " plt.xticks([])\n", - " plt.yticks([])\n", - "\n", - " plt.title(species_names[i])" - ] - }, - { - "cell_type": "markdown", - "id": "a49eec84", - "metadata": {}, - "source": [ - "The coreset is very similar to the brute force approach but is evaluated over many fewer points." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.11.4" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/jupyter/density_sketch/coreset_naive_bayes.ipynb b/jupyter/density_sketch/coreset_naive_bayes.ipynb deleted file mode 100644 index 2dbe61ed..00000000 --- a/jupyter/density_sketch/coreset_naive_bayes.ipynb +++ /dev/null @@ -1,302 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "180d8095-f241-4752-8780-182d9fec5e83", - "metadata": {}, - "source": [ - "# Naive Bayes Models with Coresets\n", - "\n", - "**Objective.** We show how to use coresets in place of a full Naive Bayes model. The coreset idea build upon using kernel density estimation for Naive Bayes models as outlined [here](https://arxiv.org/pdf/1302.4964.pdf) under \"flex Bayes\"." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "82e7db28-ecce-420b-b29e-57f9264df851", - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "from sklearn.naive_bayes import GaussianNB\n", - "from sklearn.metrics import accuracy_score\n", - "from scipy.stats import norm\n", - "from sklearn.neighbors import KernelDensity\n", - "import matplotlib.pyplot as plt\n", - "from datasketches import density_sketch\n", - "%matplotlib inline" - ] - }, - { - "cell_type": "markdown", - "id": "2d214482-de94-4ad5-8985-41771c3754f3", - "metadata": {}, - "source": [ - "## 1. Kernel Density Functions\n", - "First, we show how to define the kernel functions. The tutorial will only use a Gaussian kernel that is explicitly define here. This is so that the function below can be changed and compared with scikit-learn's implementations of kernel density functions." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "045401f8-3855-45e4-a537-6cba8e2fdeb8", - "metadata": {}, - "outputs": [], - "source": [ - "from scipy.spatial.distance import cdist\n", - "from scipy.stats import multivariate_normal\n", - "from sklearn.neighbors import KernelDensity\n", - "from sklearn.datasets import make_blobs" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "b85a794f-fe74-492b-b05b-a749b9700a8b", - "metadata": {}, - "outputs": [], - "source": [ - "def kernel_density(Xtrain, Xtest, bandwidth=1.):\n", - " \"\"\"\n", - " Returns the kernel density estimate between Xtrain and Xtest.\n", - " returns:\n", - " (1/n)*(1/bandwidth*sqrt(2pi))^d*sum_{i=1}^n K( (x* - x_i) / bandwidth )\n", - " The bandwidth in scipy is in the numerator so we use 1./bandwidth\n", - " The mean function picks up the 1/n factor.\n", - " \"\"\"\n", - " for x in [Xtrain, Xtest]:\n", - " if x.ndim == 1:\n", - " x.reshape(-1, 1)\n", - " g = (1./bandwidth)**2\n", - " K = np.exp(-cdist(Xtrain, Xtest, metric='sqeuclidean')*g/2)\n", - " K *= 1./(bandwidth*np.sqrt(2*np.pi))**Xtrain.shape[1]\n", - " return np.mean(K, axis=0)" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "18da8990-0e44-451c-b178-4f181d22e076", - "metadata": {}, - "outputs": [], - "source": [ - "def test_kernel_density():\n", - " # Generate random data\n", - " np.random.seed(0)\n", - " X, _ = make_blobs(n_samples=1000, centers=3, n_features=2, random_state=0)\n", - "\n", - " # Calculate true densities using scipy's multivariate_normal\n", - " true_densities = multivariate_normal.pdf(X, mean=X.mean(axis=0), cov=X.var(axis=0))\n", - "\n", - " # Calculate estimated densities using your function\n", - " estimated_densities = kernel_density(X, X, bandwidth=1.)\n", - "\n", - " # Check that the estimated densities are close to the true densities\n", - " assert np.allclose(estimated_densities, true_densities, atol=0.05)\n", - "\n", - " # Check that your function gives the same results as sklearn's KernelDensity\n", - " kde = KernelDensity(bandwidth=1., kernel='gaussian').fit(X)\n", - " estimated_densities_sklearn = np.exp(kde.score_samples(X))\n", - " assert np.allclose(estimated_densities, estimated_densities_sklearn, atol=0.05)\n", - "test_kernel_density()" - ] - }, - { - "cell_type": "markdown", - "id": "58e61f7b-1595-470a-8d1d-7bca2e660015", - "metadata": {}, - "source": [ - "We will only use coresets with the default Gaussian kernel. \n", - "This can be changed, however the above two cells show how to define an appropriately scaled kernel function for cross-checking with scikit-learn.\n", - "Without checking, the functions can disagree due to different scaling parameters.\n", - "\n", - "## 2. Naive Bayes Model\n", - "We define a `NaiveBayes` class in a similar way to the scikit-learn API. The kernel function is set to a default of the Gaussian kernel and is unused but is included in the implementation for consistency with scikit-learn. The class accepts a flag for the `coreset` variable which runs the standard Naive Bayesian model with Gaussian kernel when `False`. If `coreset == True`, then instead a one-dimensional coreset is generated for every feature-label pair. Every coreset keeps a weighted sample of points in that column, for that class label, rather than keeping all of the points." - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "2ca0ff91-4184-47e5-a81a-b929687807a7", - "metadata": {}, - "outputs": [], - "source": [ - "class NaiveBayes:\n", - " def __init__(self, kernel='gaussian', bandwidth=1.0, coreset=False, coreset_k=None, coreset_dim=None):\n", - " self.kernel = kernel\n", - " self.bandwidth = bandwidth\n", - " self.class_priors = None\n", - " self.class_kdes = None\n", - " self.using_coreset = coreset\n", - " if self.using_coreset:\n", - " self.class_coresets = {}\n", - " self.k = coreset_k\n", - " self.d = coreset_dim\n", - "\n", - " def fit(self, X, y):\n", - " self.X = X\n", - " self.y = y\n", - " self.class_priors = {}\n", - " self.class_kdes = {}\n", - "\n", - " for c in np.unique(y):\n", - " X_c = X[y == c]\n", - " self.class_priors[c] = len(X_c) / len(X)\n", - " self.class_kdes[c] = []\n", - "\n", - " if self.using_coreset:\n", - " self.class_coresets[c] = []\n", - " # if using a different kernel then it should be specified here. \n", - " coreset = density_sketch(self.k, 1)\n", - " for i in range(X.shape[1]):\n", - " # perform 1d density estimation over every feature \n", - " for sample in X_c[:, i]:\n", - " coreset.update([sample / self.bandwidth] )\n", - " self.class_coresets[c].append(coreset)\n", - "\n", - " def predict_proba(self, X):\n", - " posteriors = []\n", - " for i in range(X.shape[0]):\n", - " likelihoods = []\n", - " for c in self.class_priors:\n", - " likelihood = self.class_priors[c]\n", - " if self.using_coreset:\n", - " kde = 1.\n", - " for j in range(X.shape[1]):\n", - " kde *= self.class_coresets[c][j].get_estimate([X[i, j] / self.bandwidth])\n", - " else:\n", - " # if using a different kernel then the kernel_density function here would need changing \n", - " # and should be checked against scikit-learn as in Section 1.\n", - " kde = kernel_density(self.X[self.y == c], X[i, :].reshape(1,-1), self.bandwidth)[0]\n", - " likelihoods.append(likelihood*kde)\n", - " posterior = likelihoods / np.sum(likelihoods)\n", - " posteriors.append(posterior)\n", - " return np.array(posteriors)\n", - "\n", - " def predict(self, X):\n", - " posteriors = self.predict_proba(X)\n", - " return np.argmax(posteriors, axis=1)\n" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "15f77ced-e0c9-441d-999b-90c753aa187c", - "metadata": {}, - "outputs": [], - "source": [ - "def main():\n", - " np.random.seed(4223452)\n", - "\n", - " # Generate some random data\n", - " n_sample = 200\n", - " X = np.concatenate([np.random.normal(0, 1, size=(n_sample, 2)), np.random.normal(2, 1, size=(n_sample, 2))], axis=0)\n", - " y = np.concatenate([np.zeros(n_sample), np.ones(n_sample)], axis=0)\n", - " \n", - " # Split the data into training and testing sets\n", - " indices = np.random.permutation(X.shape[0])\n", - " train_indices, test_indices = indices[:int(0.8 * X.shape[0])], indices[int(0.8 * X.shape[0]):]\n", - " X_train, y_train = X[train_indices], y[train_indices]\n", - " X_test, y_test = X[test_indices], y[test_indices]\n", - " \n", - " # Train and test the Naive Bayes classifier with Gaussian kernel\n", - " nb = NaiveBayes()\n", - " nb.fit(X_train, y_train)\n", - " y_pred = nb.predict(X_test)\n", - " print(f\"Custom Naive Bayes Accuracy: {accuracy_score(y_test, y_pred)}\")\n", - " \n", - " # Train and test the Naive Bayes classifier using a coreset\n", - " nbc = NaiveBayes(coreset=True, coreset_k=8, coreset_dim=X.shape[1])\n", - " nbc.fit(X_train, y_train)\n", - " y_pred = nbc.predict(X_test)\n", - " print(f\"Coreset Naive Bayes Accuracy: {accuracy_score(y_test, y_pred)}\")\n", - " \n", - " # Train and test the Sklearn Naive Bayes classifier as a check.\n", - " gnb = GaussianNB()\n", - " gnb.fit(X_train, y_train)\n", - " y_pred = gnb.predict(X_test)\n", - " print(f\"Sklearn Naive Bayes Accuracy: {accuracy_score(y_test, y_pred)}\")\n", - " \n", - " fig, ax = plt.subplots()\n", - " fig.suptitle(\"Coreset Naive Bayes\")\n", - " buffer = 0.5\n", - " x = np.linspace(X_train[:, 0].min() - buffer, X_train[:, 0].max() + buffer, 200)\n", - " y = np.linspace(X_train[:, 1].min() - buffer, X_train[:, 1].max() + buffer, 200)\n", - " X_plot, Y_plot = np.meshgrid(x, y)\n", - " X_plot_2d = np.c_[X_plot.ravel(), Y_plot.ravel()]\n", - " plot_preds = nbc.predict(X_plot_2d)\n", - " plot_preds.reshape(X_plot.shape)\n", - " ax.scatter(X_plot, Y_plot, c=plot_preds, alpha=0.01)#0875)\n", - " \n", - " # plot the markers on top of the color background\n", - " ax.scatter(X_train[:, 0], X_train[:, 1], c=y_train, marker='d', alpha=1., edgecolor=\"black\", label='Training data')\n", - " ax.scatter(X_test[:, 0], X_test[:, 1], c=\"white\", edgecolor=\"black\", marker='o', label='Test data')\n", - " x_star = np.array([5, -2])[np.newaxis, :]\n", - " print(\"Predicting point x* = : \", x_star)\n", - " print(\"Predicted class for x*: \", nbc.predict(x_star))\n", - " ax.legend()" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "bfc32a0a-e15e-4d2a-b2ea-9011e4643dab", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Custom Naive Bayes Accuracy: 0.9\n", - "Coreset Naive Bayes Accuracy: 0.8875\n", - "Sklearn Naive Bayes Accuracy: 0.9\n", - "Predicting point x* = : [[ 5 -2]]\n", - "Predicted class for x*: [1]\n" - ] - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAiUAAAHNCAYAAADBkguZAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/SrBM8AAAACXBIWXMAAA9hAAAPYQGoP6dpAAEAAElEQVR4nOydd5xdRf3+3zPn7m7qptECBIKAyk+qgEAwAiKIEKRIERCIIiJSFaSEnkACghTpHb5Ih9CbKKBIgoIQilQxAcQQIEBCsnvLOTO/P+bMvZ8799zdTUiTnOf1urv3njNn5pmZZ9pnylHWWkuOHDly5MiRI8dihl7cBHLkyJEjR44cOSDvlOTIkSNHjhw5lhDknZIcOXLkyJEjxxKBvFOSI0eOHDly5FgikHdKcuTIkSNHjhxLBPJOSY4cOXLkyJFjiUDeKcmRI0eOHDlyLBHIOyU5cuTIkSNHjiUCeackR44cOXLkyLFEIO+U5MiRY7Fg9OjRDB8+fHHTyJEjxxKEvFOSI0eAt956i4MOOogvfelL9OrVi/b2djbffHMuuOACOjs7Fze9z4WOjg5OPfVUnnjiiR65f+KJJ1BKoZTiH//4R8P90aNH069fvwXMcuFi9OjR1TgppSgUCgwbNowf/vCHvPLKK4ubXo4cSzUKi5tAjhxLEh544AF233132tra2G+//Vh77bUpl8v89a9/5de//jX//Oc/ueKKKxY3zflGR0cHp512GgBbbrnlPD176qmnct999y0wLldeeSXGmAXm37ygra2Nq666CoA4jnnrrbe47LLLePjhh3nllVdYccUVFwuvHDmWduSdkhw5UkydOpUf/vCHrLrqqjz22GMMHTq0eu+QQw7hX//6Fw888MDnDsdaS7FYpHfv3p/br0WF9ddfn/vvv5/nnnuOr3/96wvEz5aWlgXiz/ygUCjwox/9qO7apptuyqhRo3jggQc48MADFxOzHDmWbuTTNzlypPjNb37DnDlzuPrqq+s6JB5rrLEGRxxxRPV3HMeMGzeO1Vdfnba2NoYPH86YMWMolUp1zw0fPpxRo0bxyCOPsNFGG9G7d28uv/xyAD799FOOPPJIhg0bRltbG2ussQZnnXVWgwXhlltuYcMNN6R///60t7ezzjrrcMEFF9S56c6vadOmseyyywJw2mmnVacvTj311G7T5rDDDmPQoEE9cnvPPfewww47sOKKK9LW1sbqq6/OuHHjSJKkzp1cU1KpVBg8eDA//vGPG/ybPXs2vXr14uijj65eK5VKnHLKKayxxhq0tbUxbNgwjjnmmIa0nxessMIKgOuweHz88cccffTRrLPOOvTr14/29na+973v8cILL1TdzJkzh759+9Zpw+M///kPURQxYcKE6rUFmec5cnzhYHPkyGGttXallVayX/rSl3rsfv/997eA3W233ezFF19s99tvPwvYnXfeuc7dqquuatdYYw07aNAge9xxx9nLLrvMPv7443bu3Ll23XXXtUOGDLFjxoyxl112md1vv/2sUsoeccQR1ef/8Ic/WMBuvfXW9uKLL7YXX3yxPfTQQ+3uu+9eddMTv+bMmWMvvfRSC9hddtnF3nDDDfaGG26wL7zwQtM4Pv744xawt99+ux07dqwF7D/+8Y+6NOjbt2/dMzvvvLPdY4897Nlnn20vvfRSu/vuu1vAHn300Q3pt+qqq1Z//+QnP7EDBw60pVKpzt31119vAfvMM89Ya61NksRuu+22tk+fPvbII4+0l19+uT300ENtoVCwO+20U9O4hJw//PBD++GHH9r333/fTpo0yY4cOdIOGTLEfvDBB1W3zzzzjF199dXtcccdZy+//HI7duxYu9JKK9kBAwbY9957r+pun332scsvv7yN47gurN/85jdWKWXffvtta23P8snanuV5jhxfROSdkhw5rLWzZs2yQI8aNWutnTJligXsT3/607rrRx99tAXsY489Vr226qqrWsA+/PDDdW7HjRtn+/bta994442668cdd5yNosi+88471lprjzjiCNve3t7Q4M2PXx9++KEF7CmnnNKjeMpOyaeffmoHDRpkv//971fvZ3VKOjo6Gvw56KCDbJ8+fWyxWKx7VnZKHnnkEQvY++67r+7Z7bffvq6zeMMNN1ittX3yySfr3F122WUWsE899VSXcfKdyfCz0kor1XW4rLW2WCzaJEnqrk2dOtW2tbXZsWPHNnB/6KGH6tyuu+66dosttqj+XpB5niPHFxH59E2OHLgpAoD+/fv3yP2DDz4IwK9+9au660cddRRAw9qT1VZbje9+97t1126//XZGjhzJoEGD+Oijj6qf73znOyRJwl/+8hcABg4cyNy5c3n00Ueb8umpX58HAwYM4Mgjj+Tee+/l+eefb+pOrpX57LPP+Oijjxg5ciQdHR289tprTZ/79re/zTLLLMOtt95avfbJJ5/w6KOPsueee1av3X777ay11lp89atfrYvrt7/9bQAef/zxbuPSq1cvHn30UR599FEeeeQRLr/8cvr168f222/PG2+8UXXX1taG1q6aTJKEmTNn0q9fP77yla/w3HPPVd195zvfYcUVV+TGG2+sXnv55Zd58cUX69auLMg8z5Hji4h8oWuOHEB7ezvgGtGe4O2330ZrzRprrFF3fYUVVmDgwIG8/fbbdddXW221Bj/efPNNXnzxxeo6jxAffPABAL/4xS+47bbb+N73vsdKK63Etttuyx577MF22203z359XhxxxBGcd955nHrqqdxzzz2Zbv75z39y4okn8thjj1U7ex6zZs1q6nehUOAHP/gBN910E6VSiba2NiZOnEilUqnrlLz55pu8+uqrnyuuURTxne98p+7a9ttvz5prrsnxxx/PnXfeCYAxhgsuuIBLLrmEqVOn1q2LGTJkSPW71pp99tmHSy+9lI6ODvr06cONN95Ir1692H333eu4L6g8z5Hji4i8U5IjB65TsuKKK/Lyyy/P03NKqR65y9ppY4xhm2224Zhjjsl85stf/jIAyy23HFOmTOGRRx7hoYce4qGHHuLaa69lv/324/rrr58nvz4vvLXk1FNPzbSWfPrpp2yxxRa0t7czduxYVl99dXr16sVzzz3Hscce2+0W4B/+8IdcfvnlPPTQQ+y8887cdtttfPWrX2W99darujHGsM4663Duuedm+jFs2LD5itvKK6/MV77ylTqr0vjx4znppJP4yU9+wrhx4xg8eDBaa4488siGuOy3336cffbZ3H333ey1117cdNNNjBo1igEDBtRxX1B5niPHFxF5pyRHjhSjRo3iiiuuYPLkyWy22WZdul111VUxxvDmm2+y1lprVa/PmDGDTz/9lFVXXbXb8FZffXXmzJnTMGLPQmtrKzvuuCM77rgjxhh+8YtfcPnll3PSSSexxhpr9NivnnaiusKRRx7J+eefz2mnncbAgQPr7j3xxBPMnDmTiRMn8q1vfat6ferUqT3y+1vf+hZDhw7l1ltv5Zvf/CaPPfYYJ5xwQp2b1VdfnRdeeIGtt956gcRHIo5j5syZU/19xx13sNVWW3H11VfXufv0009ZZpll6q6tvfbabLDBBtx4442svPLKvPPOO1x44YUN3BdUnufI8UVEvqYkR44UxxxzDH379uWnP/0pM2bMaLj/1ltvVbdkbr/99gCcf/75dW786H2HHXboNrw99tiDyZMn88gjjzTc+/TTT4njGICZM2fW3dNas+666wJUt8D21K8+ffpUr80vvLXknnvuYcqUKXX3oigC3FksHuVymUsuuaRHfmut2W233bjvvvu44YYbiOO4buoGXFzfe+89rrzyyobnOzs7mTt37jzGyOGNN97g9ddfr7PKRFFUFxdw60Lee++9TD/23Xdf/vCHP3D++eczZMgQvve97zVwX1B5niPHFxHKhiUuR46lGPfeey977rknvXv3rjvRddKkSdx+++2MHj26esbI6NGjuf7669ljjz3YYost+Pvf/87111/PzjvvzF133VX1c/jw4ay99trcf//9dWF1dHQwcuRIXnzxRUaPHs2GG27I3Llzeemll7jjjjuYNm0ayyyzDLvssgsff/wx3/72t1l55ZV5++23ufDCCxk+fDj/+Mc/0Fr32C+Ar33ta3z88cecdNJJDB48mLXXXpu11147Mz2eeOIJttpqK26//XZ222236vVPP/2U4cOHM2vWLPr27Vu1LsycOZM111yT9vZ2Dj/8cJRS3HDDDRhjeOGFF3j88cerJ8mOHj2aJ554gmnTptWF+dRTT/HNb36T/v37M3z4cF588cW6+8YYdtxxRx566CH23HNPNt98c5Ik4bXXXuO2226rngfTDKNHj+aWW26pnuhqjGHatGlcdtllzJgxg/vvv7/amTjllFMYO3Yso0ePZsSIEbz00kvceOONDBw4kGHDhjUc1z9jxgxWXnll4jjm4IMPbuiMLcg8z5HjC4nFu/knR44lD2+88YY98MAD7fDhw21ra6vt37+/3Xzzze2FF15Yt6W1UqnY0047za622mq2paXFDhs2zB5//PF1bqx1W4J32GGHzLA+++wze/zxx9s11ljDtra22mWWWcaOGDHCnnPOObZcLltrrb3jjjvstttua5dbbjnb2tpqV1llFXvQQQfZ6dOnz7Nf1lo7adIku+GGG9rW1tZutwfLLcEhTjnlFAs0bAl+6qmn7Kabbmp79+5tV1xxRXvMMcdUt8w+/vjjVXfhlmAPY4wdNmyYBezpp5+eyatcLtuzzjrLfu1rX7NtbW120KBBdsMNN7SnnXaanTVrVtP4+HAJtgO3t7fbrbfe2v7xj3+sc1ssFu1RRx1lhw4danv37m0333xzO3nyZLvFFlvUbfWV2H777S1gJ02alHl/QeZ5jhxfNOSWkhw5cuRYgNhll1146aWX+Ne//rW4qeTI8T+H3AaYI0eOHAsI06dP54EHHmDfffdd3FRy5PifRL77JkeOHDk+J6ZOncpTTz3FVVddRUtLCwcddNDippQjx/8kcktJjhw5cnxO/PnPf2bfffdl6tSpXH/99dWX++XIkWPekK8pyZEjR44cOXIsEcgtJTly5MiRI0eOJQJ5pyRHjhw5cuTIsUQg75TkyJEjR44cOZYI5J2SHDly5MiRI8cSgbxTkiNHjhw5cuRYIpB3SnLkyJEjR44cSwTyTkmOHDly5MiRY4lA3inJkSNHjhw5ciwRyDslOXLkyJEjR44lAnmnJEeOHDly5MixRCDvlOTIkSNHjhw5lgjknZIcOXLkyJEjxxKBvFOSI0eOHDly5FgikHdKcuTIkSNHjhxLBPJOSY4cOXLkyJFjiUDeKcmRI0eOHDlyLBHIOyU5cuTIkSNHjiUCeackR44cOXLkyLFEIO+U5MiRI0eOHDmWCOSdkhw5cuTIkSPHEoG8U5IjR44cOXLkWCKQd0py5MiRI0eOHEsE8k5Jjhw5cuTIkWOJQN4pyZEjR44cOXIsEcg7JTly5MiRI0eOJQJ5pyRHjhw5cuTIsUQg75TkyJEjR44cOZYI5J2SHDly5MiRI8cSgcLiJtAVjDH897//pX///iilFjedHDly5MiRI0cPYK3ls88+Y8UVV0Trnts/luhOyX//+1+GDRu2uGnkyJEjR44cOeYD7777LiuvvHKP3S/RnZL+/fsDLlLt7e2LmU2OHDly5MiRoyeYPXs2w4YNq7bjPcUS3SnxUzbt7e15pyRHjhw5cuT4H8O8Lr3IF7rmyJEjR44cOZYI5J2SHDly5MiRI8cSgbxTkiNHjhw5cuRYIrBErynJkSNHjhyLFtZa4jgmSZLFTSXHEowoiigUCgv8uI68U5IjR44cOQAol8tMnz6djo6OxU0lx/8A+vTpw9ChQ2ltbV1gfuadkhw5cuTIgTGGqVOnEkURK664Iq2trfmhlTkyYa2lXC7z4YcfMnXqVNZcc815OiCtK+Sdkhw5cuTIQblcxhjDsGHD6NOnz+Kmk2MJR+/evWlpaeHtt9+mXC7Tq1evBeJvvtA1R44cOXJUsaBGvDm++FgYWsktJTly5FiikSQJTz75JNOnT2fo0KGMHDmSKIoWN60cOXIsBCzULvF7773Hj370I4YMGULv3r1ZZ511ePbZZxdmkDly5PgCYeLEiayxxhpstdVW7L333my11VasscYaTJw4cXFTy9ENjDGLm8LnwvDhwzn//PN77P6JJ55AKcWnn3660Dg1w3XXXcfAgQMXebgLAwutU/LJJ5+w+eab09LSwkMPPcQrr7zCb3/7WwYNGrSwgsyRI8cXCBMnTmS33XZjnXXWYfLkyXz22WdMnjyZddZZh9122y3vmCzBeO2111hxxaHce++9Cz0spVSXn1NPPXW+/H3mmWf42c9+1mP3I0aMYPr06QwYMGC+wlvUmNdO16LCQpu+Oeussxg2bBjXXntt9dpqq622sILLkSPHFwhJknDUUUcxatQo7r777urc9aabbsrdd9/NzjvvzNFHH81OO+2UT+UsYbDWcuihv2DGjA849NCD2Xrrrenbt+9CC2/69OnV77feeisnn3wyr7/+evVav3796rglSUKh0H3Tt+yyy84Tj9bWVlZYYYV5eiZHIxaapeTee+9lo402Yvfdd2e55ZZjgw024Morr+zymVKpxOzZs+s+OXLkWPrw5JNPMm3aNMaMGdOwmE5rzfHHH8/UqVN58sknFxPDHM1wxx138Kc/Pc7vzliWDz6Ywfjx4xdqeCussEL1M2DAAJRS1d+vvfYa/fv356GHHmLDDTekra2Nv/71r7z11lvstNNOLL/88vTr14+NN96YP/7xj3X+hpYEpRRXXXUVu+yyC3369GHNNdesswSF0zd+SuWRRx5hrbXWol+/fmy33XZ1nag4jjn88MMZOHAgQ4YM4dhjj2X//fdn55137jLO1113Haussgp9+vRhl112YebMmXX3u4vflltuydtvv80vf/nLqkUJYObMmey1116stNJK9OnTh3XWWYebb755XrLjc2OhdUr+/e9/c+mll7LmmmvyyCOPcPDBB3P44Ydz/fXXN31mwoQJDBgwoPoZNmzYwqKXI0eOJRi+4l577bUz7/vrsoLPsfgxZ84cfvnLw/n+d/tzyE8GctxhAzj77N/wxhtvLFZexx13HGeeeSavvvoq6667LnPmzGH77bfnT3/6E88//zzbbbcdO+64I++8806X/px22mnssccevPjii2y//fbss88+fPzxx03dd3R0cM4553DDDTfwl7/8hXfeeYejjz66ev+ss87ixhtv5Nprr+Wpp55i9uzZ3H333V1y+Nvf/sYBBxzAoYceypQpU9hqq604/fTT69x0F7+JEyey8sorM3bsWKZPn14tR8VikQ033JAHHniAl19+mZ/97Gfsu+++/P3vf++S0wKFXUhoaWmxm222Wd21ww47zG666aZNnykWi3bWrFnVz7vvvmsBO2vWrIVFM0eOHEsgHn/8cQvYyZMnZ96fNGmSBezjjz++aIl9gdHZ2WlfeeUV29nZOd9+HHvssbZXr8i+9ffhNpm+pp3z79Xtaqv0sttu+x1rjFmAbLNx7bXX2gEDBlR/ex3dfffd3T77ta99zV544YXV36uuuqo977zzqr8Be+KJJ1Z/z5kzxwL2oYceqgvrk08+qXIB7L/+9a/qMxdffLFdfvnlq7+XX355e/bZZ1d/x3FsV1llFbvTTjs15bnXXnvZ7bffvu7annvuWRfv+YlfM+ywww72qKOOyrzXlWZmzZo1X+33QrOUDB06lP/3//5f3bW11lqry55oW1sb7e3tdZ8cOXIsfRg5ciTDhw9n/PjxDbs4jDFMmDCB1VZbjZEjRy4mhjlCvPrqq/z2t+dw/GEDGD6sBYDevTXnnz6IP/zhj9x1112LjdtGG21U93vOnDkcffTRrLXWWgwcOJB+/frx6quvdmspWXfddavf+/btS3t7Ox988EFT93369GH11Vev/h46dGjV/axZs5gxYwbf+MY3qvejKGLDDTfsksOrr77KJptsUndts802WyDxS5KEcePGsc466zB48GD69evHI4880u1zCxILrVOy+eab1y02AnjjjTdYddVVF1aQOXLk+IIgiiJ++9vfcv/997PzzjvX7b7Zeeeduf/++znnnHPyRa5LEG644Qa0thzxs/odlqO26cfXvtKLK6+8fDExo2Gh7dFHH81dd93F+PHjefLJJ5kyZQrrrLMO5XK5S39aWlrqfiulutz6nOXeWjuP7Ocd8xu/s88+mwsuuIBjjz2Wxx9/nClTpvDd73632+cWJBZap+SXv/wlTz/9NOPHj+df//oXN910E1dccQWHHHLIwgoyR44cXyDsuuuu3HHHHbz00kuMGDGC9vZ2RowYwcsvv8wdd9zBrrvuurgp5hDYY489iGO44oZZddf/+JcO/vl6kX322XcxMWvEU089xejRo9lll11YZ511WGGFFZg2bdoi5TBgwACWX355nnnmmeq1JEl47rnnunxurbXW4m9/+1vdtaeffrrud0/i19ra2vAm6KeeeoqddtqJH/3oR6y33np86UtfWuTrgRZap2TjjTfmrrvu4uabb2bttddm3LhxnH/++eyzzz4LK8gcOXJ8wbDrrrvyr3/9i8cff5ybbrqJxx9/nDfffDPvkCyBWH/99TnkkEMY+9tPeW96DEC5bDnixI8ZOXLEElX3r7nmmkycOJEpU6bwwgsvsPfeey+Ww94OO+wwJkyYwD333MPrr7/OEUccwSeffNLlixAPP/xwHn74Yc455xzefPNNLrroIh5++OE6Nz2J3/Dhw/nLX/7Ce++9x0cffVR97tFHH2XSpEm8+uqrHHTQQcyYMWPBR7wLLNQTXUeNGsVLL71EsVjk1Vdf5cADD1yYweXIkeMLiCiK2HLLLdlrr73Ycsst8ymbJRhjx46lT98B/Hqs26J6wZWf8Oa/S1x88WVL1BuHzz33XAYNGsSIESPYcccd+e53v8vXv/71Rc7j2GOPZa+99mK//fZjs802o1+/fnz3u9/t8uV2m266KVdeeSUXXHAB6623Hn/4wx848cQT69z0JH5jx45l2rRprL766tUzWU488US+/vWv893vfpctt9ySFVZYodvtyQsayi6KCa75xOzZsxkwYACzZs3KF73myJEjx0JEsVhk6tSprLbaap/rja/XX389o0eP5rrfLc8hx8/kwAMP5bzzzluATL+4MMaw1lprscceezBu3LjFTadbdKWZ+W2/89dB5siRI0eOBYZ9992XESM2YfThM+jXb+B8H/O+NODtt9/myiuv5I033uCll17i4IMPZurUqey9996Lm9piQ94pyZEjR44cCwxaay6++DL69evL+edf+D/zLpjFAa011113HRtvvDGbb745L730En/84x9Za621Fje1xYaF9u6bHDly5MixdGL99dfno49m0tbWtripLNEYNmwYTz311OKmsUQht5TkyJEjR44FjrxDkmN+kHdKcuTIkSNHjhxLBPJOSY4cOXLkyJFjiUDeKcmRI0eOHDlyLBHIOyU5cuTIkSNHjiUCeackR44cOXLkyLFEIO+U5MiRI0eOHAsQ06ZNQynFlClTFjeV/znknZIcOXLkyPE/C6VUl5/Pc6KsUoq77757gXHtCqNHj17k75lZEpEfnpYjR44cORYokiThySefZPr06QwdOpSRI0cutBcpTp8+vfr91ltv5eSTT+b111+vXuvXr99CCTfHwkFuKcmRI0eOHAsMEydOZI011mCrrbZi7733ZquttmKNNdZg4sSJCyW8FVZYofoZMGAASqm6a7fccgtrrbUWvXr14qtf/SqXXHJJ9dlyucyhhx7K0KFD6dWrF6uuuioTJkwAYPjw4QDssssuKKWqv7Pw97//nQ022IBevXqx0UYb8fzzz9fdT5KEAw44gNVWW43evXvzla98hQsuuKB6/9RTT+X666/nnnvuqVp4nnjiCcC9SfjLX/4yffr04Utf+hInnXQSlUplwSTeEojcUpIjR44cORYIJk6cyG677caoUaO4+eabWXvttXn55ZcZP348u+22G3fccQe77rrrIuNz4403cvLJJ3PRRRexwQYb8Pzzz3PggQfSt29f9t9/f373u99x7733ctttt7HKKqvw7rvv8u677wLwzDPPsNxyy3Httdey3XbbNbX0zJkzh1GjRrHNNtvw+9//nqlTp3LEEUfUuTHGsPLKK3P77bczZMgQJk2axM9+9jOGDh3KHnvswdFHH82rr77K7NmzufbaawEYPHgwAP379+e6665jxRVX5KWXXuLAAw+kf//+HHPMMQsx5RYj7BKMWbNmWcDOmjVrcVPJkSNHji80Ojs77SuvvGI7Ozvn6/k4ju3w4cPtjjvuaJMkqbuXJIndcccd7WqrrWbjOF4QdDNx7bXX2gEDBlR/r7766vamm26qczNu3Di72WabWWutPeyww+y3v/1ta4zJ9A+wd911V5dhXn755XbIkCF16XbppZdawD7//PNNnzvkkEPsD37wg+rv/fff3+60005dhmWttWeffbbdcMMNu3W3KNCVZua3/c4tJTly5MiR43PjySefZNq0adx8881oXb8yQGvN8ccfz4gRI3jyySfZcsstFzqfuXPn8tZbb3HAAQdw4IEHVq/HcVx9c/Ho0aPZZptt+MpXvsJ2223HqFGj2HbbbecpnFdffZV1112XXr16Va9tttlmDe4uvvhirrnmGt555x06Ozspl8usv/763fp/66238rvf/Y633nqLOXPmEMcx7e3t88Txfwn5mpIcOXLkyPG54Recrr322pn3/XW5MHVhYs6cOQBceeWVTJkypfp5+eWXefrppwH4+te/ztSpUxk3bhydnZ3sscce7Lbbbgucyy233MLRRx/NAQccwB/+8AemTJnCj3/8Y8rlcpfPTZ48mX322Yftt9+e+++/n+eff54TTjih2+f+l5FbSnLkyJEjx+fG0KFDAXj55ZfZdNNNG+6//PLLde4WNpZffnlWXHFF/v3vf7PPPvs0ddfe3s6ee+7JnnvuyW677cZ2223Hxx9/zODBg2lpaSFJki7DWWuttbjhhhsoFotVa4nv9Hg89dRTjBgxgl/84hfVa2+99Vadm9bW1oawJk2axKqrrsoJJ5xQvfb22293HfH/ceSWkhw5cuTI8bkxcuRIhg8fzvjx4zHG1N0zxjBhwgRWW201Ro4cucg4nXbaaUyYMIHf/e53vPHGG7z00ktce+21nHvuuQCce+653Hzzzbz22mu88cYb3H777aywwgoMHDgQcDtw/vSnP/H+++/zySefZIax9957o5TiwAMP5JVXXuHBBx/knHPOqXOz5ppr8uyzz/LII4/wxhtvcNJJJ/HMM8/UuRk+fDgvvvgir7/+Oh999BGVSoU111yTd955h1tuuYW33nqL3/3ud9x1110LPqGWJCyoBS8LA/lC1xw5cuRYNPi8C12ttfbOO++0Sim744472kmTJtnZs2fbSZMm2R133NEqpeydd965ABk3Ilzoaq21N954o11//fVta2urHTRokP3Wt75lJ06caK219oorrrDrr7++7du3r21vb7dbb721fe6556rP3nvvvXaNNdawhULBrrrqqk3DnTx5sl1vvfVsa2urXX/99e2dd95Zt9C1WCza0aNH2wEDBtiBAwfagw8+2B533HF2vfXWq/rxwQcf2G222cb269fPAvbxxx+31lr761//2g4ZMsT269fP7rnnnva8885riOPiwsJY6KqstXbxdouaY/bs2QwYMIBZs2Z9oRf25MiRI8fiRrFYZOrUqay22mp1izbnFRMnTuSoo45i2rRp1WurrbYa55xzziLdDpxj4aMrzcxv+52vKcmRI0eOHAsMu+66KzvttNMiO9E1xxcLeackR44cOXIsUERRtEi2/eb44iFf6JojR44cOXLkWCKQd0py5MiRI0eOHEsE8k5Jjhw5cuTIkWOJ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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "main()" - ] - }, - { - "cell_type": "markdown", - "id": "946a29f4-ac14-4e0a-9aea-92e36607a32a", - "metadata": {}, - "source": [ - "The coloured regions of the graph represent the regions in which the model predicts either class." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.11.4" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/pyproject.toml b/pyproject.toml deleted file mode 100644 index e8fa7831..00000000 --- a/pyproject.toml +++ /dev/null @@ -1,36 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -[build-system] -requires = ["wheel", - "setuptools >= 30.3.0", - "numpy", - "nanobind >= 1.6"] -build-backend = "setuptools.build_meta" - -[tool.cibuildwheel] -build-verbosity = 0 # options: 1, 2, or 3 -skip = ["cp36-*", "cp37-*", "cp38-*", "pp*", "*-win32"] - -[tool.cibuildwheel.windows] -archs = ["auto64"] - -[tool.cibuildwheel.linux] -archs = ["auto", "aarch64"] - -[tool.cibuildwheel.macos] -archs = ["x86_64", "arm64"] diff --git a/setup.py b/setup.py deleted file mode 100644 index fdb7c2f8..00000000 --- a/setup.py +++ /dev/null @@ -1,113 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -# Modified from: -# http://www.benjack.io/2018/02/02/python-cpp-revisited.html - -import os -import sys -import platform -import shutil -import subprocess -import re -from datetime import datetime, timezone - -from setuptools import setup, find_packages, Extension -from setuptools.command.build_ext import build_ext - -class CMakeExtension(Extension): - def __init__(self, name, sourcedir=''): - Extension.__init__(self, name, sources=[]) - self.sourcedir = os.path.abspath(sourcedir) - -class CMakeBuild(build_ext): - def run(self): - if shutil.which('cmake') is None: - raise RuntimeError( - "CMake >= 3.16 must be installed to build the following extensions: " + - ", ".join(e.name for e in self.extensions)) - - for ext in self.extensions: - self.build_extension(ext) - - def build_extension(self, ext): - extdir = os.path.abspath( - os.path.dirname(self.get_ext_fullpath(ext.name))) - cmake_args = ['-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=' + extdir] - # ensure we use a consistent python version - #cmake_args += ['-DPython3_EXECUTABLE=' + sys.executable] - cmake_args += ['-DPython_EXECUTABLE=' + sys.executable] - cfg = 'Debug' if self.debug else 'Release' - build_args = ['--config', cfg] - - if platform.system() == "Windows": - cmake_args += ['-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_{}={}'.format( - cfg.upper(), - extdir)] - if sys.maxsize > 2**32: - cmake_args += ['-T', 'host=x64'] - cmake_args += ['-DCMAKE_GENERATOR_PLATFORM=x64'] - build_args += ['--', '/m'] - else: - cmake_args += ['-DCMAKE_BUILD_TYPE=' + cfg] - build_args += ['--', '-j2'] - - env = os.environ.copy() - env['CXXFLAGS'] = '{} -DVERSION_INFO=\\"{}\\"'.format( - env.get('CXXFLAGS', ''), - self.distribution.get_version()) - if not os.path.exists(self.build_temp): - os.makedirs(self.build_temp) - subprocess.check_call(['cmake', ext.sourcedir] + cmake_args, - cwd=self.build_temp, env=env) - subprocess.check_call(['cmake', '--build', '.', '--target', 'python'] + build_args, - cwd=self.build_temp, env=env) - print() # add an empty line to pretty print - -# Read and parse the version format -# @DT@ -> datestamp -# @HHMM@ -> .devHHMM to indicate development version -# Releases should have a fixed version with no @ variables -with open('version.cfg.in', 'r') as file: - ds_version = file.read().rstrip() -dt = datetime.now(timezone.utc) -ds_version = re.sub('@DT@', dt.strftime('%Y%m%d'), ds_version) -ds_version = re.sub('@HHMM@', 'dev' + dt.strftime('%H%M'), ds_version) - -setup_requires = [] -if shutil.which('cmake') is None: - setup_requires += ['cmake >= 3.16'] - -setup( - name='datasketches', - version=ds_version, - author='Apache Software Foundation', - author_email='dev@datasketches.apache.org', - description='The Apache DataSketches Library for Python', - license='Apache License 2.0', - url='http://datasketches.apache.org', - long_description=open('README.md').read(), - long_description_content_type='text/markdown', - packages=find_packages(exclude=['src','include','*tests*']), # src not needed if only the .so - package_dir={'':'.'}, - # may need to add all source paths for sdist packages w/o MANIFEST.in - ext_modules=[CMakeExtension('datasketches','.')], - cmdclass={'build_ext': CMakeBuild}, - setup_requires=setup_requires, - install_requires=['numpy'], - zip_safe=False -) diff --git a/src/__init__.py b/src/__init__.py deleted file mode 100644 index 756e6938..00000000 --- a/src/__init__.py +++ /dev/null @@ -1,18 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -name = "datasketches" diff --git a/src/count_wrapper.cpp b/src/count_wrapper.cpp deleted file mode 100644 index 96774a98..00000000 --- a/src/count_wrapper.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#include -#include - -#include "count_min.hpp" -#include "common_defs.hpp" - -namespace nb = nanobind; - -template -void bind_count_min_sketch(nb::module_ &m, const char* name) { - using namespace datasketches; - - nb::class_>(m, name) - .def(nb::init(), nb::arg("num_hashes"), nb::arg("num_buckets"), nb::arg("seed")=DEFAULT_SEED, - "Creates an instance of a CountMin sketch\n\n" - ":param num_hashes: Number of rows in the sketch\n:type num_hashes: int\n" - ":param num_buckets: Number of columns in the sketch\n:type num_buckets: int\n" - ":param seed: Hash seed to use\n:type seed: int, optional" - ) - // using nun_hashes (rows), num_buckets (columns), and hash seed `seed`.) - .def("__copy__", [](const count_min_sketch& sk){ return count_min_sketch(sk); }) - .def_static("suggest_num_buckets", &count_min_sketch::suggest_num_buckets, nb::arg("relative_error"), - "Suggests the number of buckets needed to achieve an accuracy within the provided " - "relative_error. For example, when relative_error = 0.05, the returned frequency estimates " - "satisfy the 'relative_error' guarantee that never overestimates the weights but may " - "underestimate the weights by 5% of the total weight in the sketch. " - "Returns the number of hash buckets at every level of the sketch required in order to obtain " - "the specified relative error.") - .def_static("suggest_num_hashes", &count_min_sketch::suggest_num_hashes, nb::arg("confidence"), - "Suggests the number of hashes needed to achieve the provided confidence. For example, " - "with 95% confidence, frequency estimates satisfy the 'relative_error' guarantee. " - "Returns the number of hash functions that are required in order to achieve the specified " - "confidence of the sketch. confidence = 1 - delta, with delta denoting the sketch failure probability.") - .def("__str__", [](const count_min_sketch& sk) { return sk.to_string(); }, - "Produces a string summary of the sketch") - .def("to_string", &count_min_sketch::to_string, - "Produces a string summary of the sketch") - .def("is_empty", &count_min_sketch::is_empty, - "Returns True if the sketch has seen no items, otherwise False") - .def_prop_ro("num_hashes", &count_min_sketch::get_num_hashes, - "The configured number of hashes for the sketch") - .def_prop_ro("num_buckets", &count_min_sketch::get_num_buckets, - "The configured number of buckets for the sketch") - .def_prop_ro("seed", &count_min_sketch::get_seed, - "The base hash seed for the sketch") - .def("get_relative_error", &count_min_sketch::get_relative_error, - "Returns the maximum permissible error for any frequency estimate query") - .def_prop_ro("total_weight", &count_min_sketch::get_total_weight, - "The total weight currently inserted into the stream") - .def("update", static_cast::*)(int64_t, W)>(&count_min_sketch::update), nb::arg("item"), nb::arg("weight")=1.0, - "Updates the sketch with the given 64-bit integer value") - .def("update", static_cast::*)(const std::string&, W)>(&count_min_sketch::update), nb::arg("item"), nb::arg("weight")=1.0, - "Updates the sketch with the given string") - .def("get_estimate", static_cast::*)(int64_t) const>(&count_min_sketch::get_estimate), nb::arg("item"), - "Returns an estimate of the frequency of the provided 64-bit integer value") - .def("get_estimate", static_cast::*)(const std::string&) const>(&count_min_sketch::get_estimate), nb::arg("item"), - "Returns an estimate of the frequency of the provided string") - .def("get_upper_bound", static_cast::*)(int64_t) const>(&count_min_sketch::get_upper_bound), nb::arg("item"), - "Returns an upper bound on the estimate for the given 64-bit integer value") - .def("get_upper_bound", static_cast::*)(const std::string&) const>(&count_min_sketch::get_upper_bound), nb::arg("item"), - "Returns an upper bound on the estimate for the provided string") - .def("get_lower_bound", static_cast::*)(int64_t) const>(&count_min_sketch::get_lower_bound), nb::arg("item"), - "Returns a lower bound on the estimate for the given 64-bit integer value") - .def("get_lower_bound", static_cast::*)(const std::string&) const>(&count_min_sketch::get_lower_bound), nb::arg("item"), - "Returns a lower bound on the estimate for the provided string") - .def("merge", &count_min_sketch::merge, nb::arg("other"), - "Merges the provided other sketch into this one") - .def("get_serialized_size_bytes", &count_min_sketch::get_serialized_size_bytes, - "Returns the size in bytes of the serialized image of the sketch") - .def( - "serialize", - [](const count_min_sketch& sk) { - auto bytes = sk.serialize(); - return nb::bytes(reinterpret_cast(bytes.data()), bytes.size()); - }, - "Serializes the sketch into a bytes object" - ) - .def_static( - "deserialize", - [](const nb::bytes& bytes) { return count_min_sketch::deserialize(bytes.c_str(), bytes.size()); }, - nb::arg("bytes"), - "Reads a bytes object and returns the corresponding count_min_sketch" - ); -} - -void init_count_min(nb::module_ &m) { - bind_count_min_sketch(m, "count_min_sketch"); -} - diff --git a/src/cpc_wrapper.cpp b/src/cpc_wrapper.cpp deleted file mode 100644 index 06c428ac..00000000 --- a/src/cpc_wrapper.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#include -#include - -#include "cpc_sketch.hpp" -#include "cpc_union.hpp" -#include "cpc_common.hpp" -#include "common_defs.hpp" - -namespace nb = nanobind; - -void init_cpc(nb::module_ &m) { - using namespace datasketches; - - nb::class_(m, "cpc_sketch") - .def(nb::init(), nb::arg("lg_k")=cpc_constants::DEFAULT_LG_K, nb::arg("seed")=DEFAULT_SEED, - "Creates a new CPC sketch\n\n" - ":param lg_k: base 2 logarithm of the number of bins in the sketch\n" - ":type lg_k: int, optional\n" - ":param seed: seed value for the hash function\n" - ":type seed: int, optional" - ) - .def("__copy__", [](const cpc_sketch& sk){ return cpc_sketch(sk); }) - .def("__str__", [](const cpc_sketch& sk) { return sk.to_string(); }, - "Produces a string summary of the sketch") - .def("to_string", &cpc_sketch::to_string, - "Produces a string summary of the sketch") - .def("update", &cpc_sketch::update, nb::arg("datum"), - "Updates the sketch with the given 64-bit integer value") - .def("update", &cpc_sketch::update, nb::arg("datum"), - "Updates the sketch with the given 64-bit floating point") - .def("update", &cpc_sketch::update, nb::arg("datum"), - "Updates the sketch with the given string") - .def_prop_ro("lg_k", &cpc_sketch::get_lg_k, - "Configured lg_k of this sketch") - .def("is_empty", &cpc_sketch::is_empty, - "Returns True if the sketch is empty, otherwise False") - .def("get_estimate", &cpc_sketch::get_estimate, - "Estimate of the distinct count of the input stream") - .def("get_lower_bound", &cpc_sketch::get_lower_bound, nb::arg("kappa"), - "Returns an approximate lower bound on the estimate for kappa values in {1, 2, 3}, roughly corresponding to standard deviations") - .def("get_upper_bound", &cpc_sketch::get_upper_bound, nb::arg("kappa"), - "Returns an approximate upper bound on the estimate for kappa values in {1, 2, 3}, roughly corresponding to standard deviations") - .def( - "serialize", - [](const cpc_sketch& sk) { - auto bytes = sk.serialize(); - return nb::bytes(reinterpret_cast(bytes.data()), bytes.size()); - }, - "Serializes the sketch into a bytes object" - ) - .def_static( - "deserialize", - [](const nb::bytes& bytes) { return cpc_sketch::deserialize(bytes.c_str(), bytes.size()); }, - nb::arg("bytes"), - "Reads a bytes object and returns the corresponding cpc_sketch" - ); - - nb::class_(m, "cpc_union") - .def(nb::init(), nb::arg("lg_k"), nb::arg("seed")=DEFAULT_SEED) - .def("update", (void (cpc_union::*)(const cpc_sketch&)) &cpc_union::update, nb::arg("sketch"), - "Updates the union with the provided CPC sketch") - .def("get_result", &cpc_union::get_result, - "Returns a CPC sketch with the result of the union") - ; -} diff --git a/src/datasketches.cpp b/src/datasketches.cpp deleted file mode 100644 index 118683bc..00000000 --- a/src/datasketches.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#include -#include - -// needed for sketches such as Density and Tuple which rely -// on a joint C++/Python object -#include - -namespace nb = nanobind; - -// sketches -void init_hll(nb::module_& m); -void init_kll(nb::module_& m); -void init_fi(nb::module_& m); -void init_cpc(nb::module_& m); -void init_theta(nb::module_& m); -void init_tuple(nb::module_& m); -void init_vo(nb::module_& m); -void init_ebpps(nb::module_& m); -void init_req(nb::module_& m); -void init_quantiles(nb::module_& m); -void init_count_min(nb::module_& m); -void init_density(nb::module_& m); -void init_tdigest(nb::module_& m); -void init_vector_of_kll(nb::module_& m); - -// supporting objects -void init_kolmogorov_smirnov(nb::module_& m); -void init_serde(nb::module_& m); - -NB_MODULE(_datasketches, m) { - // needed in conjunction with the counter.inl include above - nb::intrusive_init( - [](PyObject *o) noexcept { - nb::gil_scoped_acquire guard; - Py_INCREF(o); - }, - [](PyObject *o) noexcept { - nb::gil_scoped_acquire guard; - Py_DECREF(o); - } - ); - - init_hll(m); - init_kll(m); - init_fi(m); - init_cpc(m); - init_theta(m); - init_tuple(m); - init_vo(m); - init_ebpps(m); - init_req(m); - init_quantiles(m); - init_count_min(m); - init_density(m); - init_tdigest(m); - init_vector_of_kll(m); - - init_kolmogorov_smirnov(m); - init_serde(m); -} diff --git a/src/density_wrapper.cpp b/src/density_wrapper.cpp deleted file mode 100644 index 2bc422fe..00000000 --- a/src/density_wrapper.cpp +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include "kernel_function.hpp" -#include "density_sketch.hpp" - -namespace nb = nanobind; - -template -void bind_density_sketch(nb::module_ &m, const char* name) { - using namespace datasketches; - - nb::class_>(m, name) - .def("__init__", [](density_sketch* sk, uint16_t k, uint32_t dim, kernel_function* kernel) - { K holder(kernel); - new (sk) density_sketch(k, dim, holder); - }, - nb::arg("k"), nb::arg("dim"), nb::arg("kernel"), - "Creates a new density sketch\n\n" - ":param k: controls the size and error of the sketch\n:type k: int\n" - ":param dim: dimension of the input data\n:type dim: int\n" - ":param kernel: instance of a kernel\n:type kernel: KernelFunction\n" - ) - .def("__copy__", [](const density_sketch& sk){ return density_sketch(sk); }) - .def("update", static_cast::*)(const std::vector&)>(&density_sketch::update), nb::arg("vector"), - "Updates the sketch with the given vector") - .def("merge", static_cast::*)(const density_sketch&)>(&density_sketch::merge), nb::arg("sketch"), - "Merges the provided sketch into this one") - .def("is_empty", &density_sketch::is_empty, - "Returns True if the sketch is empty, otherwise False") - .def_prop_ro("k", &density_sketch::get_k, - "The configured parameter k") - .def_prop_ro("dim", &density_sketch::get_dim, - "The configured parameter dim") - .def_prop_ro("n", &density_sketch::get_n, - "The length of the input stream") - .def_prop_ro("num_retained", &density_sketch::get_num_retained, - "The number of retained items (samples) in the sketch") - .def("is_estimation_mode", &density_sketch::is_estimation_mode, - "Returns True if the sketch is in estimation mode, otherwise False") - .def("get_estimate", &density_sketch::get_estimate, nb::arg("point"), - "Returns an approximate density at the given point") - .def("__str__", [](const density_sketch& sk) { return sk.to_string(); }, - "Produces a string summary of the sketch") - .def("to_string", &density_sketch::to_string, nb::arg("print_levels")=false, nb::arg("print_items")=false, - "Produces a string summary of the sketch") - .def("__iter__", [](const density_sketch &sk) { - return nb::make_iterator(nb::type >(), - "density_iterator", - sk.begin(), - sk.end()); - }, - nb::keep_alive<0,1>()) - .def("serialize", - [](const density_sketch& sk) { - auto bytes = sk.serialize(); - return nb::bytes(reinterpret_cast(bytes.data()), bytes.size()); - }, - "Serializes the sketch into a bytes object" - ) - .def_static( - "deserialize", - [](const nb::bytes& bytes, kernel_function* kernel) { - K holder(kernel); - return density_sketch::deserialize(bytes.c_str(), bytes.size(), holder); - }, - nb::arg("bytes"), nb::arg("kernel"), - "Reads a bytes object and returns the corresponding density_sketch" - ); -} - -int prepare_numpy() { - import_array1(0); - return 0; -} - -void init_density(nb::module_ &m) { - using namespace datasketches; - - prepare_numpy(); - - // generic kernel function - nb::class_(m, "KernelFunction", - nb::intrusive_ptr( - [](kernel_function *kf, PyObject *po) noexcept { kf->set_self_py(po); }), - "A generic base class from which user-defined kernels must inherit.") - .def(nb::init()) - .def("__call__", &kernel_function::operator(), nb::arg("a"), nb::arg("b"), - "A method to evaluate a kernel with given inputs a and b.\n\n" - ":param a: An input vector\n:type a: numpy array\n" - ":param b: An input vector\n:type b: numpy array\n" - ":return: A vector similarity score\n:rtype: float" - ) - ; - - // the old sketch names can almost be defined, but the kernel_function_holder won't work in init() - //bind_density_sketch>(m, "density_floats_sketch"); - //bind_density_sketch>(m, "density_doubles_sketch"); - bind_density_sketch(m, "density_sketch"); -} diff --git a/src/ebpps_wrapper.cpp b/src/ebpps_wrapper.cpp deleted file mode 100644 index d2f24f27..00000000 --- a/src/ebpps_wrapper.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#include -#include -#include -#include - -#include "py_serde.hpp" -#include "py_object_ostream.hpp" - -#include "ebpps_sketch.hpp" - -namespace nb = nanobind; - -template -void bind_ebpps_sketch(nb::module_ &m, const char* name) { - using namespace datasketches; - - nb::class_>(m, name) - .def(nb::init(), nb::arg("k"), - "Creates a new EBPPS sketch instance\n\n" - ":param k: Maximum number of samples in the sketch\n:type k: int\n" - ) - .def("__copy__", [](const ebpps_sketch& sk){ return ebpps_sketch(sk); }) - .def("__str__", [](const ebpps_sketch& sk) { return sk.to_string(); }, - "Produces a string summary of the sketch") - .def("to_string", - [](const ebpps_sketch& sk, bool print_items) { - std::ostringstream ss; - ss << sk.to_string(); - if (print_items) - ss << sk.items_to_string(); - return ss.str(); - }, nb::arg("print_items")=false, - "Produces a string summary of the sketch and optionally prints the items") - .def("update", (void (ebpps_sketch::*)(const T&, double)) &ebpps_sketch::update, nb::arg("item"), nb::arg("weight")=1.0, - "Updates the sketch with the given value and weight") - .def("merge", (void (ebpps_sketch::*)(const ebpps_sketch&)) &ebpps_sketch::merge, - nb::arg("sketch"), "Merges the sketch with the given sketch") - .def_prop_ro("k", &ebpps_sketch::get_k, - "The sketch's maximum configured sample size") - .def_prop_ro("n", &ebpps_sketch::get_n, - "The total stream length") - .def_prop_ro("c", &ebpps_sketch::get_c, - "The expected number of samples returned upon a call to get_result() or the creation of an iterator. " - "The number is a floating point value, where the fractional portion represents the probability of including " - "a \"partial item\" from the sample. The value C should be no larger than the sketch's configured value of k, " - "although numerical precision limitations mean it may exceed k by double precision floating point error margins in certain cases.") - .def("is_empty", &ebpps_sketch::is_empty, - "Returns True if the sketch is empty, otherwise False") - .def("get_serialized_size_bytes", - [](const ebpps_sketch& sk, py_object_serde& serde) { return sk.get_serialized_size_bytes(serde); }, - nb::arg("serde"), - "Computes the size in bytes needed to serialize the current sketch") - .def("serialize", - [](const ebpps_sketch& sk, py_object_serde& serde) { - auto bytes = sk.serialize(0, serde); - return nb::bytes(reinterpret_cast(bytes.data()), bytes.size()); - }, nb::arg("serde"), - "Serializes the sketch into a bytes object") - .def_static( - "deserialize", - [](const nb::bytes& bytes, py_object_serde& serde) { return ebpps_sketch::deserialize(bytes.c_str(), bytes.size(), serde); }, - nb::arg("bytes"), nb::arg("serde"), - "Reads a bytes object and returns the corresponding ebpps_sketch") - .def("__iter__", - [](const ebpps_sketch& sk) { - return nb::make_iterator(nb::type>(), - "ebpps_iterator", - sk.begin(), - sk.end()); - }, nb::keep_alive<0,1>() - ) - ; -} - -void init_ebpps(nb::module_ &m) { - bind_ebpps_sketch(m, "ebpps_sketch"); -} diff --git a/src/fi_wrapper.cpp b/src/fi_wrapper.cpp deleted file mode 100644 index c14debaf..00000000 --- a/src/fi_wrapper.cpp +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - - -#include "py_serde.hpp" -#include "py_object_ostream.hpp" -#include "frequent_items_sketch.hpp" - -#include -#include -#include - -#include -#include - -namespace pb = nanobind; - -// forward declarations -// std::string and arithmetic types, where we don't need a separate serde -template::value || std::is_same::value, bool>::type = 0> -void add_serialization(nb::class_>& clazz); - -// nb::object and other types where the caller must provide a serde -template::value && !std::is_same::value, bool>::type = 0> -void add_serialization(nb::class_>& clazz); - -template -void bind_fi_sketch(nb::module_ &m, const char* name) { - using namespace datasketches; - - auto fi_class = nb::class_>(m, name) - .def(nb::init(), nb::arg("lg_max_k"), - "Creates an instance of the sketch\n\n" - ":param lg_max_k: base 2 logarithm of the maximum size of the internal hash map of the sketch. Maximum " - "capacity is 0.75 of this value, which is the maximum number of distinct items the sketch can contain.\n" - ":type lg_max_k: int\n" - ) - .def("__copy__", [](const frequent_items_sketch& sk){ return frequent_items_sketch(sk); }) - .def("__str__", [](const frequent_items_sketch& sk) { return sk.to_string(); }, - "Produces a string summary of the sketch") - .def("to_string", &frequent_items_sketch::to_string, nb::arg("print_items")=false, - "Produces a string summary of the sketch") - .def("update", (void (frequent_items_sketch::*)(const T&, uint64_t)) &frequent_items_sketch::update, nb::arg("item"), nb::arg("weight")=1, - "Updates the sketch with the given string and, optionally, a weight") - .def("merge", (void (frequent_items_sketch::*)(const frequent_items_sketch&)) &frequent_items_sketch::merge, - "Merges the given sketch into this one") - .def("is_empty", &frequent_items_sketch::is_empty, - "Returns True if the sketch is empty, otherwise False") - .def_prop_ro("num_active_items", &frequent_items_sketch::get_num_active_items, - "The number of active items in the sketch") - .def_prop_ro("total_weight", &frequent_items_sketch::get_total_weight, - "The sum of the weights (frequencies) in the stream seen so far by the sketch") - .def("get_estimate", &frequent_items_sketch::get_estimate, nb::arg("item"), - "Returns the estimate of the weight (frequency) of the given item.\n" - "Note: The true frequency of a item would be the sum of the counts as a result of the " - "two update functions.") - .def("get_lower_bound", &frequent_items_sketch::get_lower_bound, nb::arg("item"), - "Returns the guaranteed lower bound weight (frequency) of the given item.") - .def("get_upper_bound", &frequent_items_sketch::get_upper_bound, nb::arg("item"), - "Returns the guaranteed upper bound weight (frequency) of the given item.") - .def_prop_ro("epsilon", (double (frequent_items_sketch::*)(void) const) &frequent_items_sketch::get_epsilon, - "The epsilon value used by the sketch to compute error") - .def( - "get_frequent_items", - [](const frequent_items_sketch& sk, frequent_items_error_type err_type, uint64_t threshold) { - if (threshold == 0) threshold = sk.get_maximum_error(); - nb::list list; - auto rows = sk.get_frequent_items(err_type, threshold); - for (auto row: rows) { - list.append(nb::make_tuple( - row.get_item(), - row.get_estimate(), - row.get_lower_bound(), - row.get_upper_bound()) - ); - } - return list; - }, - nb::arg("err_type"), nb::arg("threshold")=0 - ) - .def_static( - "get_epsilon_for_lg_size", - [](uint8_t lg_max_map_size) { return frequent_items_sketch::get_epsilon(lg_max_map_size); }, - nb::arg("lg_max_map_size"), - "Returns the epsilon value used to compute a priori error for a given log2(max_map_size)" - ) - .def_static( - "get_apriori_error", - &frequent_items_sketch::get_apriori_error, - nb::arg("lg_max_map_size"), nb::arg("estimated_total_weight"), - "Returns the estimated a priori error given the max_map_size for the sketch and the estimated_total_stream_weight." - ); - - // serialization may need a caller-provided serde depending on the sketch type, so - // we use a separate method to handle that appropriately based on type T. - add_serialization(fi_class); -} - -// std::string or arithmetic types, for which we have a built-in serde -template::value || std::is_same::value, bool>::type> -void add_serialization(nb::class_>& clazz) { - using namespace datasketches; - clazz.def( - "get_serialized_size_bytes", - [](const frequent_items_sketch& sk) { return sk.get_serialized_size_bytes(); }, - "Computes the size needed to serialize the current state of the sketch. This can be expensive since every item needs to be looked at." - ) - .def( - "serialize", - [](const frequent_items_sketch& sk) { - auto bytes = sk.serialize(); - return nb::bytes(reinterpret_cast(bytes.data()), bytes.size()); - }, - "Serializes the sketch into a bytes object." - ) - .def_static( - "deserialize", - [](const nb::bytes& bytes) { return frequent_items_sketch::deserialize(bytes.c_str(), bytes.size()); }, - nb::arg("bytes"), - "Reads a bytes object and returns the corresponding frequent_strings_sketch." - ); -} - -// nb::object or any other type that requires a provided serde -template::value && !std::is_same::value, bool>::type> -void add_serialization(nb::class_>& clazz) { - using namespace datasketches; - clazz.def( - "get_serialized_size_bytes", - [](const frequent_items_sketch& sk, py_object_serde& serde) { return sk.get_serialized_size_bytes(serde); }, - nb::arg("serde"), - "Computes the size needed to serialize the current state of the sketch using the provided serde. This can be expensive since every item needs to be looked at." - ) - .def( - "serialize", - [](const frequent_items_sketch& sk, py_object_serde& serde) { - auto bytes = sk.serialize(0, serde); - return nb::bytes(reinterpret_cast(bytes.data()), bytes.size()); - }, nb::arg("serde"), - "Serializes the sketch into a bytes object using the provided serde." - ) - .def_static( - "deserialize", - [](const nb::bytes& bytes, py_object_serde& serde) { - return frequent_items_sketch::deserialize(bytes.c_str(), bytes.size(), serde); - }, nb::arg("bytes"), nb::arg("serde"), - "Reads a bytes object using the provided serde and returns the corresponding frequent_strings_sketch." - ); -} - -// calls class __hash__ method -struct py_hash_caller { - virtual size_t operator()(const nb::object& a) const { - Py_hash_t result = PyObject_Hash(a.ptr()); - if (result == -1) { - throw nb::type_error("Could not compute hash value of object"); - } - return static_cast(result); - } -}; - -// calls class __eq__ method -struct py_equal_caller { - bool operator()(const nb::object& a, const nb::object& b) const { - return a.equal(b); - } -}; - -void init_fi(nb::module_ &m) { - using namespace datasketches; - - nb::enum_(m, "frequent_items_error_type") - .value("NO_FALSE_POSITIVES", NO_FALSE_POSITIVES, "Returns only true positives, but may miss some heavy hitters.") - .value("NO_FALSE_NEGATIVES", NO_FALSE_NEGATIVES, "Does not miss any heavy hitters, but may return false positives.") - .export_values(); - - bind_fi_sketch, std::equal_to>(m, "frequent_strings_sketch"); - bind_fi_sketch(m, "frequent_items_sketch"); -} diff --git a/src/hll_wrapper.cpp b/src/hll_wrapper.cpp deleted file mode 100644 index 51041ad3..00000000 --- a/src/hll_wrapper.cpp +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#include -#include - -#include "hll.hpp" - -namespace nb = nanobind; - -void init_hll(nb::module_ &m) { - using namespace datasketches; - - nb::enum_(m, "tgt_hll_type", "Target HLL flavor") - .value("HLL_4", HLL_4) - .value("HLL_6", HLL_6) - .value("HLL_8", HLL_8) - .export_values(); - - nb::class_(m, "hll_sketch") - .def(nb::init(), nb::arg("lg_k"), nb::arg("tgt_type")=HLL_8, nb::arg("start_max_size")=false, - "Constructs a new HLL sketch\n\n" - ":param lg_config_k: A full sketch can hold 2^lg_config_k rows. Must be between 7 and 21, inclusive,\n" - ":type lg_config_k: int\n" - ":param tgt_type: The HLL mode to use, if/when the sketch reaches estimation mode\n" - ":type tgt_type: tgt_hll_type\n" - ":param start_full_size: Indicates whether to start in HLL mode, keeping memory use constant (if HLL_6 or " - "HLL_8) at the cost of much higher initial memory use. Default (and recommended) is False.\n" - ":type start_full_size: bool" - ) - .def("__str__", [](const hll_sketch& sk) { return sk.to_string(); }, - "Produces a string summary of the sketch") - .def("to_string", (std::string (hll_sketch::*)(bool,bool,bool,bool) const) &hll_sketch::to_string, - nb::arg("summary")=true, nb::arg("detail")=false, nb::arg("aux_detail")=false, nb::arg("all")=false, - "Produces a string summary of the sketch") - .def_prop_ro("lg_config_k", &hll_sketch::get_lg_config_k, "Configured lg_k value for the sketch") - .def_prop_ro("tgt_type", &hll_sketch::get_target_type, "The HLL type (4, 6, or 8) when in estimation mode") - .def("get_estimate", &hll_sketch::get_estimate, - "Estimate of the distinct count of the input stream") - .def("get_lower_bound", &hll_sketch::get_lower_bound, nb::arg("num_std_devs"), - "Returns the approximate lower error bound given the specified number of standard deviations in {1, 2, 3}") - .def("get_upper_bound", &hll_sketch::get_upper_bound, nb::arg("num_std_devs"), - "Returns the approximate upper error bound given the specified number of standard deviations in {1, 2, 3}") - .def("is_compact", &hll_sketch::is_compact, - "True if the sketch is compact, otherwise False") - .def("is_empty", &hll_sketch::is_empty, - "True if the sketch is empty, otherwise False") - .def("get_updatable_serialization_bytes", &hll_sketch::get_updatable_serialization_bytes, - "Returns the size of the serialized sketch") - .def("get_compact_serialization_bytes", &hll_sketch::get_compact_serialization_bytes, - "Returns the size of the serialized sketch when compressing the exception table if HLL_4") - .def("reset", &hll_sketch::reset, - "Resets the sketch to the empty state in coupon collection mode") - .def("update", (void (hll_sketch::*)(int64_t)) &hll_sketch::update, nb::arg("datum"), - "Updates the sketch with the given integral value") - .def("update", (void (hll_sketch::*)(double)) &hll_sketch::update, nb::arg("datum"), - "Updates the sketch with the given floating point value") - .def("update", (void (hll_sketch::*)(const std::string&)) &hll_sketch::update, nb::arg("datum"), - "Updates the sketch with the given string value") - .def_static("get_max_updatable_serialization_bytes", &hll_sketch::get_max_updatable_serialization_bytes, - nb::arg("lg_k"), nb::arg("tgt_type"), - "Provides a likely upper bound on serialization size for the given parameters") - .def_static("get_rel_err", &hll_sketch::get_rel_err, - nb::arg("upper_bound"), nb::arg("unioned"), nb::arg("lg_k"), nb::arg("num_std_devs"), - "Returns the a priori relative error bound for the given parameters") - .def( - "serialize_compact", - [](const hll_sketch& sk) { - auto bytes = sk.serialize_compact(); - return nb::bytes(reinterpret_cast(bytes.data()), bytes.size()); - }, - "Serializes the sketch into a bytes object, compressing the exception table if HLL_4" - ) - .def( - "serialize_updatable", - [](const hll_sketch& sk) { - auto bytes = sk.serialize_updatable(); - return nb::bytes(reinterpret_cast(bytes.data()), bytes.size()); - }, - "Serializes the sketch into a bytes object" - ) - .def_static( - "deserialize", - [](const nb::bytes& bytes) { return hll_sketch::deserialize(bytes.c_str(), bytes.size()); }, - nb::arg("bytes"), - "Reads a bytes object and returns the corresponding hll_sketch" - ); - - nb::class_(m, "hll_union") - .def(nb::init(), nb::arg("lg_max_k"), - "Construct an hll_union object if the given size.\n\n" - ":param lg_max_k: The maximum size, in log2, of k. Must be between 7 and 21, inclusive.\n" - ":type lg_max_k: int" - ) - .def_prop_ro("lg_config_k", &hll_union::get_lg_config_k, "Configured lg_k value for the union") - .def("get_estimate", &hll_union::get_estimate, - "Estimate of the distinct count of the input stream") - .def("get_lower_bound", &hll_union::get_lower_bound, nb::arg("num_std_devs"), - "Returns the approximate lower error bound given the specified number of standard deviations in {1, 2, 3}") - .def("get_upper_bound", &hll_union::get_upper_bound, nb::arg("num_std_devs"), - "Returns the approximate upper error bound given the specified number of standard deviations in {1, 2, 3}") - .def("is_empty", &hll_union::is_empty, - "True if the union is empty, otherwise False") - .def("reset", &hll_union::reset, - "Resets the union to the empty state") - .def("get_result", &hll_union::get_result, nb::arg("tgt_type")=HLL_4, - "Returns a sketch of the target type representing the current union state") - .def("update", &hll_union::update, nb::arg("sketch"), - "Updates the union with the given HLL sketch") - .def("update", &hll_union::update, nb::arg("datum"), - "Updates the union with the given integral value") - .def("update", &hll_union::update, nb::arg("datum"), - "Updates the union with the given floating point value") - .def("update", &hll_union::update, nb::arg("datum"), - "Updates the union with the given string value") - .def_static("get_rel_err", &hll_union::get_rel_err, - nb::arg("upper_bound"), nb::arg("unioned"), nb::arg("lg_k"), nb::arg("num_std_devs"), - "Returns the a priori relative error bound for the given parameters") - ; -} diff --git a/src/kll_wrapper.cpp b/src/kll_wrapper.cpp deleted file mode 100644 index 694f6cff..00000000 --- a/src/kll_wrapper.cpp +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#include - -#include -#include -#include -#include - -#include "py_object_lt.hpp" -#include "py_object_ostream.hpp" -#include "quantile_conditional.hpp" - -#include "kll_sketch.hpp" - -namespace nb = nanobind; - -template -void bind_kll_sketch(nb::module_ &m, const char* name) { - using namespace datasketches; - - auto kll_class = nb::class_>(m, name) - .def(nb::init(), nb::arg("k")=kll_constants::DEFAULT_K, - "Creates a KLL sketch instance with the given value of k.\n\n" - ":param k: Controls the size/accuracy trade-off of the sketch. Default is 200.\n" - ":type k: int, optional" - ) - .def("__copy__", [](const kll_sketch& sk){ return kll_sketch(sk); }) - .def("update", static_cast::*)(const T&)>(&kll_sketch::update), nb::arg("item"), - "Updates the sketch with the given value") - .def("merge", (void (kll_sketch::*)(const kll_sketch&)) &kll_sketch::merge, nb::arg("sketch"), - "Merges the provided sketch into this one") - .def("__str__", [](const kll_sketch& sk) { return sk.to_string(); }, - "Produces a string summary of the sketch") - .def("to_string", &kll_sketch::to_string, nb::arg("print_levels")=false, nb::arg("print_items")=false, - "Produces a string summary of the sketch") - .def("is_empty", &kll_sketch::is_empty, - "Returns True if the sketch is empty, otherwise False") - .def_prop_ro("k", &kll_sketch::get_k, - "The configured parameter k") - .def_prop_ro("n", &kll_sketch::get_n, - "The length of the input stream") - .def_prop_ro("num_retained", &kll_sketch::get_num_retained, - "The number of retained items (samples) in the sketch") - .def("is_estimation_mode", &kll_sketch::is_estimation_mode, - "Returns True if the sketch is in estimation mode, otherwise False") - .def("get_min_value", &kll_sketch::get_min_item, - "Returns the minimum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError") - .def("get_max_value", &kll_sketch::get_max_item, - "Returns the maximum value from the stream. If empty, kll_floats_sketch returns nan; kll_ints_sketch throws a RuntimeError") - .def("get_quantile", &kll_sketch::get_quantile, nb::arg("rank"), nb::arg("inclusive")=false, - "Returns an approximation to the data value " - "associated with the given normalized rank in a hypothetical sorted " - "version of the input stream so far.\n" - "For kll_floats_sketch: if the sketch is empty this returns nan. " - "For kll_ints_sketch: if the sketch is empty this throws a RuntimeError.") - .def( - "get_quantiles", - [](const kll_sketch& sk, const std::vector& ranks, bool inclusive) { - std::vector quantiles; - if (!sk.is_empty()) { - quantiles.reserve(ranks.size()); - for (size_t i = 0; i < ranks.size(); ++i) quantiles.push_back(sk.get_quantile(ranks[i], inclusive)); - } - return quantiles; - }, - nb::arg("ranks"), nb::arg("inclusive")=false, - "This returns an array that could have been generated by using get_quantile() for each " - "normalized rank separately.\n" - "If the sketch is empty this returns an empty vector." - ) - .def("get_rank", &kll_sketch::get_rank, nb::arg("value"), nb::arg("inclusive")=false, - "Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive.\n" - "The resulting approximation has a probabilistic guarantee that can be obtained from the " - "get_normalized_rank_error(False) function.\n" - "With the parameter inclusive=true the weight of the given value is included into the rank." - "Otherwise the rank equals the sum of the weights of values less than the given value.\n" - "If the sketch is empty this returns nan.") - .def( - "get_pmf", - [](const kll_sketch& sk, const std::vector& split_points, bool inclusive) { - return sk.get_PMF(split_points.data(), split_points.size(), inclusive); - }, - nb::arg("split_points"), nb::arg("inclusive")=false, - "Returns an approximation to the Probability Mass Function (PMF) of the input stream " - "given a set of split points (values).\n" - "The resulting approximations have a probabilistic guarantee that can be obtained from the " - "get_normalized_rank_error(True) function.\n" - "If the sketch is empty this returns an empty vector.\n" - "split_points is an array of m unique, monotonically increasing float values " - "that divide the real number line into m+1 consecutive disjoint intervals.\n" - "If the parameter inclusive=false, the definition of an 'interval' is inclusive of the left split point (or minimum value) and " - "exclusive of the right split point, with the exception that the last interval will include " - "the maximum value.\n" - "If the parameter inclusive=true, the definition of an 'interval' is exclusive of the left split point (or minimum value) and " - "inclusive of the right split point.\n" - "It is not necessary to include either the min or max values in these split points." - ) - .def( - "get_cdf", - [](const kll_sketch& sk, const std::vector& split_points, bool inclusive) { - return sk.get_CDF(split_points.data(), split_points.size(), inclusive); - }, - nb::arg("split_points"), nb::arg("inclusive")=false, - "Returns an approximation to the Cumulative Distribution Function (CDF), which is the " - "cumulative analog of the PMF, of the input stream given a set of split points (values).\n" - "The resulting approximations have a probabilistic guarantee that can be obtained from the " - "get_normalized_rank_error(True) function.\n" - "If the sketch is empty this returns an empty vector.\n" - "split_points is an array of m unique, monotonically increasing float values " - "that divide the real number line into m+1 consecutive disjoint intervals.\n" - "If the parameter inclusive=false, the definition of an 'interval' is inclusive of the left split point (or minimum value) and " - "exclusive of the right split point, with the exception that the last interval will include " - "the maximum value.\n" - "If the parameter inclusive=true, the definition of an 'interval' is exclusive of the left split point (or minimum value) and " - "inclusive of the right split point.\n" - "It is not necessary to include either the min or max values in these split points." - ) - .def( - "normalized_rank_error", - static_cast::*)(bool) const>(&kll_sketch::get_normalized_rank_error), - nb::arg("as_pmf"), - "Gets the normalized rank error for this sketch.\n" - "If pmf is True, returns the 'double-sided' normalized rank error for the get_PMF() function.\n" - "Otherwise, it is the 'single-sided' normalized rank error for all the other queries.\n" - "Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials" - ) - .def_static( - "get_normalized_rank_error", - [](uint16_t k, bool pmf) { return kll_sketch::get_normalized_rank_error(k, pmf); }, - nb::arg("k"), nb::arg("as_pmf"), - "Gets the normalized rank error given parameters k and the pmf flag.\n" - "If pmf is True, returns the 'double-sided' normalized rank error for the get_PMF() function.\n" - "Otherwise, it is the 'single-sided' normalized rank error for all the other queries.\n" - "Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials" - ) - .def("__iter__", - [](const kll_sketch& s) { - return nb::make_iterator(nb::type>(), - "kll_iterator", - s.begin(), - s.end()); - }, nb::keep_alive<0, 1>() - ) - ; - - add_serialization(kll_class); - add_vector_update(kll_class); -} - -void init_kll(nb::module_ &m) { - bind_kll_sketch>(m, "kll_ints_sketch"); - bind_kll_sketch>(m, "kll_floats_sketch"); - bind_kll_sketch>(m, "kll_doubles_sketch"); - bind_kll_sketch(m, "kll_items_sketch"); -} diff --git a/src/ks_wrapper.cpp b/src/ks_wrapper.cpp deleted file mode 100644 index 0a77d6cb..00000000 --- a/src/ks_wrapper.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#include "kolmogorov_smirnov.hpp" -#include "kll_sketch.hpp" -#include "quantiles_sketch.hpp" -#include "py_object_lt.hpp" - -#include - -namespace nb = nanobind; - -void init_kolmogorov_smirnov(nb::module_ &m) { - using namespace datasketches; - - m.def("ks_test", &kolmogorov_smirnov::test>, nb::arg("sk_1"), nb::arg("sk_2"), nb::arg("p"), - "Performs the Kolmogorov-Smirnov Test for :code:`kll_ints_sketch` pairs.\n" - "Note: if the given sketches have insufficient data or if the sketch sizes are too small, " - "this will return false.\n" - "Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying " - "distribution) using the provided p-value, otherwise False."); - m.def("ks_test", &kolmogorov_smirnov::test>, nb::arg("sk_1"), nb::arg("sk_2"), nb::arg("p"), - "Performs the Kolmogorov-Smirnov Test for :code:`kll_floats_sketch` pairs.\n" - "Note: if the given sketches have insufficient data or if the sketch sizes are too small, " - "this will return false.\n" - "Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying " - "distribution) using the provided p-value, otherwise False."); - m.def("ks_test", &kolmogorov_smirnov::test>, nb::arg("sk_1"), nb::arg("sk_2"), nb::arg("p"), - "Performs the Kolmogorov-Smirnov Test for :code:`kll_doubles_sketch` pairs.\n" - "Note: if the given sketches have insufficient data or if the sketch sizes are too small, " - "this will return false.\n" - "Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying " - "distribution) using the provided p-value, otherwise False."); - m.def("ks_test", &kolmogorov_smirnov::test>, nb::arg("sk_1"), nb::arg("sk_2"), nb::arg("p"), - "Performs the Kolmogorov-Smirnov Test for :code:`kll_items_sketch` pairs.\n" - "Note: if the given sketches have insufficient data or if the sketch sizes are too small, " - "this will return false.\n" - "Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying " - "distribution) using the provided p-value, otherwise False."); - - m.def("ks_test", &kolmogorov_smirnov::test>, nb::arg("sk_1"), nb::arg("sk_2"), nb::arg("p"), - "Performs the Kolmogorov-Smirnov Test for :code:`quantiles_ints_sketch` pairs.\n" - "Note: if the given sketches have insufficient data or if the sketch sizes are too small, " - "this will return false.\n" - "Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying " - "distribution) using the provided p-value, otherwise False."); - m.def("ks_test", &kolmogorov_smirnov::test>, nb::arg("sk_1"), nb::arg("sk_2"), nb::arg("p"), - "Performs the Kolmogorov-Smirnov Test for :code:`quantiles_floats_sketch` pairs.\n" - "Note: if the given sketches have insufficient data or if the sketch sizes are too small, " - "this will return false.\n" - ":Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying " - "distribution) using the provided p-value, otherwise False."); - m.def("ks_test", &kolmogorov_smirnov::test>, nb::arg("sk_1"), nb::arg("sk_2"), nb::arg("p"), - "Performs the Kolmogorov-Smirnov Test for :code:`quantiles_doubles_sketch` pairs.\n" - "Note: if the given sketches have insufficient data or if the sketch sizes are too small, " - "this will return false.\n" - "Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying " - "distribution) using the provided p-value, otherwise False."); - m.def("ks_test", &kolmogorov_smirnov::test>, nb::arg("sk_1"), nb::arg("sk_2"), nb::arg("p"), - "Performs the Kolmogorov-Smirnov Test for :code:`quantiles_items_sketch` pairs.\n" - "Note: if the given sketches have insufficient data or if the sketch sizes are too small, " - "this will return false.\n" - "Returns True if we can reject the null hypothesis (that the sketches reflect the same underlying " - "distribution) using the provided p-value, otherwise False."); -} diff --git a/src/py_serde.cpp b/src/py_serde.cpp deleted file mode 100644 index a1896a63..00000000 --- a/src/py_serde.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#include -#include "memory_operations.hpp" - -#include "py_serde.hpp" - -#include - -namespace nb = nanobind; - -void init_serde(nb::module_& m) { - using namespace datasketches; - nb::class_(m, "PyObjectSerDe", - "An abstract base class for serde objects. All custom serdes must extend this class.") - .def(nb::init<>()) - .def("get_size", &py_object_serde::get_size, nb::arg("item"), - "Returns the size in bytes of an item\n\n" - ":param item: The specified object\n:type item: object\n" - ":return: The size of the item in bytes\n:rtype: int" - ) - .def("to_bytes", &py_object_serde::to_bytes, nb::arg("item"), - "Retuns a bytes object with a serialized version of an item\n\n" - ":param item: The specified object\n:type item: object\n" - ":return: A :class:`bytes` object with the serialized object\n:rtype: bytes" - ) - .def("from_bytes", &py_object_serde::from_bytes, nb::arg("data"), nb::arg("offset"), - "Reads a bytes object starting from the given offest and returns a tuple of the reconstructed " - "object and the number of additional bytes read\n\n" - ":param data: A :class:`bytes` object from which to deserialize\n:type data: bytes\n" - ":param offset: The offset, in bytes, at which to start reading\n:type offset: int\n" - ":return: A :class:`tuple` with the reconstructed object and the number of bytes read\n" - ":rtype: tuple(object, int)" - ) - ; -} - -namespace datasketches { - size_t py_object_serde::size_of_item(const nb::object& item) const { - return get_size(item); - } - - size_t py_object_serde::serialize(void* ptr, size_t capacity, const nb::object* items, unsigned num) const { - size_t bytes_written = 0; - nb::gil_scoped_acquire acquire; - for (unsigned i = 0; i < num; ++i) { - nb::bytes bytes = to_bytes(items[i]); // implicit cast from nb::bytes - check_memory_size(bytes_written + bytes.size(), capacity); - memcpy(ptr, bytes.c_str(), bytes.size()); - ptr = static_cast(ptr) + bytes.size(); - bytes_written += bytes.size(); - } - nb::gil_scoped_release release; - return bytes_written; - } - - size_t py_object_serde::deserialize(const void* ptr, size_t capacity, nb::object* items, unsigned num) const { - size_t bytes_read = 0; - unsigned i = 0; - bool failure = false; - bool error_from_python = false; - nb::gil_scoped_acquire acquire; - - // copy data into bytes only once - nb::bytes bytes(static_cast(ptr), capacity); - for (; i < num && !failure; ++i) { - nb::tuple bytes_and_len; - try { - bytes_and_len = from_bytes(bytes, bytes_read); - } catch (nb::python_error &e) { - failure = true; - error_from_python = true; - break; - } - - size_t length = nb::cast(bytes_and_len[1]); - if (bytes_read + length > capacity) { - bytes_read += length; // use this value to report the error - failure = true; - break; - } - - new (&items[i]) nb::object(nb::cast(bytes_and_len[0])); - ptr = static_cast(ptr) + length; - bytes_read += length; - } - - if (failure) { - // clean up what we've allocated - for (unsigned j = 0; j < i; ++j) { - items[j].dec_ref(); - } - - if (error_from_python) { - throw nb::value_error("Error reading value in from_bytes"); - } else { - // this next call will throw - check_memory_size(bytes_read, capacity); - } - } - - nb::gil_scoped_release release; - return bytes_read; - } - - -} // namespace datasketches \ No newline at end of file diff --git a/src/quantiles_wrapper.cpp b/src/quantiles_wrapper.cpp deleted file mode 100644 index fe830025..00000000 --- a/src/quantiles_wrapper.cpp +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#include -#include - -#include -#include -#include -#include - -#include "py_object_lt.hpp" -#include "py_object_ostream.hpp" -#include "quantile_conditional.hpp" -#include "quantiles_sketch.hpp" - - -namespace nb = nanobind; - -template -void bind_quantiles_sketch(nb::module_ &m, const char* name) { - using namespace datasketches; - - auto quantiles_class = nb::class_>(m, name) - .def(nb::init(), nb::arg("k")=quantiles_constants::DEFAULT_K, - "Creates a classic quantiles sketch instance with the given value of k.\n\n" - ":param k: Controls the size/accuracy trade-off of the sketch. Default is 128.\n" - ":type k: int, optional" - ) - .def("__copy__", [](const quantiles_sketch& sk) { return quantiles_sketch(sk); }) - .def( - "update", - static_cast::*)(const T&)>(&quantiles_sketch::update), - nb::arg("item"), - "Updates the sketch with the given value" - ) - .def("merge", (void (quantiles_sketch::*)(const quantiles_sketch&)) &quantiles_sketch::merge, nb::arg("sketch"), - "Merges the provided sketch into this one") - .def("__str__", [](const quantiles_sketch& sk) { return sk.to_string(); }, - "Produces a string summary of the sketch") - .def("to_string", &quantiles_sketch::to_string, nb::arg("print_levels")=false, nb::arg("print_items")=false, - "Produces a string summary of the sketch") - .def("is_empty", &quantiles_sketch::is_empty, - "Returns True if the sketch is empty, otherwise False") - .def_prop_ro("k", &quantiles_sketch::get_k, - "The configured parameter k") - .def_prop_ro("n", &quantiles_sketch::get_n, - "The length of the input stream") - .def_prop_ro("num_retained", &quantiles_sketch::get_num_retained, - "The number of retained items (samples) in the sketch") - .def("is_estimation_mode", &quantiles_sketch::is_estimation_mode, - "Returns True if the sketch is in estimation mode, otherwise False") - .def("get_min_value", &quantiles_sketch::get_min_item, - "Returns the minimum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError") - .def("get_max_value", &quantiles_sketch::get_max_item, - "Returns the maximum value from the stream. If empty, quantiles_floats_sketch returns nan; quantiles_ints_sketch throws a RuntimeError") - .def("get_quantile", &quantiles_sketch::get_quantile, nb::arg("rank"), nb::arg("inclusive")=false, - "Returns an approximation to the data value " - "associated with the given rank in a hypothetical sorted " - "version of the input stream so far.\n" - "For quantiles_floats_sketch: if the sketch is empty this returns nan. " - "For quantiles_ints_sketch: if the sketch is empty this throws a RuntimeError.") - .def( - "get_quantiles", - [](const quantiles_sketch& sk, const std::vector& ranks, bool inclusive) { - std::vector quantiles; - if (!sk.is_empty()) { - quantiles.reserve(ranks.size()); - for (size_t i = 0; i < ranks.size(); ++i) quantiles.push_back(sk.get_quantile(ranks[i], inclusive)); - } - return quantiles; - }, - nb::arg("ranks"), nb::arg("inclusive")=false, - "This returns an array that could have been generated by using get_quantile() for each " - "normalized rank separately.\n" - "If the sketch is empty this returns an empty vector." - ) - .def("get_rank", &quantiles_sketch::get_rank, nb::arg("value"), nb::arg("inclusive")=false, - "Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive.\n" - "The resulting approximation has a probabilistic guarantee that can be obtained from the " - "get_normalized_rank_error(False) function.\n" - "With the parameter inclusive=true the weight of the given value is included into the rank." - "Otherwise the rank equals the sum of the weights of values less than the given value.\n" - "If the sketch is empty this returns nan.") - .def( - "get_pmf", - [](const quantiles_sketch& sk, const std::vector& split_points, bool inclusive) { - return sk.get_PMF(split_points.data(), split_points.size(), inclusive); - }, - nb::arg("split_points"), nb::arg("inclusive")=false, - "Returns an approximation to the Probability Mass Function (PMF) of the input stream " - "given a set of split points (values).\n" - "The resulting approximations have a probabilistic guarantee that can be obtained from the " - "get_normalized_rank_error(True) function.\n" - "If the sketch is empty this returns an empty vector.\n" - "split_points is an array of m unique, monotonically increasing float values " - "that divide the real number line into m+1 consecutive disjoint intervals.\n" - "The definition of an 'interval' is inclusive of the left split point (or minimum value) and " - "exclusive of the right split point, with the exception that the last interval will include " - "the maximum value.\n" - "It is not necessary to include either the min or max values in these split points." - ) - .def( - "get_cdf", - [](const quantiles_sketch& sk, const std::vector& split_points, bool inclusive) { - return sk.get_CDF(split_points.data(), split_points.size(), inclusive); - }, - nb::arg("split_points"), nb::arg("inclusive")=false, - "Returns an approximation to the Cumulative Distribution Function (CDF), which is the " - "cumulative analog of the PMF, of the input stream given a set of split points (values).\n" - "The resulting approximations have a probabilistic guarantee that can be obtained from the " - "get_normalized_rank_error(True) function.\n" - "If the sketch is empty this returns an empty vector.\n" - "split_points is an array of m unique, monotonically increasing float values " - "that divide the real number line into m+1 consecutive disjoint intervals.\n" - "The definition of an 'interval' is inclusive of the left split point (or minimum value) and " - "exclusive of the right split point, with the exception that the last interval will include " - "the maximum value.\n" - "It is not necessary to include either the min or max values in these split points." - ) - .def( - "normalized_rank_error", - static_cast::*)(bool) const>(&quantiles_sketch::get_normalized_rank_error), - nb::arg("as_pmf"), - "Gets the normalized rank error for this sketch.\n" - "If pmf is True, returns the 'double-sided' normalized rank error for the get_PMF() function.\n" - "Otherwise, it is the 'single-sided' normalized rank error for all the other queries.\n" - "Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials" - ) - .def_static( - "get_normalized_rank_error", - [](uint16_t k, bool pmf) { return quantiles_sketch::get_normalized_rank_error(k, pmf); }, - nb::arg("k"), nb::arg("as_pmf"), - "Gets the normalized rank error given parameters k and the pmf flag.\n" - "If pmf is True, returns the 'double-sided' normalized rank error for the get_PMF() function.\n" - "Otherwise, it is the 'single-sided' normalized rank error for all the other queries.\n" - "Constants were derived as the best fit to 99 percentile empirically measured max error in thousands of trials" - ) - .def("__iter__", - [](const quantiles_sketch& s) { - return nb::make_iterator(nb::type>(), - "quantiles_iterator", - s.begin(), - s.end()); - }, nb::keep_alive<0,1>() - ) - ; - - add_serialization(quantiles_class); - add_vector_update(quantiles_class); -} - -void init_quantiles(nb::module_ &m) { - bind_quantiles_sketch>(m, "quantiles_ints_sketch"); - bind_quantiles_sketch>(m, "quantiles_floats_sketch"); - bind_quantiles_sketch>(m, "quantiles_doubles_sketch"); - bind_quantiles_sketch(m, "quantiles_items_sketch"); -} diff --git a/src/req_wrapper.cpp b/src/req_wrapper.cpp deleted file mode 100644 index 4f862b1f..00000000 --- a/src/req_wrapper.cpp +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#include -#include - -#include -#include -#include -#include - -#include "py_object_lt.hpp" -#include "py_object_ostream.hpp" -#include "quantile_conditional.hpp" -#include "req_sketch.hpp" - -namespace nb = nanobind; - -template -void bind_req_sketch(nb::module_ &m, const char* name) { - using namespace datasketches; - - auto req_class = nb::class_>(m, name) - .def(nb::init(), nb::arg("k")=12, nb::arg("is_hra")=true, - "Creates an REQ sketch instance with the given value of k.\n\n" - ":param k: Controls the size/accuracy trade-off of the sketch. Default is 12.\n" - ":type k: int, optional\n" - ":param is_hra: Specifies whether the skech has High Rank Accuracy (True) or Low Rank Accuracy. Default True.\n" - ":type is_hra: bool, optional" - ) - .def("__copy__", [](const req_sketch& sk){ return req_sketch(sk); }) - .def("update", (void (req_sketch::*)(const T&)) &req_sketch::update, nb::arg("item"), - "Updates the sketch with the given value") - .def("merge", (void (req_sketch::*)(const req_sketch&)) &req_sketch::merge, nb::arg("sketch"), - "Merges the provided sketch into this one") - .def("__str__", [](const req_sketch& sk) { return sk.to_string(); }, - "Produces a string summary of the sketch") - .def("to_string", &req_sketch::to_string, nb::arg("print_levels")=false, nb::arg("print_items")=false, - "Produces a string summary of the sketch") - .def("is_hra", &req_sketch::is_HRA, - "Returns True if the sketch is in High Rank Accuracy mode, otherwise False") - .def("is_empty", &req_sketch::is_empty, - "Returns True if the sketch is empty, otherwise False") - .def_prop_ro("k", &req_sketch::get_k, - "The configured parameter k") - .def_prop_ro("n", &req_sketch::get_n, - "The length of the input stream") - .def_prop_ro("num_retained", &req_sketch::get_num_retained, - "The number of retained items (samples) in the sketch") - .def("is_estimation_mode", &req_sketch::is_estimation_mode, - "Returns True if the sketch is in estimation mode, otherwise False") - .def("get_min_value", &req_sketch::get_min_item, - "Returns the minimum value from the stream. If empty, req_floats_sketch returns nan; req_ints_sketch throws a RuntimeError") - .def("get_max_value", &req_sketch::get_max_item, - "Returns the maximum value from the stream. If empty, req_floats_sketch returns nan; req_ints_sketch throws a RuntimeError") - .def("get_quantile", &req_sketch::get_quantile, nb::arg("rank"), nb::arg("inclusive")=false, - "Returns an approximation to the data value " - "associated with the given normalized rank in a hypothetical sorted " - "version of the input stream so far.\n" - "For req_floats_sketch: if the sketch is empty this returns nan. " - "For req_ints_sketch: if the sketch is empty this throws a RuntimeError.") - .def( - "get_quantiles", - [](const req_sketch& sk, const std::vector& ranks, bool inclusive) { - std::vector quantiles; - if (!sk.is_empty()) { - quantiles.reserve(ranks.size()); - for (size_t i = 0; i < ranks.size(); ++i) quantiles.push_back(sk.get_quantile(ranks[i], inclusive)); - } - return quantiles; - }, - nb::arg("ranks"), nb::arg("inclusive")=false, - "This returns an array that could have been generated by using get_quantile() for each " - "normalized rank separately.\n" - "If the sketch is empty this returns an empty vector." - ) - .def("get_rank", &req_sketch::get_rank, nb::arg("value"), nb::arg("inclusive")=false, - "Returns an approximation to the normalized rank of the given value from 0 to 1, inclusive.\n" - "The resulting approximation has a probabilistic guarantee that can be obtained from the " - "get_normalized_rank_error(False) function.\n" - "With the parameter inclusive=true the weight of the given value is included into the rank." - "Otherwise the rank equals the sum of the weights of values less than the given value.\n" - "If the sketch is empty this returns nan.") - .def( - "get_pmf", - [](const req_sketch& sk, const std::vector& split_points, bool inclusive) { - return sk.get_PMF(split_points.data(), split_points.size(), inclusive); - }, - nb::arg("split_points"), nb::arg("inclusive")=false, - "Returns an approximation to the Probability Mass Function (PMF) of the input stream " - "given a set of split points (values).\n" - "The resulting approximations have a probabilistic guarantee that can be obtained from the " - "get_normalized_rank_error(True) function.\n" - "If the sketch is empty this returns an empty vector.\n" - "split_points is an array of m unique, monotonically increasing float values " - "that divide the real number line into m+1 consecutive disjoint intervals.\n" - "If the parameter inclusive=false, the definition of an 'interval' is inclusive of the left split point (or minimum value) and " - "exclusive of the right split point, with the exception that the last interval will include " - "the maximum value.\n" - "If the parameter inclusive=true, the definition of an 'interval' is exclusive of the left split point (or minimum value) and " - "inclusive of the right split point.\n" - "It is not necessary to include either the min or max values in these split points." - ) - .def( - "get_cdf", - [](const req_sketch& sk, const std::vector& split_points, bool inclusive) { - return sk.get_CDF(split_points.data(), split_points.size(), inclusive); - }, - nb::arg("split_points"), nb::arg("inclusive")=false, - "Returns an approximation to the Cumulative Distribution Function (CDF), which is the " - "cumulative analog of the PMF, of the input stream given a set of split points (values).\n" - "The resulting approximations have a probabilistic guarantee that can be obtained from the " - "get_normalized_rank_error(True) function.\n" - "If the sketch is empty this returns an empty vector.\n" - "split_points is an array of m unique, monotonically increasing float values " - "that divide the real number line into m+1 consecutive disjoint intervals.\n" - "If the parameter inclusive=false, the definition of an 'interval' is inclusive of the left split point (or minimum value) and " - "exclusive of the right split point, with the exception that the last interval will include " - "the maximum value.\n" - "If the parameter inclusive=true, the definition of an 'interval' is exclusive of the left split point (or minimum value) and " - "inclusive of the right split point.\n" - "It is not necessary to include either the min or max values in these split points." - ) - .def("get_rank_lower_bound", &req_sketch::get_rank_lower_bound, nb::arg("rank"), nb::arg("num_std_dev"), - "Returns an approximate lower bound on the given normalized rank.\n" - "Normalized rank must be a value between 0.0 and 1.0 (inclusive); " - "the number of standard deviations must be 1, 2, or 3.") - .def("get_rank_upper_bound", &req_sketch::get_rank_upper_bound, nb::arg("rank"), nb::arg("num_std_dev"), - "Returns an approximate upper bound on the given normalized rank.\n" - "Normalized rank must be a value between 0.0 and 1.0 (inclusive); " - "the number of standard deviations must be 1, 2, or 3.") - .def_static("get_RSE", &req_sketch::get_RSE, - nb::arg("k"), nb::arg("rank"), nb::arg("is_hra"), nb::arg("n"), - "Returns an a priori estimate of relative standard error (RSE, expressed as a number in [0,1]). " - "Derived from Lemma 12 in http://arxiv.org/abs/2004.01668v2, but the constant factors have been " - "modified based on empirical measurements, for a given value of parameter k.\n" - "Normalized rank must be a value between 0.0 and 1.0 (inclusive). If is_hra is True, uses high " - "rank accuracy mode, else low rank accuracy. N is an estimate of the total number of points " - "provided to the sketch.") - .def("__iter__", - [](const req_sketch& s) { - return nb::make_iterator(nb::type>(), - "req_iterator", - s.begin(), - s.end()); - }, nb::keep_alive<0, 1>() - ) - ; - - add_serialization(req_class); - add_vector_update(req_class); -} - -void init_req(nb::module_ &m) { - bind_req_sketch>(m, "req_ints_sketch"); - bind_req_sketch>(m, "req_floats_sketch"); - bind_req_sketch(m, "req_items_sketch"); -} diff --git a/src/tdigest_wrapper.cpp b/src/tdigest_wrapper.cpp deleted file mode 100644 index 43248fb0..00000000 --- a/src/tdigest_wrapper.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#include -#include -#include // should ultimately be in tdigest.hpp - -#include -#include -#include -#include -#include - -#include "tdigest.hpp" -#include "quantile_conditional.hpp" - -namespace nb = nanobind; - -template -void bind_tdigest(nb::module_ &m, const char* name) { - using namespace datasketches; - - auto tdigest_class = nb::class_>(m, name) - .def(nb::init(), nb::arg("k")=tdigest::DEFAULT_K, - "Creates a tdigest instance with the given value of k.\n\n" - ":param k: Controls the size/accuracy trade-off of the sketch. Default is 200.\n" - ":type k: int, optional" - ) - .def("__copy__", [](const tdigest& sk) { return tdigest(sk); }) - .def("update", (void(tdigest::*)(T)) &tdigest::update, nb::arg("item"), - "Updates the sketch with the given value") - .def("merge", (void(tdigest::*)(const tdigest&)) &tdigest::merge, nb::arg("sketch"), - "Merges the provided sketch into this one") - .def("__str__", [](const tdigest& sk) { return sk.to_string(); }, - "Produces a string summary of the sketch") - .def("to_string", &tdigest::to_string, nb::arg("print_centroids")=false, - "Produces a string summary of the sketch") - .def("is_empty", &tdigest::is_empty, - "Returns True if the sketch is empty, otherwise False") - .def_prop_ro("k", &tdigest::get_k, - "The configured parameter k") - .def("get_total_weight", &tdigest::get_total_weight, - "The total weight processed by the sketch") - .def("compress", &tdigest::compress, - "Process buffered values and merge centroids, if necesssary") - .def("get_min_value", &tdigest::get_min_value, - "Returns the minimum value from the stream. If empty, throws a RuntimeError") - .def("get_max_value", &tdigest::get_max_value, - "Returns the maximum value from the stream. If empty, throws a RuntimeError") - .def("get_rank", &tdigest::get_rank, nb::arg("value"), - "Computes the approximate normalized rank of the given value") - .def("get_quantile", &tdigest::get_quantile, nb::arg("rank"), - "Returns an approximation to the data value " - "associated with the given rank in a hypothetical sorted " - "version of the input stream so far.\n") - .def("get_serialized_size_bytes", &tdigest::get_serialized_size_bytes, - nb::arg("with_buffer")=false, - "Returns the size of the serialized sketch, in bytes") - .def( - "get_pmf", - [](const tdigest& sk, const std::vector& split_points) { - return sk.get_PMF(split_points.data(), split_points.size()); - }, - nb::arg("split_points"), - "Returns an approximation to the Probability Mass Function (PMF) of the input stream " - "given a set of split points (values).\n" - "If the sketch is empty this returns an empty vector.\n" - "split_points is an array of m unique, monotonically increasing float values " - "that divide the real number line into m+1 consecutive disjoint intervals.\n" - "It is not necessary to include either the min or max values in these split points." - ) - .def( - "get_cdf", - [](const tdigest& sk, const std::vector& split_points) { - return sk.get_CDF(split_points.data(), split_points.size()); - }, - nb::arg("split_points"), - "Returns an approximation to the Cumulative Distribution Function (CDF), which is the " - "cumulative analog of the PMF, of the input stream given a set of split points (values).\n" - "If the sketch is empty this returns an empty vector.\n" - "split_points is an array of m unique, monotonically increasing float values " - "that divide the real number line into m+1 consecutive disjoint intervals.\n" - "It is not necessary to include either the min or max values in these split points." - ) - ; - - add_serialization(tdigest_class); - add_vector_update(tdigest_class); -} - -void init_tdigest(nb::module_ &m) { - bind_tdigest(m, "tdigest_float"); - bind_tdigest(m, "tdigest_double"); -} diff --git a/src/theta_wrapper.cpp b/src/theta_wrapper.cpp deleted file mode 100644 index 2915e175..00000000 --- a/src/theta_wrapper.cpp +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#include -#include -#include -#include -#include - -#include "theta_sketch.hpp" -#include "theta_union.hpp" -#include "theta_intersection.hpp" -#include "theta_a_not_b.hpp" -#include "theta_jaccard_similarity.hpp" -#include "common_defs.hpp" - -namespace nb = nanobind; - -void init_theta(nb::module_ &m) { - using namespace datasketches; - - nb::class_(m, "theta_sketch", "An abstract base class for theta sketches") - .def("__str__", [](const theta_sketch& sk) { return sk.to_string(); }, - "Produces a string summary of the sketch") - .def("to_string", [](const theta_sketch& sk, bool print_items) { return sk.to_string(print_items); }, nb::arg("print_items")=false, - "Produces a string summary of the sketch") - .def("is_empty", static_cast(&theta_sketch::is_empty), - "Returns True if the sketch is empty, otherwise False") - .def("get_estimate", static_cast(&theta_sketch::get_estimate), - "Estimate of the distinct count of the input stream") - .def("get_upper_bound", static_cast(&theta_sketch::get_upper_bound), nb::arg("num_std_devs"), - "Returns an approximate upper bound on the estimate at standard deviations in {1, 2, 3}") - .def("get_lower_bound", static_cast(&theta_sketch::get_lower_bound), nb::arg("num_std_devs"), - "Returns an approximate lower bound on the estimate at standard deviations in {1, 2, 3}") - .def("is_estimation_mode", static_cast(&theta_sketch::is_estimation_mode), - "Returns True if sketch is in estimation mode, otherwise False") - .def_prop_ro("theta", static_cast(&theta_sketch::get_theta), - "Theta (effective sampling rate) as a fraction from 0 to 1") - .def_prop_ro("theta64", static_cast(&theta_sketch::get_theta64), - "Theta as 64-bit value") - .def_prop_ro("num_retained", static_cast(&theta_sketch::get_num_retained), - "The number of items currently in the sketch") - .def("get_seed_hash", static_cast(&theta_sketch::get_seed_hash), - "Returns a hash of the seed used in the sketch") - .def("is_ordered", static_cast(&theta_sketch::is_ordered), - "Returns True if the sketch entries are sorted, otherwise False") - .def("__iter__", - [](const theta_sketch& s) { - return nb::make_iterator(nb::type(), - "theta_iterator", - s.begin(), - s.end()); - }, nb::keep_alive<0,1>() - ) - ; - - nb::class_(m, "update_theta_sketch") - .def("__init__", - [](update_theta_sketch* sk, uint8_t lg_k, double p, uint64_t seed) { - new (sk) update_theta_sketch(update_theta_sketch::builder().set_lg_k(lg_k).set_p(p).set_seed(seed).build()); - }, - nb::arg("lg_k")=theta_constants::DEFAULT_LG_K, nb::arg("p")=1.0, nb::arg("seed")=DEFAULT_SEED, - "Creates an update_theta_sketch using the provided parameters\n\n" - ":param lg_k: base 2 logarithm of the maximum size of the sketch. Default 12.\n:type lg_k: int, optional\n" - ":param p: an initial sampling rate to use. Default 1.0\n:type p: float, optional\n" - ":param seed: the seed to use when hashing values\n:type seed: int, optional\n" - ) - .def("__copy__", [](const update_theta_sketch& sk){ return update_theta_sketch(sk); }) - .def("update", (void (update_theta_sketch::*)(int64_t)) &update_theta_sketch::update, nb::arg("datum"), - "Updates the sketch with the given integral value") - .def("update", (void (update_theta_sketch::*)(double)) &update_theta_sketch::update, nb::arg("datum"), - "Updates the sketch with the given floating point value") - .def("update", (void (update_theta_sketch::*)(const std::string&)) &update_theta_sketch::update, nb::arg("datum"), - "Updates the sketch with the given string") - .def("compact", &update_theta_sketch::compact, nb::arg("ordered")=true, - "Returns a compacted form of the sketch, optionally sorting it") - .def("trim", &update_theta_sketch::trim, "Removes retained entries in excess of the nominal size k (if any)") - .def("reset", &update_theta_sketch::reset, "Resets the sketch to the initial empty state") - ; - - nb::class_(m, "compact_theta_sketch") - .def(nb::init(), - "Creates a compact_theta_sketch from an existing theta_sketch.\n\n" - ":param other: a source theta_sketch\n:type other: theta_sketch\n" - ":param ordered: whether the incoming sketch entries are sorted. Default True\n" - ":type ordered: bool" - ) - .def("__copy__", [](const compact_theta_sketch& sk){ return compact_theta_sketch(sk); }) - .def( - "serialize", - [](const compact_theta_sketch& sk, bool compress) { - auto bytes = compress ? sk.serialize_compressed() : sk.serialize(); - return nb::bytes(reinterpret_cast(bytes.data()), bytes.size()); - }, nb::arg("compress")=false, - "Serializes the sketch into a bytes object, optionally compressing the data" - ) - .def_static( - "deserialize", - [](const nb::bytes& bytes, uint64_t seed) { - return compact_theta_sketch::deserialize(bytes.c_str(), bytes.size(), seed); - }, - nb::arg("bytes"), nb::arg("seed")=DEFAULT_SEED, - "Reads a bytes object and returns the corresponding compact_theta_sketch" - ); - - nb::class_(m, "theta_union") - .def("__init__", - [](theta_union* u, uint8_t lg_k, double p, uint64_t seed) { - new (u) theta_union(theta_union::builder().set_lg_k(lg_k).set_p(p).set_seed(seed).build()); - }, - nb::arg("lg_k")=theta_constants::DEFAULT_LG_K, nb::arg("p")=1.0, nb::arg("seed")=DEFAULT_SEED, - "Creates a theta_union using the provided parameters\n\n" - ":param lg_k: base 2 logarithm of the maximum size of the union. Default 12.\n:type lg_k: int, optional\n" - ":param p: an initial sampling rate to use. Default 1.0\n:type p: float, optional\n" - ":param seed: the seed to use when hashing values. Must match all sketch seeds.\n:type seed: int, optional" - ) - .def("update", &theta_union::update, nb::arg("sketch"), - "Updates the union with the given sketch") - .def("get_result", &theta_union::get_result, nb::arg("ordered")=true, - "Returns the sketch corresponding to the union result") - ; - - nb::class_(m, "theta_intersection") - .def(nb::init(), nb::arg("seed")=DEFAULT_SEED, - "Creates a theta_intersection using the provided parameters\n\n" - ":param seed: the seed to use when hashing values. Must match all sketch seeds\n:type seed: int, optional" - ) - .def("update", &theta_intersection::update, nb::arg("sketch"), - "Intersections the provided sketch with the current intersection state") - .def("get_result", &theta_intersection::get_result, nb::arg("ordered")=true, - "Returns the sketch corresponding to the intersection result") - .def("has_result", &theta_intersection::has_result, - "Returns True if the intersection has a valid result, otherwise False") - ; - - nb::class_(m, "theta_a_not_b") - .def(nb::init(), nb::arg("seed")=DEFAULT_SEED, - "Creates a tuple_a_not_b object\n\n" - ":param seed: the seed to use when hashing values. Must match all sketch seeds.\n:type seed: int, optional" - ) - .def( - "compute", - &theta_a_not_b::compute, - nb::arg("a"), nb::arg("b"), nb::arg("ordered")=true, - "Returns a sketch with the result of applying the A-not-B operation on the given inputs" - ) - ; - - nb::class_(m, "theta_jaccard_similarity", - "An object to help compute Jaccard similarity between theta sketches.") - .def_static( - "jaccard", - [](const theta_sketch& sketch_a, const theta_sketch& sketch_b, uint64_t seed) { - return theta_jaccard_similarity::jaccard(sketch_a, sketch_b, seed); - }, - nb::arg("sketch_a"), nb::arg("sketch_b"), nb::arg("seed")=DEFAULT_SEED, - "Returns a list with {lower_bound, estimate, upper_bound} of the Jaccard similarity between sketches" - ) - .def_static( - "exactly_equal", - &theta_jaccard_similarity::exactly_equal, - nb::arg("sketch_a"), nb::arg("sketch_b"), nb::arg("seed")=DEFAULT_SEED, - "Returns True if sketch_a and sketch_b are equivalent, otherwise False" - ) - .def_static( - "similarity_test", - &theta_jaccard_similarity::similarity_test, - nb::arg("actual"), nb::arg("expected"), nb::arg("threshold"), nb::arg("seed")=DEFAULT_SEED, - "Tests similarity of an actual sketch against an expected sketch. Computers the lower bound of the Jaccard " - "index J_{LB} of the actual and expected sketches. If J_{LB} >= threshold, then the sketches are considered " - "to be similar with a confidence of 97.7% and returns True, otherwise False.") - .def_static( - "dissimilarity_test", - &theta_jaccard_similarity::dissimilarity_test, - nb::arg("actual"), nb::arg("expected"), nb::arg("threshold"), nb::arg("seed")=DEFAULT_SEED, - "Tests dissimilarity of an actual sketch against an expected sketch. Computers the lower bound of the Jaccard " - "index J_{UB} of the actual and expected sketches. If J_{UB} <= threshold, then the sketches are considered " - "to be dissimilar with a confidence of 97.7% and returns True, otherwise False." - ) - ; -} diff --git a/src/tuple_wrapper.cpp b/src/tuple_wrapper.cpp deleted file mode 100644 index 6563e5bd..00000000 --- a/src/tuple_wrapper.cpp +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "py_serde.hpp" -#include "py_object_ostream.hpp" -#include "tuple_policy.hpp" - -#include "theta_sketch.hpp" -#include "tuple_sketch.hpp" -#include "tuple_union.hpp" -#include "tuple_intersection.hpp" -#include "tuple_a_not_b.hpp" -#include "theta_jaccard_similarity_base.hpp" -#include "common_defs.hpp" - -namespace nb = nanobind; - -void init_tuple(nb::module_ &m) { - using namespace datasketches; - - // generic tuple_policy: - // * update sketch policy uses create_summary and update_summary - // * set operation policies all use __call__ - nb::class_(m, "TuplePolicy", - nb::intrusive_ptr( - [](tuple_policy *tp, PyObject *po) noexcept { tp->set_self_py(po); }), - "An abstract base class for Tuple Policy objects. All custom policies must extend this class.") - .def(nb::init()) - .def("create_summary", &tuple_policy::create_summary, - "Creates a new Summary object\n\n" - ":return: a Summary object\n:rtype: :class:`object`" - ) - .def("update_summary", &tuple_policy::update_summary, nb::arg("summary"), nb::arg("update"), - "Applies the relevant policy to update the provided summary with the data in update.\n\n" - ":param summary: An existing Summary\n:type summary: :class:`object`\n" - ":param update: An update to apply to the Summary\n:type update: :class:`object`\n" - ":return: The updated Summary\n:rtype: :class:`object`" - ) - .def("__call__", &tuple_policy::operator(), nb::arg("summary"), nb::arg("update"), - "Similar to update_summary but allows a different implementation for set operations (union and intersection)\n\n" - ":param summary: An existing Summary\n:type summary: :class:`object`\n" - ":param update: An update to apply to the Summary\n:type update: :class:`object`\n" - ":return: The updated Summary\n:rtype: :class:`object`" - ) - ; - - using py_tuple_sketch = tuple_sketch; - using py_update_tuple = update_tuple_sketch; - using py_compact_tuple = compact_tuple_sketch; - using py_tuple_union = tuple_union; - using py_tuple_intersection = tuple_intersection; - using py_tuple_a_not_b = tuple_a_not_b; - using py_tuple_jaccard_similarity = jaccard_similarity_base, tuple_intersection, pair_extract_key>; - - nb::class_(m, "tuple_sketch", "An abstract base class for tuple sketches.") - .def("__str__", [](const py_tuple_sketch& sk) { return sk.to_string(); }, - "Produces a string summary of the sketch") - .def("to_string", &py_tuple_sketch::to_string, nb::arg("print_items")=false, - "Produces a string summary of the sketch") - .def("is_empty", &py_tuple_sketch::is_empty, - "Returns True if the sketch is empty, otherwise False") - .def("get_estimate", &py_tuple_sketch::get_estimate, - "Estimate of the distinct count of the input stream") - .def("get_upper_bound", static_cast(&py_tuple_sketch::get_upper_bound), nb::arg("num_std_devs"), - "Returns an approximate upper bound on the estimate at standard deviations in {1, 2, 3}") - .def("get_lower_bound", static_cast(&py_tuple_sketch::get_lower_bound), nb::arg("num_std_devs"), - "Returns an approximate lower bound on the estimate at standard deviations in {1, 2, 3}") - .def("is_estimation_mode", &py_tuple_sketch::is_estimation_mode, - "Returns True if sketch is in estimation mode, otherwise False") - .def_prop_ro("theta", &py_tuple_sketch::get_theta, - "Theta (effective sampling rate) as a fraction from 0 to 1") - .def_prop_ro("theta64", &py_tuple_sketch::get_theta64, - "Theta as 64-bit value") - .def_prop_ro("num_retained", &py_tuple_sketch::get_num_retained, - "The number of items currently in the sketch") - .def("get_seed_hash", [](const py_tuple_sketch& sk) { return sk.get_seed_hash(); }, // why does regular call not work?? - "Returns a hash of the seed used in the sketch") - .def("is_ordered", &py_tuple_sketch::is_ordered, - "Returns True if the sketch entries are sorted, otherwise False") - .def("__iter__", - [](const py_tuple_sketch& s) { - return nb::make_iterator(nb::type(), - "tuple_iterator", - s.begin(), - s.end()); - }, nb::keep_alive<0,1>() - ) - .def_prop_ro_static("DEFAULT_SEED", [](nb::object /* self */) { return DEFAULT_SEED; }); - ; - - nb::class_(m, "compact_tuple_sketch") - .def(nb::init(), nb::arg("other"), nb::arg("ordered")=true, - "Creates a compact_tuple_sketch from an existing tuple_sketch.\n\n" - ":param other: a sourch tuple_sketch\n:type other: tuple_sketch\n" - ":param ordered: whether the incoming sketch entries are sorted. Default True\n" - ":type ordered: bool, optional" - ) - .def(nb::init(), nb::arg("other"), nb::arg("summary"), - "Creates a compact_tuple_sketch from a theta_sketch using a fixed summary value.\n\n" - ":param other: a source theta sketch\n:type other: theta_sketch\n" - ":param summary: a summary to use for every sketch entry\n:type summary: object" - ) - .def("__copy__", [](const py_compact_tuple& sk){ return py_compact_tuple(sk); }) - .def( - "serialize", - [](const py_compact_tuple& sk, py_object_serde& serde) { - auto bytes = sk.serialize(0, serde); - return nb::bytes(reinterpret_cast(bytes.data()), bytes.size()); - }, nb::arg("serde"), - "Serializes the sketch into a bytes object" - ) - .def("filter", - [](const py_compact_tuple& sk, const std::function func) { - return sk.filter(func); - }, nb::arg("predicate"), - "Produces a compact_tuple_sketch from the given sketch by applying a predicate to " - "the summary in each entry.\n\n" - ":param predicate: A function returning true or value evaluated on each tuple summary\n" - ":return: A compact_tuple_sketch with the selected entries\n:rtype: :class:`compact_tuple_sketch`") - .def_static( - "deserialize", - [](const nb::bytes& bytes, py_object_serde& serde, uint64_t seed) { - return py_compact_tuple::deserialize(bytes.c_str(), bytes.size(), seed, serde); - }, - nb::arg("bytes"), nb::arg("serde"), nb::arg("seed")=DEFAULT_SEED, - "Reads a bytes object and returns the corresponding compact_tuple_sketch" - ); - - nb::class_(m, "update_tuple_sketch") - .def("__init__", - [](py_update_tuple* sk, tuple_policy* policy, uint8_t lg_k, double p, uint64_t seed) { - tuple_policy_holder holder(policy); - new (sk) py_update_tuple(py_update_tuple::builder(holder).set_lg_k(lg_k).set_p(p).set_seed(seed).build()); - }, - nb::arg("policy"), nb::arg("lg_k")=theta_constants::DEFAULT_LG_K, nb::arg("p")=1.0, nb::arg("seed")=DEFAULT_SEED, - "Creates an update_tuple_sketch using the provided parameters\n\n" - ":param policy: a policy to use when updating\n:type policy: TuplePolicy\n" - ":param lg_k: base 2 logarithm of the maximum size of the sketch. Default 12.\n:type lg_k: int, optional\n" - ":param p: an initial sampling rate to use. Default 1.0\n:type p: float, optional\n" - ":param seed: the seed to use when hashing values\n:type seed: int, optional" - ) - .def("__copy__", [](const py_update_tuple& sk){ return py_update_tuple(sk); }) - .def("update", static_cast(&py_update_tuple::update), - nb::arg("datum"), nb::arg("value"), - "Updates the sketch with the given integral item and summary value") - .def("update", static_cast(&py_update_tuple::update), - nb::arg("datum"), nb::arg("value"), - "Updates the sketch with the given floating point item and summary value") - .def("update", static_cast(&py_update_tuple::update), - nb::arg("datum"), nb::arg("value"), - "Updates the sketch with the given string item and summary value") - .def("compact", &py_update_tuple::compact, nb::arg("ordered")=true, - "Returns a compacted form of the sketch, optionally sorting it") - .def("trim", &py_update_tuple::trim, "Removes retained entries in excess of the nominal size k (if any)") - .def("reset", &py_update_tuple::reset, "Resets the sketch to the initial empty state") - .def("filter", - [](const py_update_tuple& sk, const std::function func) { - return sk.filter(func); - }, nb::arg("predicate"), - "Produces a compact_tuple_sketch from the given sketch by applying a predicate to " - "the summary in each entry.\n\n" - ":param predicate: A function returning true or value evaluated on each tuple summary\n" - ":return: A compact_tuple_sketch with the selected entries\n:rtype: :class:`compact_tuple_sketch`") - ; - - nb::class_(m, "tuple_union") - .def("__init__", - [](py_tuple_union* u, tuple_policy* policy, uint8_t lg_k, double p, uint64_t seed) { - tuple_policy_holder holder(policy); - new (u) py_tuple_union(py_tuple_union::builder(holder).set_lg_k(lg_k).set_p(p).set_seed(seed).build()); - }, - nb::arg("policy"), nb::arg("lg_k")=theta_constants::DEFAULT_LG_K, nb::arg("p")=1.0, nb::arg("seed")=DEFAULT_SEED, - "Creates a tuple_union using the provided parameters\n\n" - ":param policy: a policy to use when unioning entries\n:type policy: TuplePolicy\n" - ":param lg_k: base 2 logarithm of the maximum size of the union. Default 12.\n:type lg_k: int, optional\n" - ":param p: an initial sampling rate to use. Default 1.0\n:type p: float, optional\n" - ":param seed: the seed to use when hashing values. Must match any sketch seeds.\n:type seed: int, optional" - ) - .def("update", &py_tuple_union::update, nb::arg("sketch"), - "Updates the union with the given sketch") - .def("get_result", &py_tuple_union::get_result, nb::arg("ordered")=true, - "Returns the sketch corresponding to the union result") - .def("reset", &py_tuple_union::reset, - "Resets the sketch to the initial empty") - ; - - nb::class_(m, "tuple_intersection") - .def("__init__", - [](py_tuple_intersection* sk, tuple_policy* policy, uint64_t seed) { - tuple_policy_holder holder(policy); - new (sk) py_tuple_intersection(seed, holder); - }, - nb::arg("policy"), nb::arg("seed")=DEFAULT_SEED, - "Creates a tuple_intersection using the provided parameters\n\n" - ":param policy: a policy to use when intersecting entries\n:type policy: TuplePolicy\n" - ":param seed: the seed to use when hashing values. Must match any sketch seeds\n:type seed: int, optional" - ) - .def("update", &py_tuple_intersection::update, nb::arg("sketch"), - "Intersects the provided sketch with the current intersection state") - .def("get_result", &py_tuple_intersection::get_result, nb::arg("ordered")=true, - "Returns the sketch corresponding to the intersection result") - .def("has_result", &py_tuple_intersection::has_result, - "Returns True if the intersection has a valid result, otherwise False") - ; - - nb::class_(m, "tuple_a_not_b") - .def(nb::init(), nb::arg("seed")=DEFAULT_SEED, - "Creates a tuple_a_not_b object\n\n" - ":param seed: the seed to use when hashing values. Must match any sketch seeds.\n:type seed: int, optional" - ) - .def( - "compute", - &py_tuple_a_not_b::compute, - nb::arg("a"), nb::arg("b"), nb::arg("ordered")=true, - "Returns a sketch with the result of applying the A-not-B operation on the given inputs" - ) - ; - - nb::class_(m, "tuple_jaccard_similarity", - "An object to help compute Jaccard similarity between tuple sketches.") - .def_static( - "jaccard", - [](const py_tuple_sketch& sketch_a, const py_tuple_sketch& sketch_b, uint64_t seed) { - return py_tuple_jaccard_similarity::jaccard(sketch_a, sketch_b, seed); - }, - nb::arg("sketch_a"), nb::arg("sketch_b"), nb::arg("seed")=DEFAULT_SEED, - "Returns a list with {lower_bound, estimate, upper_bound} of the Jaccard similarity between sketches" - ) - .def_static( - "exactly_equal", - &py_tuple_jaccard_similarity::exactly_equal, - nb::arg("sketch_a"), nb::arg("sketch_b"), nb::arg("seed")=DEFAULT_SEED, - "Returns True if sketch_a and sketch_b are equivalent, otherwise False" - ) - .def_static( - "similarity_test", - &py_tuple_jaccard_similarity::similarity_test, - nb::arg("actual"), nb::arg("expected"), nb::arg("threshold"), nb::arg("seed")=DEFAULT_SEED, - "Tests similarity of an actual sketch against an expected sketch. Computes the lower bound of the Jaccard " - "index J_{LB} of the actual and expected sketches. If J_{LB} >= threshold, then the sketches are considered " - "to be similar with a confidence of 97.7% and returns True, otherwise False.") - .def_static( - "dissimilarity_test", - &py_tuple_jaccard_similarity::dissimilarity_test, - nb::arg("actual"), nb::arg("expected"), nb::arg("threshold"), nb::arg("seed")=DEFAULT_SEED, - "Tests dissimilarity of an actual sketch against an expected sketch. Computes the upper bound of the Jaccard " - "index J_{UB} of the actual and expected sketches. If J_{UB} <= threshold, then the sketches are considered " - "to be dissimilar with a confidence of 97.7% and returns True, otherwise False." - ) - ; -} diff --git a/src/vector_of_kll.cpp b/src/vector_of_kll.cpp deleted file mode 100644 index 3bbe17b6..00000000 --- a/src/vector_of_kll.cpp +++ /dev/null @@ -1,586 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "kll_sketch.hpp" - -namespace nb = nanobind; - -namespace datasketches { - -namespace vector_of_kll_constants { - static const uint32_t DEFAULT_K = kll_constants::DEFAULT_K; - static const uint32_t DEFAULT_D = 1; -} - -// Wrapper class for Numpy compatibility -template > -class vector_of_kll_sketches { - public: - explicit vector_of_kll_sketches(uint32_t k = vector_of_kll_constants::DEFAULT_K, uint32_t d = vector_of_kll_constants::DEFAULT_D); - vector_of_kll_sketches(const vector_of_kll_sketches& other); - vector_of_kll_sketches(vector_of_kll_sketches&& other) noexcept; - vector_of_kll_sketches& operator=(const vector_of_kll_sketches& other); - vector_of_kll_sketches& operator=(vector_of_kll_sketches&& other); - - // container parameters - inline uint32_t get_k() const; - inline uint32_t get_d() const; - - template - using Array1D = nb::ndarray>; - - template - using Array2D = nb::ndarray, nb::c_contig>; - - // sketch updates/merges - void update(nb::ndarray& items, char order); - void merge(const vector_of_kll_sketches& other); - - template - using ArrInputType = std::variant, nb::list, V>; - - // returns a single sketch combining all data in the array - kll_sketch collapse(ArrInputType& isk) const; - - // sketch queries returning an array of results - Array1D is_empty() const; - Array1D get_n() const; - Array1D is_estimation_mode() const; - Array1D get_min_values() const; - Array1D get_max_values() const; - Array1D get_num_retained() const; - Array2D get_quantiles(ArrInputType& ranks, ArrInputType& isk) const; - Array2D get_ranks(ArrInputType& values, ArrInputType& isk) const; - Array2D get_pmf(ArrInputType& split_points, ArrInputType& isk) const; - Array2D get_cdf(ArrInputType& split_points, ArrInputType& isk) const; - - // human-readable output - std::string to_string(bool print_levels = false, bool print_items = false) const; - - // binary output/input - nb::list serialize(ArrInputType& isk); - // note: deserialize() replaces the sketch at the specified - // index. Not a static method. - void deserialize(const nb::bytes& sk_bytes, uint32_t idx); - - private: - template - Array1D input_to_vec(ArrInputType& input) const; - - Array1D get_indices(Array1D& isk) const; - - template - Array1D make_ndarray(size_t size) const; - - template - Array2D make_ndarray(size_t rows, size_t cols) const; - - const uint32_t k_; // kll sketch k parameter - const uint32_t d_; // number of dimensions (here: sketches) to hold - std::vector> sketches_; -}; - -template -vector_of_kll_sketches::vector_of_kll_sketches(uint32_t k, uint32_t d): -k_(k), -d_(d) -{ - // check d is valid (k is checked by kll_sketch) - if (d < 1) { - throw std::invalid_argument("D must be >= 1: " + std::to_string(d)); - } - - sketches_.reserve(d); - // spawn the sketches - for (uint32_t i = 0; i < d; i++) { - sketches_.emplace_back(k); - } -} - -template -vector_of_kll_sketches::vector_of_kll_sketches(const vector_of_kll_sketches& other) : - k_(other.k_), - d_(other.d_), - sketches_(other.sketches_) -{} - -template -vector_of_kll_sketches::vector_of_kll_sketches(vector_of_kll_sketches&& other) noexcept : - k_(other.k_), - d_(other.d_), - sketches_(std::move(other.sketches_)) -{} - -template -vector_of_kll_sketches& vector_of_kll_sketches::operator=(const vector_of_kll_sketches& other) { - vector_of_kll_sketches copy(other); - k_ = copy.k_; - d_ = copy.d_; - std::swap(sketches_, copy.sketches_); - return *this; -} - -template -vector_of_kll_sketches& vector_of_kll_sketches::operator=(vector_of_kll_sketches&& other) { - k_ = other.k_; - d_ = other.d_; - std::swap(sketches_, other.sketches_); - return *this; -} - -template -uint32_t vector_of_kll_sketches::get_k() const { - return k_; -} - -template -uint32_t vector_of_kll_sketches::get_d() const { - return d_; -} - -template -template -auto vector_of_kll_sketches::make_ndarray(size_t size) const -> Array1D { - TT* data = new TT[size]; - - nb::capsule owner(data, [](void *p) noexcept { - delete[] static_cast(p); - }); - - return Array1D(data, {size}, owner); -} - -template -template -auto vector_of_kll_sketches::make_ndarray(size_t rows, size_t cols) const -> Array2D { - TT* data = new TT[rows * cols]; - - nb::capsule owner(data, [](void *p) noexcept { - delete[] static_cast(p); - }); - - return Array2D(data, {rows, cols}, owner); -} - -template -template -auto vector_of_kll_sketches::input_to_vec(ArrInputType& input) const -> Array1D { - if (std::holds_alternative>(input)) { - nb::ndarray<> arr = std::get>(input); - return Array1D(arr); - } else if (std::holds_alternative(input)) { - nb::list list = std::get(input); - Array1D output = make_ndarray(list.size()); - for (size_t i = 0; i < list.size(); ++i) - output(i) = nb::cast(list[i]); - return output; - } else if (std::holds_alternative(input)) { - Array1D output = make_ndarray(1); - output(0) = std::get(input); - return output; - } else { - nb::raise_type_error("Unknown input type"); - } -} - -template -auto vector_of_kll_sketches::get_indices(Array1D& isk) const -> Array1D { - auto input = isk.view>(); - size_t num_input = input.shape(0); - Array1D output; - - if (num_input == 1) { - if (input(0) == -1) { - output = make_ndarray(d_); - for (uint32_t i = 0; i < d_; ++i) { - output(i) = i; - } - } else { - output = make_ndarray(1); - output(0) = static_cast(input(0)); - } - } else { - output = make_ndarray(num_input); - for (uint32_t i = 0; i < num_input; ++i) { - const uint32_t idx = static_cast(input(i)); - if (idx < d_) { - output(i) = idx; - } else { - throw std::invalid_argument("request for invalid dimensions >= d (" - + std::to_string(d_) +"): "+ std::to_string(idx)); - } - } - } - return output; -} - -// Checks if each sketch is empty or not -template -auto vector_of_kll_sketches::is_empty() const -> Array1D { - auto vals = make_ndarray(d_); - auto view = vals.view(); - for (uint32_t i = 0; i < d_; ++i) { - view(i) = sketches_[i].is_empty(); - } - return vals; -} - -// Updates each sketch with values -// Currently: all values must be present -// TODO: allow subsets of sketches to be updated -template -void vector_of_kll_sketches::update(nb::ndarray& items, char order) { - size_t ndim = items.ndim(); - - if (items.shape(ndim-1) != d_) { - throw std::invalid_argument("input data must have rows with " + std::to_string(d_) - + " elements. Found: " + std::to_string(items.shape(ndim-1))); - } - - if (ndim == 1) { - // 1D case: single value to update per sketch - const T* data = items.data(); - for (uint32_t i = 0; i < d_; ++i) { - sketches_[i].update(data[i]); - } - } - else if (ndim == 2) { - // 2D case: multiple values to update per sketch - // We could speedthis up by using raw array access and pre-computing an offset for the - // row/column, but if we use the wrong ordering the computation would be incorrect. - // By using a view and dereferencing by (row, column) each time we ensure correct - // processing at the cost of an extra multiply each derference. Using a mismatched - // ordering versus the actual data storage will be potentially slower but will still - // produce correct output. - auto data = items.template view>(); - if (order == 'F' || order == 'f') { // Fortran-style (column-major) order - for (uint32_t j = 0; j < d_; ++j) { - const size_t offset = j * d_; - for (uint32_t i = 0; i < items.shape(0); ++i) { - sketches_[j].update(data(i, j)); - } - } - } else { // nb::c_contig or nb::any_contig - for (uint32_t i = 0; i < items.shape(0); ++i) { - const size_t offset = i * items.shape(0); - for (uint32_t j = 0; j < d_; ++j) { - sketches_[j].update(data(i, j)); - } - } - } - } - else { - throw std::invalid_argument("Update input must be 2 or fewer dimensions : " + std::to_string(ndim)); - } -} - -// Merges two arrays of sketches -// Currently: all values must be present -template -void vector_of_kll_sketches::merge(const vector_of_kll_sketches& other) { - if (d_ != other.get_d()) { - throw std::invalid_argument("Must have same number of dimensions to merge: " + std::to_string(d_) - + " vs " + std::to_string(other.d_)); - } else { - for (uint32_t i = 0; i < d_; ++i) { - sketches_[i].merge(other.sketches_[i]); - } - } -} - -template -kll_sketch vector_of_kll_sketches::collapse(ArrInputType& isk) const { - Array1D indices = input_to_vec(isk); - Array1D index_arr = get_indices(indices); - auto inds = index_arr.view(); - - kll_sketch result(k_); - for (size_t idx = 0; idx < inds.shape(0); ++idx) { - result.merge(sketches_[inds(idx)]); - } - return result; -} - -// Number of updates for each sketch -template -auto vector_of_kll_sketches::get_n() const -> Array1D { - auto vals = make_ndarray(d_); - auto view = vals.view(); - for (uint32_t i = 0; i < d_; ++i) { - view(i) = sketches_[i].get_n(); - } - return vals; -} - -// Number of retained values for each sketch -template -auto vector_of_kll_sketches::get_num_retained() const -> Array1D { - auto vals = make_ndarray(d_); - auto view = vals.view(); - for (uint32_t i = 0; i < d_; ++i) { - view(i) = sketches_[i].get_num_retained(); - } - return vals; -} - -// Gets the minimum value of each sketch -// TODO: allow subsets of sketches -template -auto vector_of_kll_sketches::get_min_values() const -> Array1D { - //std::vector vals(d_); - auto vals = make_ndarray(d_); - auto view = vals.view(); - for (uint32_t i = 0; i < d_; ++i) { - view(i) = sketches_[i].get_min_item(); - } - return vals; -} - -// Gets the maximum value of each sketch -// TODO: allow subsets of sketches -template -auto vector_of_kll_sketches::get_max_values() const -> Array1D { - auto vals = make_ndarray(d_); - auto view = vals.view(); - for (uint32_t i = 0; i < d_; ++i) { - view(i) = sketches_[i].get_max_item(); - } - return vals; -} - -// Summary of each sketch as one long string -// Users should use .split('\n\n') when calling it to build a list of each -// sketch's summary -template -std::string vector_of_kll_sketches::to_string(bool print_levels, bool print_items) const { - std::ostringstream ss; - for (uint32_t i = 0; i < d_; ++i) { - // all streams into 1 string, for compatibility with Python's str() behavior - // users will need to split by \n\n, e.g., str(kll).split('\n\n') - if (i > 0) ss << "\n"; - ss << sketches_[i].to_string(print_levels, print_items); - } - return ss.str(); -} - -template -auto vector_of_kll_sketches::is_estimation_mode() const -> Array1D { - auto vals = make_ndarray(d_); - auto view = vals.view(); - for (uint32_t i = 0; i < d_; ++i) { - view(i) = sketches_[i].is_estimation_mode(); - } - return vals; -} - -// Value of sketch(es) corresponding to some quantile(s) -template -auto vector_of_kll_sketches::get_quantiles(ArrInputType& ranks, - ArrInputType& isk) const -> Array2D { - Array1D indices = input_to_vec(isk); - Array1D inds = get_indices(indices); - size_t num_sketches = inds.size(); - - Array1D ranks_arr = input_to_vec(ranks); - size_t num_quantiles = ranks_arr.size(); - - auto quants = make_ndarray(num_sketches, num_quantiles); - auto view = quants.view(); - auto ranks_view = ranks_arr.view(); - for (uint32_t i = 0; i < num_sketches; ++i) { - for (size_t j = 0; j < num_quantiles; ++j) { - view(i, j) = sketches_[inds(i)].get_quantile(ranks_view(j)); - } - } - return quants; -} - -// Value of sketch(es) corresponding to some rank(s) -template -auto vector_of_kll_sketches::get_ranks(ArrInputType& values, - ArrInputType& isk) const -> Array2D { - Array1D indices = input_to_vec(isk); - Array1D inds = get_indices(indices); - size_t num_sketches = inds.size(); - - Array1D values_arr = input_to_vec(values); - size_t num_ranks = values_arr.size(); - auto vals = values_arr.view(); - - auto ranks = make_ndarray(num_sketches, num_ranks); - auto view = ranks.view(); - for (uint32_t i = 0; i < num_sketches; ++i) { - const size_t offset = i * num_ranks; - for (size_t j = 0; j < num_ranks; ++j) { - view(i, j) = sketches_[inds(i)].get_rank(vals(j)); - } - } - return ranks; -} - -// PMF(s) of sketch(es) -template -auto vector_of_kll_sketches::get_pmf(ArrInputType& split_points, - ArrInputType& isk) const -> Array2D { - Array1D indices = input_to_vec(isk); - Array1D inds = get_indices(indices); - size_t num_sketches = inds.size(); - - Array1D splits_arr = input_to_vec(split_points); - size_t num_splits = splits_arr.size(); - - auto pmfs = make_ndarray(num_sketches, num_splits + 1); - auto view = pmfs.view(); - for (uint32_t i = 0; i < num_sketches; ++i) { - auto pmf = sketches_[inds(i)].get_PMF(splits_arr.data(), num_splits); - for (size_t j = 0; j <= num_splits; ++j) { - view(i, j) = pmf[j]; - } - } - return pmfs; -} - -// CDF(s) of sketch(es) -template -auto vector_of_kll_sketches::get_cdf(ArrInputType& split_points, - ArrInputType& isk) const -> Array2D { - Array1D indices = input_to_vec(isk); - Array1D inds = get_indices(indices); - size_t num_sketches = inds.size(); - - Array1D splits_arr = input_to_vec(split_points); - size_t num_splits = splits_arr.size(); - - auto cdfs = make_ndarray(num_sketches, num_splits + 1); - auto view = cdfs.view(); - for (uint32_t i = 0; i < num_sketches; ++i) { - auto cdf = sketches_[inds(i)].get_CDF(splits_arr.data(), num_splits); - for (size_t j = 0; j <= num_splits; ++j) { - view(i, j) = cdf[j]; - } - } - return cdfs; -} - -template -void vector_of_kll_sketches::deserialize(const nb::bytes& sk_bytes, - uint32_t idx) { - if (idx >= d_) { - throw std::invalid_argument("request for invalid dimensions >= d (" - + std::to_string(d_) +"): "+ std::to_string(idx)); - } - // load the sketch into the proper index - sketches_[idx] = std::move(kll_sketch::deserialize(sk_bytes.c_str(), sk_bytes.size())); -} - -template -nb::list vector_of_kll_sketches::serialize(ArrInputType& isk) { - Array1D indices = input_to_vec(isk); - Array1D inds = get_indices(indices); - const size_t num_sketches = inds.size(); - - nb::list list; - for (uint32_t i = 0; i < num_sketches; ++i) { - auto serResult = sketches_[inds(i)].serialize(); - list.append(nb::bytes((char*)serResult.data(), serResult.size())); - } - - return list; -} - -} // namespace datasketches - -template -void bind_vector_of_kll_sketches(nb::module_ &m, const char* name) { - using namespace datasketches; - - nb::class_>(m, name) - .def(nb::init(), nb::arg("k")=vector_of_kll_constants::DEFAULT_K, - nb::arg("d")=vector_of_kll_constants::DEFAULT_D, - "Creates a new Vector of KLL Sketches instance with the given values of k and d.\n\n" - ":param k: The value of k for every sketch in the vector\n:type k: int\n" - ":param d: The number of sketches in the vector\n:type d: int" - ) - .def("__copy__", [](const vector_of_kll_sketches& sk){ return vector_of_kll_sketches(sk); }) - // allow user to retrieve k or d, in case it's instantiated w/ defaults - .def_prop_ro("k", &vector_of_kll_sketches::get_k, - "The value of `k` of the sketch(es)") - .def_prop_ro("d", &vector_of_kll_sketches::get_d, - "The number of sketches") - .def("update", &vector_of_kll_sketches::update, nb::arg("items"), nb::arg("order") = "C", - "Updates the sketch(es) with value(s). Must be a 1D array of size equal to the number of sketches. Can also be 2D array of shape (n_updates, n_sketches). If a sketch does not have a value to update, use np.nan. " - " Order 'F' specifies a column-major (Fortran style) matrix; any other value assumes row-major (C style) matrix.") - .def("__str__", [](const vector_of_kll_sketches& sk) { return sk.to_string(); }, - "Produces a string summary of all sketches. Users should split the returned string by '\\n\\n'") - .def("to_string", &vector_of_kll_sketches::to_string, nb::arg("print_levels")=false, - nb::arg("print_items")=false, - "Produces a string summary of all sketches. Users should split the returned string by '\\n\\n'") - .def("is_empty", &vector_of_kll_sketches::is_empty, - "Returns whether the sketch(es) is(are) empty of not") - .def("get_n", &vector_of_kll_sketches::get_n, - "Returns the number of values seen by the sketch(es)") - .def("get_num_retained", &vector_of_kll_sketches::get_num_retained, - "Returns the number of values retained by the sketch(es)") - .def("is_estimation_mode", &vector_of_kll_sketches::is_estimation_mode, - "Returns whether the sketch(es) is(are) in estimation mode") - .def("get_min_values", &vector_of_kll_sketches::get_min_values, - "Returns the minimum value(s) of the sketch(es)") - .def("get_max_values", &vector_of_kll_sketches::get_max_values, - "Returns the maximum value(s) of the sketch(es)") - .def("get_quantiles", &vector_of_kll_sketches::get_quantiles, nb::arg("ranks"), - nb::arg("isk")=-1, - "Returns the value(s) associated with the specified quantile(s) for the specified sketch(es). `ranks` can be a float between 0 and 1 (inclusive), or a list/array of values. `isk` specifies which sketch(es) to return the value(s) for (default: all sketches)") - .def("get_ranks", &vector_of_kll_sketches::get_ranks, - nb::arg("value"), nb::arg("isk")=-1, - "Returns the value(s) associated with the specified rank(s) for the specified sketch(es). `values` can be an int between 0 and the number of values retained, or a list/array of values. `isk` specifies which sketch(es) to return the value(s) for (default: all sketches)") - .def("get_pmf", &vector_of_kll_sketches::get_pmf, nb::arg("split_points"), nb::arg("isk")=-1, - "Returns the probability mass function (PMF) at `split_points` of the specified sketch(es). `split_points` should be a list/array of floats between 0 and 1 (inclusive). `isk` specifies which sketch(es) to return the PMF for (default: all sketches)") - .def("get_cdf", &vector_of_kll_sketches::get_cdf, nb::arg("split_points"), nb::arg("isk")=-1, - "Returns the cumulative distribution function (CDF) at `split_points` of the specified sketch(es). `split_points` should be a list/array of floats between 0 and 1 (inclusive). `isk` specifies which sketch(es) to return the CDF for (default: all sketches)") - .def_static("get_normalized_rank_error", - [](uint16_t k, bool pmf) { return kll_sketch::get_normalized_rank_error(k, pmf); }, - nb::arg("k"), nb::arg("as_pmf"), "Returns the normalized rank error") - .def("serialize", &vector_of_kll_sketches::serialize, nb::arg("isk")=-1, - "Serializes the specified sketch(es). `isk` can be an int or a list/array of ints (default: all sketches)") - .def("deserialize", &vector_of_kll_sketches::deserialize, nb::arg("skBytes"), nb::arg("isk"), - "Deserializes the specified sketch. `isk` must be an int.") - .def("merge", &vector_of_kll_sketches::merge, nb::arg("array_of_sketches"), - "Merges the input array of KLL sketches into the existing array.") - .def("collapse", &vector_of_kll_sketches::collapse, nb::arg("isk")=-1, - "Returns the result of collapsing all sketches in the array into a single sketch. 'isk' can be an int or a list/array of ints (default: all sketches)") - ; -} - -void init_vector_of_kll(nb::module_ &m) { - bind_vector_of_kll_sketches(m, "vector_of_kll_ints_sketches"); - bind_vector_of_kll_sketches(m, "vector_of_kll_floats_sketches"); -} diff --git a/src/vo_wrapper.cpp b/src/vo_wrapper.cpp deleted file mode 100644 index ef0eb671..00000000 --- a/src/vo_wrapper.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#include -#include -#include -#include - -#include "py_serde.hpp" -#include "py_object_ostream.hpp" - -#include "var_opt_sketch.hpp" -#include "var_opt_union.hpp" - -namespace nb = nanobind; - -template -void bind_vo_sketch(nb::module_ &m, const char* name) { - using namespace datasketches; - - nb::class_>(m, name) - .def(nb::init(), nb::arg("k"), - "Creates a new Var Opt sketch instance\n\n" - ":param k: Maximum number of samples in the sketch\n:type k: int\n" - ) - .def("__copy__", [](const var_opt_sketch& sk){ return var_opt_sketch(sk); }) - .def("__str__", [](const var_opt_sketch& sk) { return sk.to_string(); }, - "Produces a string summary of the sketch") - .def("to_string", - [](const var_opt_sketch& sk, bool print_items) { - std::ostringstream ss; - ss << sk.to_string(); - if (print_items) - ss << sk.items_to_string(); - return ss.str(); - }, nb::arg("print_items")=false, - "Produces a string summary of the sketch and optionally prints the items") - .def("update", (void (var_opt_sketch::*)(const T&, double)) &var_opt_sketch::update, nb::arg("item"), nb::arg("weight")=1.0, - "Updates the sketch with the given value and weight") - .def_prop_ro("k", &var_opt_sketch::get_k, - "Returns the sketch's maximum configured sample size") - .def_prop_ro("n", &var_opt_sketch::get_n, - "Returns the total stream length") - .def_prop_ro("num_samples", &var_opt_sketch::get_num_samples, - "Returns the number of samples currently in the sketch") - .def("is_empty", &var_opt_sketch::is_empty, - "Returns True if the sketch is empty, otherwise False") - .def("estimate_subset_sum", - [](const var_opt_sketch& sk, const std::function func) { - subset_summary summary = sk.estimate_subset_sum(func); - nb::dict d; - d["estimate"] = summary.estimate; - d["lower_bound"] = summary.lower_bound; - d["upper_bound"] = summary.upper_bound; - d["total_sketch_weight"] = summary.total_sketch_weight; - return d; - }, nb::arg("predicate"), - "Applies a provided predicate to the sketch and returns the estimated total weight matching the predicate, as well " - "as upper and lower bounds on the estimate and the total weight processed by the sketch") - .def("get_serialized_size_bytes", - [](const var_opt_sketch& sk, py_object_serde& serde) { return sk.get_serialized_size_bytes(serde); }, - nb::arg("serde"), - "Computes the size in bytes needed to serialize the current sketch") - .def("serialize", - [](const var_opt_sketch& sk, py_object_serde& serde) { - auto bytes = sk.serialize(0, serde); - return nb::bytes(reinterpret_cast(bytes.data()), bytes.size()); - }, nb::arg("serde"), - "Serializes the sketch into a bytes object") - .def_static( - "deserialize", - [](const nb::bytes& bytes, py_object_serde& serde) { return var_opt_sketch::deserialize(bytes.c_str(), bytes.size(), serde); }, - nb::arg("bytes"), nb::arg("serde"), - "Reads a bytes object and returns the corresponding var opt sketch") - .def("__iter__", - [](const var_opt_sketch& sk) { - return nb::make_iterator(nb::type>(), - "var_opt_iterator", - sk.begin(), - sk.end()); - }, nb::keep_alive<0,1>() - ) - ; -} - -template -void bind_vo_union(nb::module_ &m, const char* name) { - using namespace datasketches; - - nb::class_>(m, name) - .def(nb::init(), nb::arg("max_k")) - .def("__str__", [](const var_opt_union& sk) { return sk.to_string(); }, - "Produces a string summary of the sketch") - .def("to_string", &var_opt_union::to_string, - "Produces a string summary of the sketch") - .def("update", (void (var_opt_union::*)(const var_opt_sketch& sk)) &var_opt_union::update, nb::arg("sketch"), - "Updates the union with the given sketch") - .def("get_result", &var_opt_union::get_result, - "Returns a sketch corresponding to the union result") - .def("reset", &var_opt_union::reset, - "Resets the union to the empty state") - .def("get_serialized_size_bytes", - [](const var_opt_union& u, py_object_serde& serde) { return u.get_serialized_size_bytes(serde); }, - nb::arg("serde"), - "Computes the size in bytes needed to serialize the current union") - .def("serialize", - [](const var_opt_union& u, py_object_serde& serde) { - auto bytes = u.serialize(0, serde); - return nb::bytes(reinterpret_cast(bytes.data()), bytes.size()); - }, nb::arg("serde"), - "Serializes the union into a bytes object with the provided serde") - .def_static( - "deserialize", - [](const nb::bytes& bytes, py_object_serde& serde) { return var_opt_union::deserialize(bytes.c_str(), bytes.size(), serde); }, - nb::arg("bytes"), nb::arg("serde"), - "Constructs a var opt union from the given bytes using the provided serde") - ; -} - -void init_vo(nb::module_ &m) { - bind_vo_sketch(m, "var_opt_sketch"); - bind_vo_union(m, "var_opt_union"); -} diff --git a/tests/__init__.py b/tests/__init__.py deleted file mode 100644 index 13a83393..00000000 --- a/tests/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. diff --git a/tests/count_min_test.py b/tests/count_min_test.py deleted file mode 100644 index 42b5d9bc..00000000 --- a/tests/count_min_test.py +++ /dev/null @@ -1,90 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -import unittest -from datasketches import count_min_sketch - -class CountMinTest(unittest.TestCase): - def test_count_min_example(self): - # we'll define target confidence and relative error and use the built-in - # methods to determine how many hashes and buckets to use - confidence = 0.95 - num_hashes = count_min_sketch.suggest_num_hashes(confidence) - relative_error = 0.01 - num_buckets = count_min_sketch.suggest_num_buckets(relative_error) - - # now we can create a few empty sketches - cm = count_min_sketch(num_hashes, num_buckets) - cm2 = count_min_sketch(num_hashes, num_buckets) - self.assertTrue(cm.is_empty()) - - # we'll use a moderate number of distinct items with - # increasing weights, with each item's weight being - # equal to its value - n = 1000 - total_wt = 0 - for i in range(1, n+1): - cm.update(i, i) - total_wt += i - self.assertFalse(cm.is_empty()) - self.assertEqual(cm.total_weight, total_wt) - - # querying the items, each of them should - # have a non-zero count. the estimate should - # be at least i with appropriately behaved bounds. - for i in range(1, n+1): - val = cm.get_estimate(i) - self.assertGreaterEqual(val, i) - self.assertGreaterEqual(val, cm.get_lower_bound(i)) - self.assertGreater(cm.get_upper_bound(i), val) - - # values not in the sketch should have lower estimates, but - # are not guaranteed to be zero and will succeed - self.assertIsNotNone(cm.get_estimate("not in set")) - - # we can create another sketch with partial overlap - # and merge them - for i in range(int(n / 2), int(3 * n / 2)): - cm2.update(i, i) - cm.merge(cm2) - - # and the estimated weight for the overlapped meerged values - # (n/2 to n) should now be at least 2x the value - self.assertGreaterEqual(cm.get_estimate(n), 2 * n) - - # finally, serialize and reconstruct - cm_bytes = cm.serialize() - self.assertEqual(cm.get_serialized_size_bytes(), len(cm_bytes)) - new_cm = count_min_sketch.deserialize(cm_bytes) - - # and now interrogate the sketch - self.assertFalse(new_cm.is_empty()) - self.assertEqual(new_cm.num_hashes, cm.num_hashes) - self.assertEqual(new_cm.num_buckets, cm.num_buckets) - self.assertEqual(new_cm.total_weight, cm.total_weight) - - # we can also iterate through values in and out of the sketch to ensure - # the estimates match - for i in range(0, 2 * n): - self.assertEqual(cm.get_estimate(i), new_cm.get_estimate(i)) - - # finally just check that printing works as expected - self.assertGreater(len(cm.to_string()), 0) - self.assertEqual(len(cm.__str__()), len(cm.to_string())) - -if __name__ == '__main__': - unittest.main() diff --git a/tests/cpc_test.py b/tests/cpc_test.py deleted file mode 100644 index fb1b40ee..00000000 --- a/tests/cpc_test.py +++ /dev/null @@ -1,73 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -import unittest -from datasketches import cpc_sketch, cpc_union - -class CpcTest(unittest.TestCase): - def test_cpc_example(self): - lgk = 12 # 2^k = 4096 rows in the table - n = 1 << 18 # ~256k distinct values - - # create a couple sketches and inject some values - # we'll have 1/4 of the values overlap - cpc = cpc_sketch(lgk) - cpc2 = cpc_sketch(lgk) - offset = int(3 * n / 4) # it's a float w/o cast - # because we hash on the bits, not an abstract numeric value, - # cpc.update(1) and cpc.update(1.0) give different results. - for i in range(0, n): - cpc.update(i) - cpc2.update(i + offset) - - # although we provide get_composite_estimate() and get_estimate(), - # the latter will always give the best available estimate. we - # recommend using get_estimate(). - # we can check that the upper and lower bounds bracket the - # estimate, without needing to know the exact value. - self.assertLessEqual(cpc.get_lower_bound(1), cpc.get_estimate()) - self.assertGreaterEqual(cpc.get_upper_bound(1), cpc.get_estimate()) - - # union is a separate class, so we need to get_result() - # to query the unioned sketches - union = cpc_union(lgk) - union.update(cpc) - union.update(cpc2) - result = union.get_result() - - # since our process here (including post-union CPC) is - # deterministic, we have checked and know the exact - # answer is within one standard deviation of the estimate - self.assertLessEqual(result.get_lower_bound(1), 7 * n / 4) - self.assertGreaterEqual(result.get_upper_bound(1), 7 * n / 4) - - # serialize for storage and reconstruct - sk_bytes = result.serialize() - new_cpc = cpc_sketch.deserialize(sk_bytes) - self.assertFalse(new_cpc.is_empty()) - - # finally just check that printing works as expected - self.assertGreater(len(cpc.to_string()), 0) - self.assertEqual(len(cpc.__str__()), len(cpc.to_string())) - - def test_cpc_get_lg_k(self): - lgk = 10 - cpc = cpc_sketch(lgk) - self.assertEqual(cpc.lg_k, lgk) - -if __name__ == '__main__': - unittest.main() diff --git a/tests/density_test.py b/tests/density_test.py deleted file mode 100644 index 4dd66f45..00000000 --- a/tests/density_test.py +++ /dev/null @@ -1,97 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -import unittest -from datasketches import density_sketch, KernelFunction, GaussianKernel -import numpy as np - -class UnitSphereKernel(KernelFunction): - def __call__(self, a: np.ndarray, b: np.ndarray) -> float: - if np.linalg.norm(a - b) < 1.0: - return 1.0 - else: - return 0.0 - -class densityTest(unittest.TestCase): - def test_density_sketch(self): - k = 10 - dim = 3 - n = 1000 - - sketch = density_sketch(k, dim, GaussianKernel()) - - self.assertEqual(sketch.k, k) - self.assertEqual(sketch.dim, dim) - self.assertTrue(sketch.is_empty()) - self.assertFalse(sketch.is_estimation_mode()) - self.assertEqual(sketch.n, 0) - self.assertEqual(sketch.num_retained, 0) - - for i in range(n): - sketch.update([i, i, i]) - - self.assertFalse(sketch.is_empty()) - self.assertTrue(sketch.is_estimation_mode()) - self.assertEqual(sketch.n, n) - self.assertGreater(sketch.num_retained, k) - self.assertLess(sketch.num_retained, n) - self.assertGreater(sketch.get_estimate([n - 1, n - 1, n - 1]), 0) - - for tuple in sketch: - vector = tuple[0] - weight = tuple[1] - self.assertEqual(len(vector), dim) - self.assertGreaterEqual(weight, 1) - - sk_bytes = sketch.serialize() - sketch2 = density_sketch.deserialize(sk_bytes, GaussianKernel()) - self.assertEqual(sketch.get_estimate([1.5, 2.5, 3.5]), sketch2.get_estimate([1.5, 2.5, 3.5])) - - # check that printing works as expected - self.assertGreater(len(sketch.to_string(True, True)), 0) - self.assertEqual(len(sketch.__str__()), len(sketch.to_string())) - - def test_density_merge(self): - sketch1 = density_sketch(10, 2, GaussianKernel()) - sketch1.update([0, 0]) - sketch2 = density_sketch(10, 2, GaussianKernel()) - sketch2.update([0, 1]) - sketch1.merge(sketch2) - self.assertEqual(sketch1.n, 2) - self.assertEqual(sketch1.num_retained, 2) - - def test_custom_kernel(self): - gaussianSketch = density_sketch(10, 2, GaussianKernel()) - sphericalSketch = density_sketch(10, 2, UnitSphereKernel()) - - p = [1, 1] - gaussianSketch.update(p) - sphericalSketch.update(p) - - # Spherical kernel should return 1.0 for a nearby point, 0 farther - # Gaussian kernel should return something nonzero when farther away - self.assertEqual(sphericalSketch.get_estimate([1.001, 1]), 1.0) - self.assertEqual(sphericalSketch.get_estimate([2, 2]), 0.0) - self.assertGreater(gaussianSketch.get_estimate([2, 2]), 0.0) - - # We can also use a custom kernel when deserializing - sk_bytes = sphericalSketch.serialize() - sphericalRebuilt = density_sketch.deserialize(sk_bytes, UnitSphereKernel()) - self.assertEqual(sphericalSketch.get_estimate([1.001, 1]), sphericalRebuilt.get_estimate([1.001, 1])) - -if __name__ == '__main__': - unittest.main() diff --git a/tests/ebpps_test.py b/tests/ebpps_test.py deleted file mode 100644 index 76a3d367..00000000 --- a/tests/ebpps_test.py +++ /dev/null @@ -1,117 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -import unittest -from math import floor, ceil -from datasketches import ebpps_sketch, PyIntsSerDe, PyStringsSerDe - -class EbppsTest(unittest.TestCase): - def test_ebpps_example(self): - k = 50 # a small value so we can easily fill the sketch - sk = ebpps_sketch(k) - - # ebpps sampling reduces to standard reservoir sampling - # if the items are all equally weighted, although the - # algorithm will be significantly slower than an optimized - # reservoir sampler - n = 5 * k - for i in range(0, n): - sk.update(i) - - # we should have k samples since they're equally weighted - self.assertAlmostEqual(k, sk.c, places=12) - - # we can also add a heavy item, using a negative value to - # be able to identify the item later. Keep in mind that - # "heavy" is a relative concept, so using a fixed - # multiple of n may not be considered a heavy item for - # larger values of n - sk.update(-1, 1000 * n) - self.assertEqual(k, sk.k) - self.assertLess(sk.c, k) - self.assertEqual(n + 1, sk.n) - self.assertFalse(sk.is_empty()) - - # we can easily get the list of items in the sample - items = list(sk) - self.assertLessEqual(len(items), k) - - count = 0 - for items in sk: - count = count + 1 - self.assertTrue(count == floor(sk.c) or count == ceil(sk.c)) - - # next we'll create a second, smaller sketch with - # only heavier items relative to the previous sketch - k2 = 5 - sk2 = ebpps_sketch(k2) - # for weight, use the sum of all items >=0 from before (n) - wt = n - for i in range(0, k2 + 1): - sk2.update((2 * n) + i, wt) - - # now merge the sketches, noting how the - # resulting k will be the smaller of the two. - input_sk_c = sk.c - sk.merge(sk2) - - self.assertEqual(n + k2 + 2, sk.n) - self.assertFalse(sk.is_empty()) - self.assertEqual(sk.k, k2) - self.assertLess(sk.k, k) - - # the expected number of samples post-merge may be larger than - # with the input sketch - self.assertGreater(sk.c, input_sk_c) - - # we can dump a sumamry of information in the sketch - print(sk) - - # if we want to print the list of items, there must be a - # __str__() method for each item (which need not be the same - # type; they're all generic python objects when used from - # python), otherwise you may trigger an exception. - # to_string() is provided as a convenience to avoid direct - # calls to __str__() with parameters. - print(sk.to_string(True)) - - # finally, we can serialize the sketch by providing an - # appropriate serde class. - expected_size = sk.get_serialized_size_bytes(PyIntsSerDe()) - b = sk.serialize(PyIntsSerDe()) - self.assertEqual(expected_size, len(b)) - - # if we try to deserialize with the wrong serde, things break - try: - ebpps_sketch.deserialize(b, PyStringsSerDe()) - self.fail() - except: - # expected; do nothing - self.assertTrue(True) - - # using the correct serde gives us back a copy of the original - rebuilt = ebpps_sketch.deserialize(b, PyIntsSerDe()) - self.assertEqual(sk.k, rebuilt.k) - self.assertEqual(sk.c, rebuilt.c) - self.assertEqual(sk.n, rebuilt.n) - - # check that printing works as expected - self.assertGreater(len(sk.to_string(True)), 0) - self.assertEqual(len(sk.__str__()), len(sk.to_string())) - -if __name__ == '__main__': - unittest.main() diff --git a/tests/fi_test.py b/tests/fi_test.py deleted file mode 100644 index 6d56aff6..00000000 --- a/tests/fi_test.py +++ /dev/null @@ -1,152 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -import unittest -from datasketches import frequent_strings_sketch, frequent_items_sketch -from datasketches import frequent_items_error_type, PyIntsSerDe - -class FiTest(unittest.TestCase): - def test_fi_strings_example(self): - k = 3 # a small value so we can easily fill the sketch - fi = frequent_strings_sketch(k) - - # we'll use a small number of distinct items so we - # can use exponentially increasing weights and have - # some frequent items, decreasing so we have some - # small items inserted after a purge - n = 8 - for i in range(0, n): - fi.update(str(i), 2 ** (n - i)) - - # there are two ways to extract items : - # * NO_FALSE_POSITIVES includes all items with a lower bound - # above the a posteriori error - # * NO_FALSE_NEGATIVES includes all items with an upper bound - # above the a posteriori error - # a more complete discussion may be found at - # https://datasketches.github.io/docs/Frequency/FrequentItemsOverview.html - items_no_fp = fi.get_frequent_items(frequent_items_error_type.NO_FALSE_POSITIVES) - items_no_fn = fi.get_frequent_items(frequent_items_error_type.NO_FALSE_NEGATIVES) - self.assertLessEqual(len(items_no_fp), len(items_no_fn)) - - # the items list returns a decreasing weight-sorted list, and - # for each item we have (item, estimate, lower_bound, upper_bound) - item = items_no_fp[1] - self.assertLessEqual(item[2], item[1]) # lower bound vs estimate - self.assertLessEqual(item[1], item[3]) # estimate vs upper bound - - # we can also query directly for a specific item - id = items_no_fn[0][0] - est = fi.get_estimate(id) - lb = fi.get_lower_bound(id) - ub = fi.get_upper_bound(id) - self.assertLessEqual(lb, est) - self.assertLessEqual(est, ub) - - # the values are zero if the item isn't in our list - self.assertEqual(fi.get_estimate("NaN"), 0) - - # now create a second sketch with a lot of unique - # values but all with equal weight (of 1) such that - # the total weight is much larger than the first sketch - fi2 = frequent_strings_sketch(k) - wt = fi.total_weight - for i in range(0, 4*wt): - fi2.update(str(i)) - - # merge the second sketch into the first - fi.merge(fi2) - - # we can see that the weight is much larger - self.assertEqual(5 * wt, fi.total_weight) - - # querying with NO_FALSE_POSITIVES means we don't find anything - # heavy enough to return - items_no_fp = fi.get_frequent_items(frequent_items_error_type.NO_FALSE_POSITIVES) - self.assertEqual(len(items_no_fp), 0) - - # we do, however, find a few potential heavy items - # if querying with NO_FALSE_NEGATIVES - items_no_fn = fi.get_frequent_items(frequent_items_error_type.NO_FALSE_NEGATIVES) - self.assertGreater(len(items_no_fn), 0) - - # finally, serialize and reconstruct - fi_bytes = fi.serialize() - self.assertEqual(len(fi_bytes), fi.get_serialized_size_bytes()) - new_fi = frequent_strings_sketch.deserialize(fi_bytes) - - # and now interrogate the sketch - self.assertFalse(new_fi.is_empty()) - self.assertGreater(new_fi.num_active_items, 0) - self.assertEqual(5 * wt, new_fi.total_weight) - - # This example uses generic objects but is otherwise identical - def test_fi_items_example(self): - k = 3 # a small value so we can easily fill the sketch - fi = frequent_items_sketch(k) - - # as above, but in this case inserting ints - n = 8 - for i in range(0, n): - fi.update(i, 2 ** (n - i)) - - # everything else works identically, so let's jump straight - # to merging and serialization - - # now create a second sketch with a lot of unique - # values but all with equal weight (of 1) such that - # the total weight is much larger than the first sketch - fi2 = frequent_items_sketch(k) - wt = fi.total_weight - for i in range(0, 4*wt): - fi2.update(i) - - # merge the second sketch into the first - fi.merge(fi2) - - # we can see that the weight is much larger - self.assertEqual(5 * wt, fi.total_weight) - - # finally, serialize and reconstruct -- now we need a serde to tell - # (de)serialization how to interpret the objects - fi_bytes = fi.serialize(PyIntsSerDe()) - self.assertEqual(len(fi_bytes), fi.get_serialized_size_bytes(PyIntsSerDe())) - new_fi = frequent_items_sketch.deserialize(fi_bytes, PyIntsSerDe()) - - # and again interrogate the sketch to check that it's what we serialized - self.assertFalse(new_fi.is_empty()) - self.assertGreater(new_fi.num_active_items, 0) - self.assertEqual(5 * wt, new_fi.total_weight) - - # check that printing works as expected - self.assertGreater(len(fi.to_string(True)), 0) - self.assertEqual(len(fi.__str__()), len(fi.to_string())) - - def test_fi_sketch(self): - # only testing a few things not used in the above example - k = 12 - wt = 10000 - fi = frequent_strings_sketch(k) - - self.assertAlmostEqual(fi.epsilon, 0.0008545, delta=1e-6) - - sk_apriori_error = fi.epsilon * wt - reference_apriori_error = frequent_strings_sketch.get_apriori_error(k, wt) - self.assertAlmostEqual(sk_apriori_error, reference_apriori_error, delta=1e-6) - -if __name__ == '__main__': - unittest.main() diff --git a/tests/hll_test.py b/tests/hll_test.py deleted file mode 100644 index fba7727b..00000000 --- a/tests/hll_test.py +++ /dev/null @@ -1,133 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -import unittest -from datasketches import hll_sketch, hll_union, tgt_hll_type - -class HllTest(unittest.TestCase): - def test_hll_example(self): - lgk = 12 # 2^k = 4096 rows in the table - n = 1 << 18 # ~256k unique values - - # create a couple sketches and inject some values - # we'll have 1/4 of the values overlap - hll = hll_sketch(lgk, tgt_hll_type.HLL_8) - hll2 = hll_sketch(lgk, tgt_hll_type.HLL_6) - offset = int(3 * n / 4) # it's a float w/o cast - # because we hash on the bits, not an abstract numeric value, - # hll.update(1) and hll.update(1.0) give different results. - for i in range(0, n): - hll.update(i) - hll2.update(i + offset) - - # we can check that the upper and lower bounds bracket the - # estimate, without needing to know the exact value. - self.assertLessEqual(hll.get_lower_bound(1), hll.get_estimate()) - self.assertGreaterEqual(hll.get_upper_bound(1), hll.get_estimate()) - - # union is a separate class, and we can either get a result - # sketch or query the union object directly - union = hll_union(lgk) - union.update(hll) - union.update(hll2) - result = union.get_result() - self.assertEqual(result.get_estimate(), union.get_estimate()) - - # since our process here (including post-union HLL) is - # deterministic, we have checked and know the exact - # answer is within one standard deviation of the estimate - self.assertLessEqual(union.get_lower_bound(1), 7 * n / 4) - self.assertGreaterEqual(union.get_upper_bound(1), 7 * n / 4) - - # serialize for storage and reconstruct - sk_bytes = result.serialize_compact() - self.assertEqual(len(sk_bytes), result.get_compact_serialization_bytes()) - new_hll = hll_sketch.deserialize(sk_bytes) - - # the sketch can self-report its configuration and status - self.assertEqual(new_hll.lg_config_k, lgk) - self.assertEqual(new_hll.tgt_type, tgt_hll_type.HLL_4) - self.assertFalse(new_hll.is_empty()) - - # if we want to reduce some object overhead, we can also reset - new_hll.reset() - self.assertTrue(new_hll.is_empty()) - - # check that printing works as expected - self.assertGreater(len(hll.to_string(True, True, True, True)), 0) - self.assertEqual(len(hll.__str__()), len(hll.to_string())) - - def test_hll_sketch(self): - lgk = 8 - n = 117 - hll = self.generate_sketch(n, lgk, tgt_hll_type.HLL_6) - hll.update('string data') - hll.update(3.14159) # double data - - self.assertLessEqual(hll.get_lower_bound(1), hll.get_estimate()) - self.assertGreaterEqual(hll.get_upper_bound(1), hll.get_estimate()) - - self.assertEqual(hll.lg_config_k, lgk) - self.assertEqual(hll.tgt_type, tgt_hll_type.HLL_6) - - bytes_compact = hll.serialize_compact() - bytes_update = hll.serialize_updatable() - self.assertEqual(len(bytes_compact), hll.get_compact_serialization_bytes()) - self.assertEqual(len(bytes_update), hll.get_updatable_serialization_bytes()) - - self.assertFalse(hll.is_compact()) - self.assertFalse(hll.is_empty()) - - self.assertTrue(isinstance(hll_sketch.deserialize(bytes_compact), hll_sketch)) - self.assertTrue(isinstance(hll_sketch.deserialize(bytes_update), hll_sketch)) - - self.assertIsNotNone(hll_sketch.get_rel_err(True, False, 12, 1)) - self.assertIsNotNone(hll_sketch.get_max_updatable_serialization_bytes(20, tgt_hll_type.HLL_6)) - - hll.reset() - self.assertTrue(hll.is_empty()) - - def test_hll_union(self): - lgk = 7 - n = 53 - union = hll_union(lgk) - - sk = self.generate_sketch(n, lgk, tgt_hll_type.HLL_4, 0) - union.update(sk) - sk = self.generate_sketch(3 * n, lgk, tgt_hll_type.HLL_4, n) - union.update(sk) - union.update('string data') - union.update(1.4142136) - - self.assertLessEqual(union.get_lower_bound(1), union.get_estimate()) - self.assertGreaterEqual(union.get_upper_bound(1), union.get_estimate()) - - self.assertEqual(union.lg_config_k, lgk) - self.assertFalse(union.is_empty()) - - sk = union.get_result() - self.assertTrue(isinstance(sk, hll_sketch)) - self.assertEqual(sk.tgt_type, tgt_hll_type.HLL_4) - - def generate_sketch(self, n, lgk, sk_type=tgt_hll_type.HLL_4, st_idx=0): - sk = hll_sketch(lgk, sk_type) - for i in range(st_idx, st_idx + n): - sk.update(i) - return sk - -if __name__ == '__main__': - unittest.main() diff --git a/tests/kll_test.py b/tests/kll_test.py deleted file mode 100644 index a03bb227..00000000 --- a/tests/kll_test.py +++ /dev/null @@ -1,175 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -import unittest -from datasketches import kll_ints_sketch, kll_floats_sketch, kll_doubles_sketch -from datasketches import kll_items_sketch, ks_test, PyStringsSerDe -import copy -import numpy as np - -class KllTest(unittest.TestCase): - def test_kll_floats_example(self): - k = 160 - n = 2 ** 20 - - # create a sketch and inject ~1 million N(0,1) points as an array and as a single item - kll = kll_floats_sketch(k) - kll.update(np.random.normal(size=n-1)) - kll.update(0.0) - - # 0 should be near the median - self.assertAlmostEqual(0.5, kll.get_rank(0.0), delta=0.035) - - # the median should be near 0 - self.assertAlmostEqual(0.0, kll.get_quantile(0.5), delta=0.035) - - # we also track the min/max independently from the rest of the data - # which lets us know the full observed data range - self.assertLessEqual(kll.get_min_value(), kll.get_quantile(0.01)) - self.assertLessEqual(0.0, kll.get_rank(kll.get_min_value())) - self.assertGreaterEqual(kll.get_max_value(), kll.get_quantile(0.99)) - self.assertGreaterEqual(1.0, kll.get_rank(kll.get_max_value())) - - # we can also extract a list of values at a time, - # here the values should give us something close to [-2, -1, 0, 1, 2]. - # then get the CDF, which will return something close to - # the original values used in get_quantiles() - # finally, can check the normalized rank error bound - pts = kll.get_quantiles([0.0228, 0.1587, 0.5, 0.8413, 0.9772]) - cdf = kll.get_cdf(pts) # include 1.0 at end to account for all probability mass - self.assertEqual(len(cdf), len(pts)+1) - err = kll.normalized_rank_error(False) - self.assertEqual(err, kll_floats_sketch.get_normalized_rank_error(k, False)) - - # and a few basic queries about the sketch - self.assertFalse(kll.is_empty()) - self.assertTrue(kll.is_estimation_mode()) - self.assertEqual(kll.n, n) - self.assertEqual(kll.k, k) - self.assertLess(kll.num_retained, n) - - # merging itself will double the number of items the sketch has seen - # but need to do that with a copy - kll_copy = copy.copy(kll) - kll.merge(kll_copy) - self.assertEqual(kll.n, 2*n) - - # we can then serialize and reconstruct the sketch - kll_bytes = kll.serialize() - new_kll = kll_floats_sketch.deserialize(kll_bytes) - self.assertEqual(kll.num_retained, new_kll.num_retained) - self.assertEqual(kll.get_min_value(), new_kll.get_min_value()) - self.assertEqual(kll.get_max_value(), new_kll.get_max_value()) - self.assertEqual(kll.get_quantile(0.7), new_kll.get_quantile(0.7)) - self.assertEqual(kll.get_rank(0.0), new_kll.get_rank(0.0)) - - # A Kolmogorov-Smirnov Test of kll and new_kll should match, even for - # a fairly small p-value -- cannot reject the null hypothesis that - # they come from the same distribution (since they do) - self.assertFalse(ks_test(kll, new_kll, 0.001)) - - total_weight = 0 - for tuple in kll: - item = tuple[0] - weight = tuple[1] - total_weight = total_weight + weight - self.assertEqual(total_weight, kll.n) - - def test_kll_ints_sketch(self): - k = 100 - n = 10 - kll = kll_ints_sketch(k) - for i in range(0, n): - kll.update(i) - - self.assertEqual(kll.get_min_value(), 0) - self.assertEqual(kll.get_max_value(), n-1) - self.assertEqual(kll.n, n) - self.assertFalse(kll.is_empty()) - self.assertFalse(kll.is_estimation_mode()) # n < k - self.assertEqual(kll.k, k) - - pmf = kll.get_pmf([round(n/2)]) - self.assertIsNotNone(pmf) - self.assertEqual(len(pmf), 2) - - cdf = kll.get_cdf([round(n/2)]) - self.assertIsNotNone(cdf) - self.assertEqual(len(cdf), 2) - - self.assertEqual(kll.get_quantile(0.5), round(n/2)) - quants = kll.get_quantiles([0.25, 0.5, 0.75]) - self.assertIsNotNone(quants) - self.assertEqual(len(quants), 3) - - self.assertEqual(kll.get_rank(round(n/2)), 0.5) - - # merge copy of self - kll_copy = copy.copy(kll) - kll.merge(kll_copy) - self.assertEqual(kll.n, 2 * n) - - sk_bytes = kll.serialize() - self.assertTrue(isinstance(kll_ints_sketch.deserialize(sk_bytes), kll_ints_sketch)) - - def test_kll_doubles_sketch(self): - # already tested float and ints and it's templatized, so just make sure it instantiates properly - k = 75 - kll = kll_doubles_sketch(k) - self.assertTrue(kll.is_empty()) - - def test_kll_items_sketch(self): - # most functionality has been tested, but we need to ensure objects and sorting work - # as well as serialization - k = 100 - n = 2 ** 16 - - # create a sketch and inject enough points to force compaction - kll = kll_items_sketch(k) - for i in range(0, n): - kll.update(str(i)) - - # check iterator for items - total_weight = 0 - for tuple in kll: - item = tuple[0] - weight = tuple[1] - total_weight = total_weight + weight - self.assertEqual(total_weight, kll.n) - - kll_copy = copy.copy(kll) - kll.merge(kll_copy) - self.assertEqual(kll.n, 2 * n) - - kll_bytes = kll.serialize(PyStringsSerDe()) - new_kll = kll_items_sketch.deserialize(kll_bytes, PyStringsSerDe()) - self.assertEqual(kll.num_retained, new_kll.num_retained) - self.assertEqual(kll.get_min_value(), new_kll.get_min_value()) - self.assertEqual(kll.get_max_value(), new_kll.get_max_value()) - self.assertEqual(kll.get_quantile(0.7), new_kll.get_quantile(0.7)) - self.assertEqual(kll.get_rank(str(n/4)), new_kll.get_rank(str(n/4))) - - # The sketches are identical so we cannot reject the null hypothesis that they - # reflect the same underlying distribtion - self.assertFalse(ks_test(kll, new_kll, 0.001)) - - # check that printing works as expected - self.assertGreater(len(kll.to_string(True, True)), 0) - self.assertEqual(len(kll.__str__()), len(kll.to_string())) - -if __name__ == '__main__': - unittest.main() diff --git a/tests/quantiles_test.py b/tests/quantiles_test.py deleted file mode 100644 index 988db2f9..00000000 --- a/tests/quantiles_test.py +++ /dev/null @@ -1,175 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -import copy -import unittest -from datasketches import quantiles_ints_sketch, quantiles_floats_sketch, quantiles_doubles_sketch -from datasketches import quantiles_items_sketch, ks_test, PyStringsSerDe -import numpy as np - -class QuantilesTest(unittest.TestCase): - def test_quantiles_floats_example(self): - k = 128 - n = 2 ** 20 - - # create a sketch and inject ~1 million N(0,1) points as an array and as a single item - quantiles = quantiles_floats_sketch(k) - quantiles.update(np.random.normal(size=n-1)) - quantiles.update(0.0) - - # 0 should be near the median - self.assertAlmostEqual(0.5, quantiles.get_rank(0.0), delta=0.035) - - # the median should be near 0 - self.assertAlmostEqual(0.0, quantiles.get_quantile(0.5), delta=0.035) - - # we also track the min/max independently from the rest of the data - # which lets us know the full observed data range - self.assertLessEqual(quantiles.get_min_value(), quantiles.get_quantile(0.01)) - self.assertLessEqual(0.0, quantiles.get_rank(quantiles.get_min_value())) - self.assertGreaterEqual(quantiles.get_max_value(), quantiles.get_quantile(0.99)) - self.assertGreaterEqual(1.0, quantiles.get_rank(quantiles.get_max_value())) - - # we can also extract a list of values at a time, - # here the values should give us something close to [-2, -1, 0, 1, 2]. - # then get the CDF, which will return something close to - # the original values used in get_quantiles() - # finally, can check the normalized rank error bound - pts = quantiles.get_quantiles([0.0228, 0.1587, 0.5, 0.8413, 0.9772]) - cdf = quantiles.get_cdf(pts) # include 1.0 at end to account for all probability mass - self.assertEqual(len(cdf), len(pts)+1) - err = quantiles.normalized_rank_error(False) - self.assertEqual(err, quantiles_floats_sketch.get_normalized_rank_error(k, False)) - - # and a few basic queries about the sketch - self.assertFalse(quantiles.is_empty()) - self.assertTrue(quantiles.is_estimation_mode()) - self.assertEqual(quantiles.n, n) - self.assertEqual(quantiles.k, k) - self.assertLess(quantiles.num_retained, n) - - # merging itself will double the number of items the sketch has seen - quantiles_copy = copy.copy(quantiles) - quantiles.merge(quantiles_copy) - self.assertEqual(quantiles.n, 2*n) - - # we can then serialize and reconstruct the sketch - quantiles_bytes = quantiles.serialize() - new_quantiles = quantiles_floats_sketch.deserialize(quantiles_bytes) - self.assertEqual(quantiles.num_retained, new_quantiles.num_retained) - self.assertEqual(quantiles.get_min_value(), new_quantiles.get_min_value()) - self.assertEqual(quantiles.get_max_value(), new_quantiles.get_max_value()) - self.assertEqual(quantiles.get_quantile(0.7), new_quantiles.get_quantile(0.7)) - self.assertEqual(quantiles.get_rank(0.0), new_quantiles.get_rank(0.0)) - - # If we create a new sketch with a very different distribution, a Kolmogorov-Smirnov Test - # of the two should return True: we can reject the null hypothesis that the sketches - # come from the same distributions. - unif_quantiles = quantiles_floats_sketch(k) - unif_quantiles.update(np.random.uniform(10, 20, size=n-1)) - self.assertTrue(ks_test(quantiles, unif_quantiles, 0.001)) - - total_weight = 0 - for tuple in quantiles: - item = tuple[0] - weight = tuple[1] - total_weight = total_weight + weight - self.assertEqual(total_weight, quantiles.n) - - def test_quantiles_ints_sketch(self): - k = 128 - n = 10 - quantiles = quantiles_ints_sketch(k) - for i in range(0, n): - quantiles.update(i) - - self.assertEqual(quantiles.get_min_value(), 0) - self.assertEqual(quantiles.get_max_value(), n-1) - self.assertEqual(quantiles.n, n) - self.assertFalse(quantiles.is_empty()) - self.assertFalse(quantiles.is_estimation_mode()) # n < k - self.assertEqual(quantiles.k, k) - - pmf = quantiles.get_pmf([round(n/2)]) - self.assertIsNotNone(pmf) - self.assertEqual(len(pmf), 2) - - cdf = quantiles.get_cdf([round(n/2)]) - self.assertIsNotNone(cdf) - self.assertEqual(len(cdf), 2) - - self.assertEqual(quantiles.get_quantile(0.5), round(n/2)) - quants = quantiles.get_quantiles([0.25, 0.5, 0.75]) - self.assertIsNotNone(quants) - self.assertEqual(len(quants), 3) - - self.assertEqual(quantiles.get_rank(round(n/2)), 0.5) - - # merge self - quantiles_copy = copy.copy(quantiles) - quantiles.merge(quantiles_copy) - self.assertEqual(quantiles.n, 2 * n) - - sk_bytes = quantiles.serialize() - self.assertTrue(isinstance(quantiles_ints_sketch.deserialize(sk_bytes), quantiles_ints_sketch)) - - def test_quantiles_doubles_sketch(self): - # already tested floats and ints and it's templatized, so just make sure it instantiates properly - k = 128 - quantiles = quantiles_doubles_sketch(k) - self.assertTrue(quantiles.is_empty()) - - def test_quantiles_items_sketch(self): - # most functionality has been tested, but we need to ensure objects and sorting work - # as well as serialization - k = 128 - n = 2 ** 16 - - # create a sketch and inject enough points to force compaction - quantiles = quantiles_items_sketch(k) - for i in range(0, n): - quantiles.update(str(i)) - - quantiles_copy = copy.copy(quantiles) - quantiles.merge(quantiles_copy) - self.assertEqual(quantiles.n, 2 * n) - - total_weight = 0 - for tuple in quantiles: - item = tuple[0] - weight = tuple[1] - total_weight = total_weight + weight - self.assertEqual(total_weight, quantiles.n) - - quantiles_bytes = quantiles.serialize(PyStringsSerDe()) - new_quantiles = quantiles_items_sketch.deserialize(quantiles_bytes, PyStringsSerDe()) - self.assertEqual(quantiles.num_retained, new_quantiles.num_retained) - self.assertEqual(quantiles.get_min_value(), new_quantiles.get_min_value()) - self.assertEqual(quantiles.get_max_value(), new_quantiles.get_max_value()) - self.assertEqual(quantiles.get_quantile(0.7), new_quantiles.get_quantile(0.7)) - self.assertEqual(quantiles.get_rank(str(n/4)), new_quantiles.get_rank(str(n/4))) - - # The sketches are identical so we cannot reject the null hypothesis that they - # reflect the same underlying distribtion - self.assertFalse(ks_test(quantiles, new_quantiles, 0.001)) - - # check that printing works as expected - self.assertGreater(len(quantiles.to_string(True, True)), 0) - self.assertEqual(len(quantiles.__str__()), len(quantiles.to_string())) - -if __name__ == '__main__': - unittest.main() diff --git a/tests/req_test.py b/tests/req_test.py deleted file mode 100644 index 775dfd44..00000000 --- a/tests/req_test.py +++ /dev/null @@ -1,170 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -import unittest -from datasketches import req_ints_sketch, req_floats_sketch, req_items_sketch, PyStringsSerDe -import copy -import numpy as np - -class reqTest(unittest.TestCase): - def test_req_example(self): - k = 12 - n = 2 ** 20 - - # create a sketch and inject ~1 million N(0,1) points as an array and as a single item - req = req_floats_sketch(k, True) # high rank accuracy - req.update(np.random.normal(size=n-1)) - req.update(0.0) - - # 0 should be near the median - self.assertAlmostEqual(0.5, req.get_rank(0.0), delta=0.045) - - # the median should be near 0 - self.assertAlmostEqual(0.0, req.get_quantile(0.5), delta=0.045) - - # we also track the min/max independently from the rest of the data - # which lets us know the full observed data range - self.assertLessEqual(req.get_min_value(), req.get_quantile(0.01)) - self.assertLessEqual(0.0, req.get_rank(req.get_min_value())) - self.assertGreaterEqual(req.get_max_value(), req.get_quantile(0.99)) - self.assertGreaterEqual(1.0, req.get_rank(req.get_max_value())) - - # we can also extract a list of values at a time, - # here the values should give us something close to [-2, -1, 0, 1, 2]. - # then get the CDF, which will return something close to - # the original values used in get_quantiles() - # finally, can check the normalized rank error bound - pts = req.get_quantiles([0.0228, 0.1587, 0.5, 0.8413, 0.9772]) - cdf = req.get_cdf(pts) # include 1.0 at end to account for all probability mass - self.assertEqual(len(cdf), len(pts)+1) - - # For relative error quantiles, the error depends on the actual rank - # so we need to use that to detemrine the bounds - est = req.get_rank(0.999, True) - lb = req.get_rank_lower_bound(est, 1) - ub = req.get_rank_upper_bound(est, 1) - self.assertLessEqual(lb, est) - self.assertLessEqual(est, ub) - - # and a few basic queries about the sketch - self.assertFalse(req.is_empty()) - self.assertTrue(req.is_estimation_mode()) - self.assertEqual(req.n, n) - self.assertLess(req.num_retained, n) - self.assertEqual(req.k, k) - - # merging itself will double the number of items the sketch has seen - req_copy = copy.copy(req) - req.merge(req_copy) - self.assertEqual(req.n, 2*n) - - # we can then serialize and reconstruct the sketch - req_bytes = req.serialize() - new_req = req_floats_sketch.deserialize(req_bytes) - self.assertEqual(req.num_retained, new_req.num_retained) - self.assertEqual(req.get_min_value(), new_req.get_min_value()) - self.assertEqual(req.get_max_value(), new_req.get_max_value()) - self.assertEqual(req.get_quantile(0.7), new_req.get_quantile(0.7)) - self.assertEqual(req.get_rank(0.0), new_req.get_rank(0.0)) - - total_weight = 0 - for tuple in req: - item = tuple[0] - weight = tuple[1] - total_weight = total_weight + weight - self.assertEqual(total_weight, req.n) - - def test_req_ints_sketch(self): - k = 100 - n = 10 - req = req_ints_sketch(k) - for i in range(0, n): - req.update(i) - - self.assertEqual(req.get_min_value(), 0) - self.assertEqual(req.get_max_value(), n-1) - self.assertEqual(req.n, n) - self.assertFalse(req.is_empty()) - self.assertFalse(req.is_estimation_mode()) # n < k - self.assertEqual(req.k, k) - - pmf = req.get_pmf([round(n/2)]) - self.assertIsNotNone(pmf) - self.assertEqual(len(pmf), 2) - - cdf = req.get_cdf([round(n/2)]) - self.assertIsNotNone(cdf) - self.assertEqual(len(cdf), 2) - - self.assertEqual(req.get_quantile(0.5), round(n/2)) - quants = req.get_quantiles([0.25, 0.5, 0.75]) - self.assertIsNotNone(quants) - self.assertEqual(len(quants), 3) - - self.assertEqual(req.get_rank(round(n/2)), 0.5) - - # merge self - req_copy = copy.copy(req) - req.merge(req_copy) - self.assertEqual(req.n, 2 * n) - - sk_bytes = req.serialize() - self.assertTrue(isinstance(req_ints_sketch.deserialize(sk_bytes), req_ints_sketch)) - - def test_req_floats_sketch(self): - # already tested floats with LRA so just check that HRA works - k = 75 - req = req_floats_sketch(k, False) # low rank accuracy - self.assertTrue(req.is_empty()) - self.assertFalse(req.is_hra()) - - def test_req_items_sketch(self): - # most functionality has been tested, but we need to ensure objects and sorting work - # as well as serialization - k = 100 - n = 2 ** 16 - - # create a sketch and inject enough points to force compaction - req = req_items_sketch(k) - for i in range(0, n): - req.update(str(i)) - - req_copy = copy.copy(req) - req.merge(req_copy) - self.assertEqual(req.n, 2 * n) - - total_weight = 0 - for tuple in req: - item = tuple[0] - weight = tuple[1] - total_weight = total_weight + weight - self.assertEqual(total_weight, req.n) - - req_bytes = req.serialize(PyStringsSerDe()) - new_req = req_items_sketch.deserialize(req_bytes, PyStringsSerDe()) - self.assertEqual(req.num_retained, new_req.num_retained) - self.assertEqual(req.get_min_value(), new_req.get_min_value()) - self.assertEqual(req.get_max_value(), new_req.get_max_value()) - self.assertEqual(req.get_quantile(0.7), new_req.get_quantile(0.7)) - self.assertEqual(req.get_rank(str(n/4)), new_req.get_rank(str(n/4))) - - # check that printing works as expected - self.assertGreater(len(req.to_string(True, True)), 0) - self.assertEqual(len(req.__str__()), len(req.to_string())) - -if __name__ == '__main__': - unittest.main() diff --git a/tests/tdigest_test.py b/tests/tdigest_test.py deleted file mode 100644 index b0c5550e..00000000 --- a/tests/tdigest_test.py +++ /dev/null @@ -1,123 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -import unittest -from datasketches import tdigest_float, tdigest_double -import numpy as np - -class TdigestTest(unittest.TestCase): - def test_tdigest_double_example(self): - n = 2 ** 20 - - # create a tdigest and inject ~1 million N(0,1) points, both using a vector - # update as well as a single value - td = tdigest_double() - td.update(np.random.normal(size=n-1)) - td.update(0.0) - - # 0 should be near the median - self.assertAlmostEqual(0.5, td.get_rank(0.0), delta=0.1) - - # the median should be near 0 - self.assertAlmostEqual(0.0, td.get_quantile(0.5), delta=0.1) - - # note that with t-digest, while it typically performs quite well in practice, - # we do not have any sort of theoretical guarantees on the error bounds - # or even an estimate of what bounds we may expect. - - # we also track the min/max independently from the rest of the data - # which lets us know the full observed data range - self.assertLessEqual(td.get_min_value(), td.get_quantile(0.01)) - self.assertLessEqual(0.0, td.get_rank(td.get_min_value())) - self.assertGreaterEqual(td.get_max_value(), td.get_quantile(0.99)) - self.assertGreaterEqual(1.0, td.get_rank(td.get_max_value())) - - # and a few basic queries about the sketch - self.assertFalse(td.is_empty()) - self.assertEqual(td.get_total_weight(), n) - - # we can get the PMF and CDF - pmf = td.get_pmf([-0.5, 0.0, 0.5]) - self.assertEqual(len(pmf), 4) - self.assertAlmostEqual(sum(pmf), 1.0) - - cdf = td.get_cdf([0.0]) - self.assertEqual(len(cdf), 2) - self.assertAlmostEqual(cdf[0], 0.5, delta = 0.05) - - # we can define a new tdigest with a different distribution, then merge them - td2 = tdigest_double() - td2.update(np.random.normal(loc=2.0, size=n)) - td.merge(td2) - - # the new median should be near 1.0, and 1.0 should be near the median although - # the error distribution is not well-characterized so we allow generous margins - self.assertAlmostEqual(0.5, td.get_rank(1.0), delta=0.2) - self.assertAlmostEqual(1.0, td.get_quantile(0.5), delta=0.2) - self.assertEqual(td.get_total_weight(), 2 * n) - - # finally, can serialize and deserialize the sketch - td_bytes = td.serialize() - new_td = tdigest_double.deserialize(td_bytes) - self.assertEqual(td.get_total_weight(), new_td.get_total_weight()) - self.assertEqual(td.get_min_value(), new_td.get_min_value()) - self.assertEqual(td.get_max_value(), new_td.get_max_value()) - self.assertEqual(td.get_quantile(0.7), new_td.get_quantile(0.7)) - self.assertEqual(td.get_rank(0.0), new_td.get_rank(0.0)) - - - # the same tests as above, but with tdigest_float - def test_tdigest_float_example(self): - n = 2 ** 20 - td = tdigest_float() - td.update(np.random.normal(size=n-1)) - td.update(0.0) - - self.assertAlmostEqual(0.5, td.get_rank(0.0), delta=0.1) - self.assertAlmostEqual(0.0, td.get_quantile(0.5), delta=0.1) - - self.assertLessEqual(td.get_min_value(), td.get_quantile(0.01)) - self.assertLessEqual(0.0, td.get_rank(td.get_min_value())) - self.assertGreaterEqual(td.get_max_value(), td.get_quantile(0.99)) - self.assertGreaterEqual(1.0, td.get_rank(td.get_max_value())) - - self.assertFalse(td.is_empty()) - self.assertEqual(td.get_total_weight(), n) - - pmf = td.get_pmf([-0.5, 0.0, 0.5]) - self.assertEqual(len(pmf), 4) - self.assertAlmostEqual(sum(pmf), 1.0) - - cdf = td.get_cdf([0.0]) - self.assertEqual(len(cdf), 2) - self.assertAlmostEqual(cdf[0], 0.5, delta = 0.05) - - td2 = tdigest_float() - td2.update(np.random.normal(loc=2.0, size=n)) - td.merge(td2) - - self.assertAlmostEqual(0.5, td.get_rank(1.0), delta=0.2) - self.assertAlmostEqual(1.0, td.get_quantile(0.5), delta=0.2) - self.assertEqual(td.get_total_weight(), 2 * n) - - td_bytes = td.serialize() - new_td = tdigest_float.deserialize(td_bytes) - self.assertEqual(td.get_total_weight(), new_td.get_total_weight()) - self.assertEqual(td.get_min_value(), new_td.get_min_value()) - self.assertEqual(td.get_max_value(), new_td.get_max_value()) - self.assertEqual(td.get_quantile(0.7), new_td.get_quantile(0.7)) - self.assertEqual(td.get_rank(0.0), new_td.get_rank(0.0)) diff --git a/tests/theta_test.py b/tests/theta_test.py deleted file mode 100644 index 1d2da0f7..00000000 --- a/tests/theta_test.py +++ /dev/null @@ -1,170 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -import unittest - -from datasketches import update_theta_sketch -from datasketches import compact_theta_sketch, theta_union -from datasketches import theta_intersection, theta_a_not_b -from datasketches import theta_jaccard_similarity - -class ThetaTest(unittest.TestCase): - def test_theta_basic_example(self): - lgk = 12 # 2^k = 4096 rows in the table - n = 1 << 18 # ~256k unique values - - # create a sketch and inject some values - sk = self.generate_theta_sketch(n, lgk) - - # we can check that the upper and lower bounds bracket the - # estimate, without needing to know the exact value. - self.assertLessEqual(sk.get_lower_bound(1), sk.get_estimate()) - self.assertGreaterEqual(sk.get_upper_bound(1), sk.get_estimate()) - - # because this sketch is deterministically generated, we can - # also compare against the exact value - self.assertLessEqual(sk.get_lower_bound(1), n) - self.assertGreaterEqual(sk.get_upper_bound(1), n) - - # compact and serialize for storage, then reconstruct - sk_bytes = sk.compact().serialize() - new_sk = compact_theta_sketch.deserialize(sk_bytes) - - # estimate remains unchanged - self.assertFalse(sk.is_empty()) - self.assertEqual(sk.get_estimate(), new_sk.get_estimate()) - - # can also serialze in a compressed format - sk_compresed_bytes = sk.compact().serialize(compress=True) - self.assertLess(len(sk_compresed_bytes), len(sk_bytes)) - sk_from_compressed = compact_theta_sketch.deserialize(sk_compresed_bytes) - - # compressed and non-compressed sketches should match - self.assertEqual(sk_from_compressed.get_estimate(), new_sk.get_estimate()) - self.assertEqual(sk_from_compressed.get_upper_bound(1), new_sk.get_upper_bound(1)) - self.assertEqual(sk_from_compressed.get_lower_bound(1), new_sk.get_lower_bound(1)) - - # check that printing works as expected - self.assertGreater(len(sk.to_string(True)), 0) - self.assertEqual(len(sk.__str__()), len(sk.to_string())) - - count = 0 - for hash in new_sk: - self.assertLess(hash, new_sk.theta64) - count = count + 1 - self.assertEqual(count, new_sk.num_retained) - - num = sk.num_retained - sk.trim() - self.assertLessEqual(sk.num_retained, num) - - sk.reset() - self.assertTrue(sk.is_empty()) - self.assertEqual(sk.num_retained, 0) - - def test_theta_set_operations(self): - lgk = 12 # 2^k = 4096 rows in the table - n = 1 << 18 # ~256k unique values - - # we'll have 1/4 of the values overlap - offset = int(3 * n / 4) # it's a float w/o cast - - # create a couple sketches and inject some values - sk1 = self.generate_theta_sketch(n, lgk) - sk2 = self.generate_theta_sketch(n, lgk, offset) - - # UNIONS - # create a union object - union = theta_union(lgk) - union.update(sk1) - union.update(sk2) - - # getting result from union returns a compact_theta_sketch - # compact theta sketches can be used in additional unions - # or set operations but cannot accept further item updates - result = union.get_result() - self.assertTrue(isinstance(result, compact_theta_sketch)) - - # since our process here is deterministic, we have - # checked and know the exact answer is within one - # standard deviation of the estimate - self.assertLessEqual(result.get_lower_bound(1), 7 * n / 4) - self.assertGreaterEqual(result.get_upper_bound(1), 7 * n / 4) - - # INTERSECTIONS - # create an intersection object - intersect = theta_intersection() # no lg_k - intersect.update(sk1) - intersect.update(sk2) - - # has_result() indicates the intersection has been used, - # although the result may be the empty set - self.assertTrue(intersect.has_result()) - - # as with unions, the result is a compact sketch - result = intersect.get_result() - self.assertTrue(isinstance(result, compact_theta_sketch)) - - # we know the sets overlap by 1/4 - self.assertLessEqual(result.get_lower_bound(1), n / 4) - self.assertGreaterEqual(result.get_upper_bound(1), n / 4) - - # A NOT B - # create an a_not_b object - anb = theta_a_not_b() # no lg_k - result = anb.compute(sk1, sk2) - - # as with unions, the result is a compact sketch - self.assertTrue(isinstance(result, compact_theta_sketch)) - - # we know the sets overlap by 1/4, so the remainder is 3/4 - self.assertLessEqual(result.get_lower_bound(1), 3 * n / 4) - self.assertGreaterEqual(result.get_upper_bound(1), 3 * n / 4) - - - # JACCARD SIMILARITY - # Jaccard Similarity measure returns (lower_bound, estimate, upper_bound) - jac = theta_jaccard_similarity.jaccard(sk1, sk2) - - # we can check that results are in the expected order - self.assertLess(jac[0], jac[1]) - self.assertLess(jac[1], jac[2]) - - # checks for sketch equivalency - self.assertTrue(theta_jaccard_similarity.exactly_equal(sk1, sk1)) - self.assertFalse(theta_jaccard_similarity.exactly_equal(sk1, sk2)) - - # we can apply a check for similarity or dissimilarity at a - # given threshold, at 97.7% confidence. - - # check that the Jaccard Index is at most (upper bound) 0.2. - # exact result would be 1/7 - self.assertTrue(theta_jaccard_similarity.dissimilarity_test(sk1, sk2, 0.2)) - - # check that the Jaccard Index is at least (lower bound) 0.7 - # exact result would be 3/4, using result from A NOT B test - self.assertTrue(theta_jaccard_similarity.similarity_test(sk1, result, 0.7)) - - - def generate_theta_sketch(self, n, lgk, offset=0): - sk = update_theta_sketch(lgk) - for i in range(0, n): - sk.update(i + offset) - return sk - -if __name__ == '__main__': - unittest.main() diff --git a/tests/tuple_test.py b/tests/tuple_test.py deleted file mode 100644 index cf505fb1..00000000 --- a/tests/tuple_test.py +++ /dev/null @@ -1,235 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -import unittest - -from datasketches import update_tuple_sketch -from datasketches import compact_tuple_sketch, tuple_union -from datasketches import tuple_intersection, tuple_a_not_b -from datasketches import tuple_jaccard_similarity -from datasketches import tuple_jaccard_similarity, PyIntsSerDe -from datasketches import AccumulatorPolicy, MaxIntPolicy, MinIntPolicy -from datasketches import update_theta_sketch - -class TupleTest(unittest.TestCase): - def test_tuple_basic_example(self): - lgk = 12 # 2^k = 4096 rows in the table - n = 1 << 18 # ~256k unique values - - # create a sketch and inject some values -- summary is 2 so we can sum them - # and know the result - sk = self.generate_tuple_sketch(AccumulatorPolicy(), n, lgk, value=2) - - # we can check that the upper and lower bounds bracket the - # estimate, without needing to know the exact value. - self.assertLessEqual(sk.get_lower_bound(1), sk.get_estimate()) - self.assertGreaterEqual(sk.get_upper_bound(1), sk.get_estimate()) - - # because this sketch is deterministically generated, we can - # also compare against the exact value - self.assertLessEqual(sk.get_lower_bound(1), n) - self.assertGreaterEqual(sk.get_upper_bound(1), n) - - # compact and serialize for storage, then reconstruct - sk_bytes = sk.compact().serialize(PyIntsSerDe()) - new_sk = compact_tuple_sketch.deserialize(sk_bytes, serde=PyIntsSerDe()) - - # estimate remains unchanged - self.assertFalse(sk.is_empty()) - self.assertEqual(sk.get_estimate(), new_sk.get_estimate()) - - # we can also iterate over the sketch entries - # the iterator provides a (hashkey, summary) pair where the - # first value is the raw hash value and the second the summary - count = 0 - cumSum = 0 - for pair in new_sk: - self.assertLess(pair[0], new_sk.theta64) - count += 1 - cumSum += pair[1] - self.assertEqual(count, new_sk.num_retained) - self.assertEqual(cumSum, 2 * new_sk.num_retained) - - # we can even create a tuple sketch from an existing theta sketch - # as long as we provide a summary to use - theta_sk = update_theta_sketch(lgk) - for i in range(n, 2*n): - theta_sk.update(i) - cts = compact_tuple_sketch(theta_sk, 5) - cumSum = 0 - for pair in cts: - cumSum += pair[1] - self.assertEqual(cumSum, 5 * cts.num_retained) - - # check that printing works as expected - self.assertGreater(len(sk.to_string(True)), 0) - self.assertEqual(len(sk.__str__()), len(sk.to_string())) - - num = sk.num_retained - sk.trim() - self.assertLessEqual(sk.num_retained, num) - - sk.reset() - self.assertTrue(sk.is_empty()) - self.assertEqual(sk.num_retained, 0) - - def test_tuple_filter(self): - lgk = 12 # 2^k = 4096 rows in the table - n = 1 << 18 # ~256k unique values - - # filtering lets us apply a predicate to the sketch, producing a new - # compact sketch using the entries matching the predicate. - sk = update_tuple_sketch(AccumulatorPolicy(), lgk) - for ii in range(0, n): - sk.update(ii, ii) - - # we can filter by a predicate, whether a lambda or a defined function - # for instance, using 0.5*n will return a compact_tuple_sketch with - # approximately half the entries. - result = sk.filter(lambda x: x < (0.5 * n)) - self.assertAlmostEqual(result.get_estimate(), 0.5 * n, delta=0.01 * n) - self.assertLess(result.get_lower_bound(1), 0.5 * n) - self.assertGreater(result.get_upper_bound(1), 0.5 * n) - - def test_tuple_set_operations(self): - lgk = 12 # 2^k = 4096 rows in the table - n = 1 << 18 # ~256k unique values - - # we'll have 1/4 of the values overlap - offset = int(3 * n / 4) # it's a float w/o cast - - # create a couple sketches and inject some values, with different summaries - sk1 = self.generate_tuple_sketch(AccumulatorPolicy(), n, lgk, value=5) - sk2 = self.generate_tuple_sketch(AccumulatorPolicy(), n, lgk, value=7, offset=offset) - - # UNIONS - # create a union object - union = tuple_union(MaxIntPolicy(), lgk) - union.update(sk1) - union.update(sk2) - - # getting result from union returns a compact_theta_sketch - # compact theta sketches can be used in additional unions - # or set operations but cannot accept further item updates - result = union.get_result() - self.assertTrue(isinstance(result, compact_tuple_sketch)) - - # since our process here is deterministic, we have - # checked and know the exact answer is within one - # standard deviation of the estimate - self.assertLessEqual(result.get_lower_bound(1), 7 * n / 4) - self.assertGreaterEqual(result.get_upper_bound(1), 7 * n / 4) - - # we unioned two equal-sized sketches with overlap and used - # the max value as the resulting summary, meaning we should - # have more summaries with value 7 than value 5 in the result - count5 = 0 - count7 = 0 - for pair in result: - if pair[1] == 5: - count5 += 1 - elif pair[1] == 7: - count7 += 1 - else: - self.fail() - self.assertLess(count5, count7) - - # INTERSECTIONS - # create an intersection object - intersect = tuple_intersection(MinIntPolicy()) # no lg_k - intersect.update(sk1) - intersect.update(sk2) - - # has_result() indicates the intersection has been used, - # although the result may be the empty set - self.assertTrue(intersect.has_result()) - - # as with unions, the result is a compact sketch - result = intersect.get_result() - self.assertTrue(isinstance(result, compact_tuple_sketch)) - - # we know the sets overlap by 1/4 - self.assertLessEqual(result.get_lower_bound(1), n / 4) - self.assertGreaterEqual(result.get_upper_bound(1), n / 4) - - # in this example, we intersected the sketches and took the - # min value as the resulting summary, so all summaries - # must be exactly equal to that value - count5 = 0 - for pair in result: - if pair[1] == 5: - count5 += 1 - else: - self.fail() - self.assertEqual(count5, result.num_retained) - - # A NOT B - # create an a_not_b object - anb = tuple_a_not_b() # no lg_k or policy - result = anb.compute(sk1, sk2) - - # as with unions, the result is a compact sketch - self.assertTrue(isinstance(result, compact_tuple_sketch)) - - # we know the sets overlap by 1/4, so the remainder is 3/4 - self.assertLessEqual(result.get_lower_bound(1), 3 * n / 4) - self.assertGreaterEqual(result.get_upper_bound(1), 3 * n / 4) - - # here, we have only values with a summary of 5 as any keys that - # existed in both sketches were removed - count5 = 0 - for pair in result: - if pair[1] == 5: - count5 += 1 - else: - self.fail() - self.assertEqual(count5, result.num_retained) - - # JACCARD SIMILARITY - # Jaccard Similarity measure returns (lower_bound, estimate, upper_bound) - # and does not examine summaries, even for (dis)similarity tests. - jac = tuple_jaccard_similarity.jaccard(sk1, sk2) - - # we can check that results are in the expected order - self.assertLess(jac[0], jac[1]) - self.assertLess(jac[1], jac[2]) - - # checks for sketch equivalence - self.assertTrue(tuple_jaccard_similarity.exactly_equal(sk1, sk1)) - self.assertFalse(tuple_jaccard_similarity.exactly_equal(sk1, sk2)) - - # we can apply a check for similarity or dissimilarity at a - # given threshold, at 97.7% confidence. - - # check that the Jaccard Index is at most (upper bound) 0.2. - # exact result would be 1/7 - self.assertTrue(tuple_jaccard_similarity.dissimilarity_test(sk1, sk2, 0.2)) - - # check that the Jaccard Index is at least (lower bound) 0.7 - # exact result would be 3/4, using result from A NOT B test - self.assertTrue(tuple_jaccard_similarity.similarity_test(sk1, result, 0.7)) - - - # Generates a basic tuple sketch with a fixed value for each update - def generate_tuple_sketch(self, policy, n, lgk, value, offset=0): - sk = update_tuple_sketch(policy, lgk) - for i in range(0, n): - sk.update(i + offset, value) - return sk - -if __name__ == '__main__': - unittest.main() diff --git a/tests/vector_of_kll_test.py b/tests/vector_of_kll_test.py deleted file mode 100644 index 51b2f0b2..00000000 --- a/tests/vector_of_kll_test.py +++ /dev/null @@ -1,155 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -import unittest -from datasketches import (vector_of_kll_ints_sketches, - vector_of_kll_floats_sketches) -import copy -import numpy as np - -class VectorOfKllSketchesTest(unittest.TestCase): - def test_vector_of_kll_floats_sketches_example(self): - k = 200 - d = 3 - n = 2 ** 20 - - # create a sketch and inject ~1 million N(0,1) points - kll = vector_of_kll_floats_sketches(k, d) - # Track the min/max for each sketch to test later - smin = np.zeros(d) + np.inf - smax = np.zeros(d) - np.inf - - for i in range(0, n): - dat = np.random.randn(d) - smin = np.amin([smin, dat], axis=0) - smax = np.amax([smax, dat], axis=0) - kll.update(dat) - - # 0 should be near the median - np.testing.assert_allclose(0.5, kll.get_ranks(0.0), atol=0.035) - # the median should be near 0 - np.testing.assert_allclose(0.0, kll.get_quantiles(0.5), atol=0.035) - # we also track the min/max independently from the rest of the data - # which lets us know the full observed data range - np.testing.assert_allclose(kll.get_min_values(), smin) - np.testing.assert_allclose(kll.get_max_values(), smax) - np.testing.assert_array_less(kll.get_min_values(), kll.get_quantiles(0.01)[:,0]) - np.testing.assert_array_less(kll.get_quantiles(0.99)[:,0], kll.get_max_values()) - - # we can also extract a list of values at a time, - # here the values should give us something close to [-2, -1, 0, 1, 2]. - # then get the CDF, which will return something close to - # the original values used in get_quantiles() - # finally, can check the normalized rank error bound - pts = kll.get_quantiles([0.0228, 0.1587, 0.5, 0.8413, 0.9772]) - # use the mean pts for the CDF, include 1.0 at end to account for all probability mass - meanpts = np.mean(pts, axis=0) - cdf = kll.get_cdf(meanpts) - self.assertEqual(cdf.shape[0], pts.shape[0]) - self.assertEqual(cdf.shape[1], pts.shape[1]+1) - - # and a few basic queries about the sketch - self.assertFalse(np.all(kll.is_empty())) - self.assertTrue(np.all(kll.is_estimation_mode())) - self.assertTrue(np.all(kll.get_n() == n)) - self.assertTrue(np.all(kll.get_num_retained() < n)) - - # we can combine sketches across all dimensions and get the result - result = kll.collapse() - self.assertEqual(result.n, d * n) - - # merging a copy of itself will double the number of items the sketch has seen - kll_copy = copy.copy(kll) - kll.merge(kll_copy) - np.testing.assert_equal(kll.get_n(), 2*n) - - # we can then serialize and reconstruct the sketch - kll_bytes = kll.serialize() # serializes each sketch as a list - new_kll = vector_of_kll_floats_sketches(k, d) - for s in range(len(kll_bytes)): - new_kll.deserialize(kll_bytes[s], s) - - # everything should be exactly equal - np.testing.assert_equal(kll.get_num_retained(), new_kll.get_num_retained()) - np.testing.assert_equal;(kll.get_min_values(), new_kll.get_min_values()) - np.testing.assert_equal(kll.get_max_values(), new_kll.get_max_values()) - np.testing.assert_equal(kll.get_quantiles(0.7), new_kll.get_quantiles(0.7)) - np.testing.assert_equal(kll.get_ranks(0.0), new_kll.get_ranks(0.0)) - - def test_kll_ints_sketches(self): - # already tested floats and it's templatized, so just make sure it instantiates properly - k = 100 - d = 5 - kll = vector_of_kll_ints_sketches(k, d) - self.assertTrue(np.all(kll.is_empty())) - - def test_kll_2Dupdates(self): - # 1D case tested in the first example - # 2D case will follow same idea, but focusing on update() - k = 200 - d = 3 - # we'll do ~250k updates of 4 values each (total ~1mil updates, as above) - n = 2 ** 18 - nbatch = 4 - - # create a sketch and inject ~1 million N(0,1) points - kll = vector_of_kll_floats_sketches(k, d) - # Track the min/max for each sketch to test later - smin = np.zeros(d) + np.inf - smax = np.zeros(d) - np.inf - - for i in range(0, n): - dat = np.random.randn(nbatch, d) - smin = np.amin(np.vstack((smin, dat)), axis=0) - smax = np.amax(np.vstack((smax, dat)), axis=0) - kll.update(dat) - - # 0 should be near the median - np.testing.assert_allclose(0.5, kll.get_ranks(0.0), atol=0.035) - # the median should be near 0 - np.testing.assert_allclose(0.0, kll.get_quantiles(0.5), atol=0.035) - # we also track the min/max independently from the rest of the data - # which lets us know the full observed data range - np.testing.assert_allclose(kll.get_min_values(), smin) - np.testing.assert_allclose(kll.get_max_values(), smax) - - # check that printing works as expected - self.assertGreater(len(kll.to_string(True, True)), 0) - self.assertEqual(len(kll.__str__()), len(kll.to_string())) - - - def test_kll_3Dupdates(self): - # now test 3D update, which should fail - k = 200 - d = 3 - - # create a sketch - kll = vector_of_kll_floats_sketches(k, d) - - # we'll try 1 3D update - dat = np.random.randn(10, 7, d) - try: - kll.update(dat) - np.testing.assert_(False) # should not reach here - except: - # this is what we expect - pass - # the sketches should still be empty - self.assertTrue(np.all(kll.is_empty())) - -if __name__ == '__main__': - unittest.main() diff --git a/tests/vo_test.py b/tests/vo_test.py deleted file mode 100644 index def29eb4..00000000 --- a/tests/vo_test.py +++ /dev/null @@ -1,141 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -import unittest -from datasketches import var_opt_sketch, var_opt_union, PyIntsSerDe, PyStringsSerDe - -class VoTest(unittest.TestCase): - def test_vo_example(self): - k = 50 # a small value so we can easily fill the sketch - vo = var_opt_sketch(k) - - # varopt sampling reduces to standard reservoir sampling - # if the items are all equally weighted, although the - # algorithm will be significantly slower than an optimized - # reservoir sampler - n = 5 * k - for i in range(0, n): - vo.update(i) - - # we can also add a heavy item, using a negative value for - # easy filtering later. Keep in mind that "heavy" is a - # relative concept, so using a fixed multiple of n may not - # be considered a heavy item for larger values of n - vo.update(-1, 1000 * n) - self.assertEqual(k, vo.k) - self.assertEqual(k, vo.num_samples) - self.assertEqual(n + 1, vo.n) - self.assertFalse(vo.is_empty()) - - # we can easily get the list of items in the sample - items = list(vo) - self.assertEqual(len(items), k) - - count = 0 - for tuple in vo: - sample = tuple[0] - weight = tuple[1] - count = count + 1 - self.assertEqual(count, vo.num_samples) - - # we can also apply a predicate to the sketch to get an estimate - # (with optimally minimal variance) of the subset sum of items - # matching that predicate among the entire population - - # we'll use a lambda here, but any function operating on a single - # item which returns a boolean value should work - summary = vo.estimate_subset_sum(lambda x: x < 0) - self.assertEqual(summary['estimate'], 1000 * n) - self.assertEqual(summary['total_sketch_weight'], 1001 * n) - - # a regular function is similarly handled - def geq_zero(x): - return x >= 0 - summary = vo.estimate_subset_sum(geq_zero) - self.assertEqual(summary['estimate'], n) - self.assertEqual(summary['total_sketch_weight'], 1001 * n) - - # next we'll create a second, smaller sketch with - # only heavier items relative to the previous sketch, - # but with the sketch in sampling mode - k2 = 5 - vo2 = var_opt_sketch(k2) - # for weight, use the estimate of all items >=0 from before - wt = summary['estimate'] - for i in range(0, k2 + 1): - vo2.update((2 * n) + i, wt) - - # now union the sketches, demonstrating how the - # union's k may not be equal to that of either - # input value - union = var_opt_union(k) - union.update(vo) - union.update(vo2) - - result = union.get_result() - self.assertEqual(n + k2 + 2, result.n) - self.assertFalse(result.is_empty()) - self.assertGreater(result.k, k2) - self.assertLess(result.k, k) - - # we can compare what information is available from both - # the union and a sketch. - print(union) - - # if we want to print the list of items, there must be a - # __str__() method for each item (which need not be the same - # type; they're all generic python objects when used from - # python), otherwise you may trigger an exception. - # to_string() is provided as a convenience to avoid direct - # calls to __str__() with parameters. - print(result.to_string(True)) - - # finally, we can serialize the sketch by providing an - # appropriate serde class. - expected_size = result.get_serialized_size_bytes(PyIntsSerDe()) - b = result.serialize(PyIntsSerDe()) - self.assertEqual(expected_size, len(b)) - - # if we try to deserialize with the wrong serde, things break - try: - var_opt_sketch.deserialize(b, PyStringsSerDe()) - self.fail() - except: - # expected; do nothing - self.assertTrue(True) - - # using the correct serde gives us back a copy of the original - rebuilt = var_opt_sketch.deserialize(b, PyIntsSerDe()) - self.assertEqual(result.k, rebuilt.k) - self.assertEqual(result.num_samples, rebuilt.num_samples) - self.assertEqual(result.n, rebuilt.n) - summary1 = result.estimate_subset_sum(geq_zero) - summary2 = rebuilt.estimate_subset_sum(geq_zero) - self.assertEqual(summary1['estimate'], summary2['estimate']) - self.assertEqual(summary1['total_sketch_weight'], summary2['total_sketch_weight']) - - # check that printing works as expected - self.assertGreater(len(result.to_string(True)), 0) - self.assertEqual(len(result.__str__()), len(result.to_string())) - - self.assertGreater(len(union.to_string()), 0) - self.assertEqual(len(union.__str__()), len(union.to_string())) - - - -if __name__ == '__main__': - unittest.main() diff --git a/tox.ini b/tox.ini deleted file mode 100644 index 64a1f683..00000000 --- a/tox.ini +++ /dev/null @@ -1,26 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -[tox] -envlist = py3 -isolated_build = true - -[testenv] -deps = pytest - numpy -changedir = tests -commands = pytest diff --git a/version.cfg.in b/version.cfg.in deleted file mode 100644 index 5ffad51a..00000000 --- a/version.cfg.in +++ /dev/null @@ -1 +0,0 @@ -5.3.@DT@.@HHMM@