From 2ff69c89e080994e3edfaaee34202b02849b47df Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 16 Oct 2023 16:19:32 +0100 Subject: [PATCH 001/232] Can now change backend (using code from geomstats) --- .../workflows/{tests.yml => tests_numpy.yml} | 0 .github/workflows/tests_pytorch.yml | 53 ++ pyrecest/__init__.py | 1 + pyrecest/_backend/LICENSE_geomstats | 9 + pyrecest/_backend/README.md | 37 + pyrecest/_backend/__init__.py | 294 +++++++ pyrecest/_backend/_backend_config.py | 9 + pyrecest/_backend/_common.py | 7 + pyrecest/_backend/_dtype_utils.py | 418 +++++++++ pyrecest/_backend/_shared_numpy/__init__.py | 422 +++++++++ pyrecest/_backend/_shared_numpy/_common.py | 117 +++ pyrecest/_backend/_shared_numpy/_dispatch.py | 12 + pyrecest/_backend/_shared_numpy/linalg.py | 105 +++ pyrecest/_backend/_shared_numpy/random.py | 29 + pyrecest/_backend/autograd/__init__.py | 175 ++++ pyrecest/_backend/autograd/_common.py | 36 + pyrecest/_backend/autograd/_dtype.py | 0 pyrecest/_backend/autograd/autodiff.py | 301 +++++++ pyrecest/_backend/autograd/linalg.py | 50 ++ pyrecest/_backend/autograd/random.py | 5 + pyrecest/_backend/numpy/__init__.py | 156 ++++ pyrecest/_backend/numpy/_common.py | 36 + pyrecest/_backend/numpy/_dtype.py | 0 pyrecest/_backend/numpy/autodiff.py | 61 ++ pyrecest/_backend/numpy/linalg.py | 27 + pyrecest/_backend/numpy/random.py | 7 + pyrecest/_backend/pytorch/__init__.py | 804 ++++++++++++++++++ pyrecest/_backend/pytorch/_common.py | 33 + pyrecest/_backend/pytorch/_dtype.py | 148 ++++ pyrecest/_backend/pytorch/autodiff.py | 364 ++++++++ pyrecest/_backend/pytorch/linalg.py | 149 ++++ pyrecest/_backend/pytorch/random.py | 44 + .../abstract_linear_distribution.py | 11 +- .../nonperiodic/custom_linear_distribution.py | 3 +- 34 files changed, 3917 insertions(+), 6 deletions(-) rename .github/workflows/{tests.yml => tests_numpy.yml} (100%) create mode 100644 .github/workflows/tests_pytorch.yml create mode 100644 pyrecest/_backend/LICENSE_geomstats create mode 100644 pyrecest/_backend/README.md create mode 100644 pyrecest/_backend/__init__.py create mode 100644 pyrecest/_backend/_backend_config.py create mode 100644 pyrecest/_backend/_common.py create mode 100644 pyrecest/_backend/_dtype_utils.py create mode 100644 pyrecest/_backend/_shared_numpy/__init__.py create mode 100644 pyrecest/_backend/_shared_numpy/_common.py create mode 100644 pyrecest/_backend/_shared_numpy/_dispatch.py create mode 100644 pyrecest/_backend/_shared_numpy/linalg.py create mode 100644 pyrecest/_backend/_shared_numpy/random.py create mode 100644 pyrecest/_backend/autograd/__init__.py create mode 100644 pyrecest/_backend/autograd/_common.py create mode 100644 pyrecest/_backend/autograd/_dtype.py create mode 100644 pyrecest/_backend/autograd/autodiff.py create mode 100644 pyrecest/_backend/autograd/linalg.py create mode 100644 pyrecest/_backend/autograd/random.py create mode 100644 pyrecest/_backend/numpy/__init__.py create mode 100644 pyrecest/_backend/numpy/_common.py create mode 100644 pyrecest/_backend/numpy/_dtype.py create mode 100644 pyrecest/_backend/numpy/autodiff.py create mode 100644 pyrecest/_backend/numpy/linalg.py create mode 100644 pyrecest/_backend/numpy/random.py create mode 100644 pyrecest/_backend/pytorch/__init__.py create mode 100644 pyrecest/_backend/pytorch/_common.py create mode 100644 pyrecest/_backend/pytorch/_dtype.py create mode 100644 pyrecest/_backend/pytorch/autodiff.py create mode 100644 pyrecest/_backend/pytorch/linalg.py create mode 100644 pyrecest/_backend/pytorch/random.py diff --git a/.github/workflows/tests.yml b/.github/workflows/tests_numpy.yml similarity index 100% rename from .github/workflows/tests.yml rename to .github/workflows/tests_numpy.yml diff --git a/.github/workflows/tests_pytorch.yml b/.github/workflows/tests_pytorch.yml new file mode 100644 index 00000000..42def008 --- /dev/null +++ b/.github/workflows/tests_pytorch.yml @@ -0,0 +1,53 @@ +--- + name: Test workflow + + permissions: read-all + + on: # yamllint disable-line rule:truthy + push: + pull_request: + branches: + - main + + jobs: + test: + runs-on: ubuntu-latest + permissions: + checks: write + pull-requests: write + + steps: + - name: Check out repository + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: "3.11" + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + python -m pip install poetry + poetry install --extras healpy_support + + - name: List files and check Python and package versions + run: | + ls -al + python -c 'import sys; print(sys.version_info[:])' + python -m pip freeze + + - name: Run tests + run: | + poetry env use python + PYRECEST_BACKEND=pytorch + poetry run python -m pytest --rootdir . -v --strict-config --junitxml=junit_test_results.xml ./pyrecest + env: + PYTHONPATH: ${{ github.workspace }} + + - name: Publish test results + if: always() + uses: EnricoMi/publish-unit-test-result-action@v2 + with: + files: junit_test_results.xml + \ No newline at end of file diff --git a/pyrecest/__init__.py b/pyrecest/__init__.py index e69de29b..8cff810a 100644 --- a/pyrecest/__init__.py +++ b/pyrecest/__init__.py @@ -0,0 +1 @@ +import pyrecest._backend \ No newline at end of file diff --git a/pyrecest/_backend/LICENSE_geomstats b/pyrecest/_backend/LICENSE_geomstats new file mode 100644 index 00000000..4e76c158 --- /dev/null +++ b/pyrecest/_backend/LICENSE_geomstats @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) 2018 Nina Miolane + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/pyrecest/_backend/README.md b/pyrecest/_backend/README.md new file mode 100644 index 00000000..24c9691d --- /dev/null +++ b/pyrecest/_backend/README.md @@ -0,0 +1,37 @@ +# _Backend Folder + +This folder contains code from the Geomstats project, adjusted for pyRecEst by Florian Pfaff. The original version of Geomstats is authored by Nina Miolane et al., and is a Python package geared towards Riemannian Geometry in Machine Learning. + +## Original Project Details + +- **Title**: Geomstats: A Python Package for Riemannian Geometry in Machine Learning +- **Authors**: Nina Miolane, Nicolas Guigui, Alice Le Brigant, Johan Mathe, Benjamin Hou, Yann Thanwerdas, Stefan Heyder, Olivier Peltre, Niklas Koep, Hadi Zaatiti, Hatem Hajri, Yann Cabanes, Thomas Gerald, Paul Chauchat, Christian Shewmake, Daniel Brooks, Bernhard Kainz, Claire Donnat, Susan Holmes, Xavier Pennec +- **Journal**: Journal of Machine Learning Research, 2020, Vol. 21, No. 223, Pp. 1-9 +- **URL**: [Geomstats Project](http://jmlr.org/papers/v21/19-027.html) + +## License + +This code is provided under the MIT License. A copy of the license can be found in this folder. + +## Modifications + +The code in this folder has been modified by Florian Pfaff to adapt it to pyRecEst. + +## (Adapted) Usage Instructions + +In order to expose a new backend function/attribute to the rest of the +codebase, it is necessary to add the name to the respective list in the +`BACKEND_ATTRIBUTES` dictionary in `pyrecest/_backend/__init__.py`. +This serves two purposes: + +1. Define a clear boundary between backend interface and backend-internal code: + Only functions/attributes which are used outside the backend should be made + available to the rest of the codebase. +1. Guarantee each backend exposes the same attributes: + When loading a backend, the backend importer verifies that a backend + provides each attribute listed in the `BACKEND_ATTRIBUTES` dict. + This way, we guarantee that unit tests fail during CI builds when a + maintainer/contributor forgets to provide an implementation of a feature for + a particular backend. + If a feature cannot be supported for some reason, the function should raise + a `NotImplementedError` for the time being. diff --git a/pyrecest/_backend/__init__.py b/pyrecest/_backend/__init__.py new file mode 100644 index 00000000..84a255a0 --- /dev/null +++ b/pyrecest/_backend/__init__.py @@ -0,0 +1,294 @@ +"""Execution backends. + +Lead authors: Johan Mathe and Niklas Koep. +""" + +import importlib +import logging +import os +import sys +import types + +import pyrecest._backend._common as common + + +def get_backend_name(): + return os.environ.get("PYRECEST_BACKEND", "numpy") + + +BACKEND_NAME = get_backend_name() + + +BACKEND_ATTRIBUTES = { + "": [ + # Types + "int32", + "int64", + "float32", + "float64", + "complex64", + "complex128", + "uint8", + # Functions + "abs", + "all", + "allclose", + "amax", + "amin", + "angle", + "any", + "arange", + "arccos", + "arccosh", + "arcsin", + "arctan2", + "arctanh", + "argmax", + "argmin", + "array", + "array_from_sparse", + "as_dtype", + "assignment", + "assignment_by_sum", + "atol", + "broadcast_arrays", + "broadcast_to", + "cast", + "ceil", + "clip", + "comb", + "concatenate", + "conj", + "convert_to_wider_dtype", + "copy", + "cos", + "cosh", + "cross", + "cumprod", + "cumsum", + "diag_indices", + "diagonal", + "divide", + "dot", + "einsum", + "empty", + "empty_like", + "equal", + "erf", + "exp", + "expand_dims", + "eye", + "flatten", + "flip", + "floor", + "from_numpy", + "gamma", + "get_default_dtype", + "get_default_cdtype", + "get_slice", + "greater", + "hsplit", + "hstack", + "imag", + "isclose", + "isnan", + "is_array", + "is_complex", + "is_floating", + "is_bool", + "kron", + "less", + "less_equal", + "linspace", + "log", + "logical_and", + "logical_or", + "mat_from_diag_triu_tril", + "matmul", + "matvec", + "maximum", + "mean", + "meshgrid", + "minimum", + "mod", + "moveaxis", + "ndim", + "one_hot", + "ones", + "ones_like", + "outer", + "pad", + "pi", + "polygamma", + "power", + "prod", + "quantile", + "ravel_tril_indices", + "real", + "repeat", + "reshape", + "rtol", + "scatter_add", + "searchsorted", + "set_default_dtype", + "set_diag", + "shape", + "sign", + "sin", + "sinh", + "split", + "sqrt", + "squeeze", + "sort", + "stack", + "std", + "sum", + "take", + "tan", + "tanh", + "tile", + "to_numpy", + "to_ndarray", + "trace", + "transpose", + "tril", + "triu", + "tril_indices", + "triu_indices", + "tril_to_vec", + "triu_to_vec", + "vec_to_diag", + "unique", + "vectorize", + "vstack", + "where", + "zeros", + "zeros_like", + "trapz", + ], + "autodiff": [ + "custom_gradient", + "hessian", + "hessian_vec", + "jacobian", + "jacobian_vec", + "jacobian_and_hessian", + "value_and_grad", + "value_jacobian_and_hessian", + ], + "linalg": [ + "cholesky", + "det", + "eig", + "eigh", + "eigvalsh", + "expm", + "fractional_matrix_power", + "inv", + "is_single_matrix_pd", + "logm", + "norm", + "qr", + "quadratic_assignment", + "solve", + "solve_sylvester", + "sqrtm", + "svd", + "matrix_rank", + ], + "random": [ + "choice", + "normal", + "multivariate_normal", + # TODO (nkoep): Remove 'rand' and replace it by 'uniform'. Much like + # 'randn' is a convenience wrapper (which we don't use) + # for 'normal', 'rand' only wraps 'uniform'. + "rand", + "randint", + "seed", + "uniform", + ], +} + + +class BackendImporter: + """Importer class to create the backend module.""" + + def __init__(self, path): + self._path = path + + @staticmethod + def _import_backend(backend_name): + try: + return importlib.import_module(f"pyrecest._backend.{backend_name}") + except ModuleNotFoundError: + raise RuntimeError(f"Unknown backend '{backend_name}'") + + def _create_backend_module(self, backend_name): + backend = self._import_backend(backend_name) + + new_module = types.ModuleType(self._path) + new_module.__file__ = backend.__file__ + + for module_name, attributes in BACKEND_ATTRIBUTES.items(): + if module_name: + try: + submodule = getattr(backend, module_name) + except AttributeError: + raise RuntimeError( + f"Backend '{backend_name}' exposes no '{module_name}' module" + ) from None + new_submodule = types.ModuleType(f"{self._path}.{module_name}") + new_submodule.__file__ = submodule.__file__ + setattr(new_module, module_name, new_submodule) + else: + submodule = backend + new_submodule = new_module + for attribute_name in attributes: + try: + submodule_ = submodule + if module_name == "" and not hasattr(submodule, attribute_name): + submodule_ = common + attribute = getattr(submodule_, attribute_name) + + except AttributeError: + if module_name: + error = ( + f"Module '{module_name}' of backend '{backend_name}' " + f"has no attribute '{attribute_name}'" + ) + else: + error = ( + f"Backend '{backend_name}' has no " + f"attribute '{attribute_name}'" + ) + + raise RuntimeError(error) from None + else: + setattr(new_submodule, attribute_name, attribute) + + return new_module + + def find_module(self, fullname, path=None): + """Find module.""" + if self._path != fullname: + return None + return self + + def load_module(self, fullname): + """Load module.""" + if fullname in sys.modules: + return sys.modules[fullname] + + module = self._create_backend_module(BACKEND_NAME) + module.__name__ = f"pyrecest.{BACKEND_NAME}" + module.__loader__ = self + sys.modules[fullname] = module + + module.set_default_dtype("float64") + + logging.info(f"Using {BACKEND_NAME} backend") + return module + + +sys.meta_path.append(BackendImporter("pyrecest.backend")) diff --git a/pyrecest/_backend/_backend_config.py b/pyrecest/_backend/_backend_config.py new file mode 100644 index 00000000..7ec4b5f1 --- /dev/null +++ b/pyrecest/_backend/_backend_config.py @@ -0,0 +1,9 @@ +pytorch_atol = 1e-6 +pytorch_rtol = 1e-5 + +np_atol = 1e-12 +np_rtol = 1e-6 + + +DEFAULT_DTYPE = None +DEFAULT_COMPLEX_DTYPE = None diff --git a/pyrecest/_backend/_common.py b/pyrecest/_backend/_common.py new file mode 100644 index 00000000..c9cb1c8c --- /dev/null +++ b/pyrecest/_backend/_common.py @@ -0,0 +1,7 @@ +import math as _math + +from numpy import pi + + +def comb(n, k): + return _math.factorial(n) // _math.factorial(k) // _math.factorial(n - k) diff --git a/pyrecest/_backend/_dtype_utils.py b/pyrecest/_backend/_dtype_utils.py new file mode 100644 index 00000000..884c990e --- /dev/null +++ b/pyrecest/_backend/_dtype_utils.py @@ -0,0 +1,418 @@ +"""Machinery to handle global control of dtypes. + +Notes +----- +Functions starting with "_pre" are shared functions that just need access to +specific backend functions. e.g. `_pre_set_default_dtype` requires access to +`as_dtype`. `set_default_dtype` can then be created in each backend by doing +`set_default_dtype = _pre_set_default_dtype(as_dtype)`. The same principle +applies to ("_pre") decorators. This decreases code duplication, while being +able to avoid (dirty) circular imports. +""" + +import functools +import inspect +import types + +from pyrecest._backend import _backend_config as _config + +_TO_UPDATE_FUNCS_DTYPE = [] +_TO_UPDATE_FUNCS_KW_DTYPE = [] + + +_MAP_FLOAT_TO_COMPLEX = { + "float32": "complex64", + "float64": "complex128", +} + + +def _copy_func(func): + """Copy function.""" + new_func = types.FunctionType( + func.__code__, + func.__globals__, + func.__name__, + func.__defaults__, + func.__closure__, + ) + new_func.__dict__.update(func.__dict__) + new_func.__kwdefaults__ = func.__kwdefaults__ + + return new_func + + +def _get_dtype_pos_in_defaults(func): + """Get dtype position in defaults.""" + pos = 0 + for name, parameter in inspect.signature(func).parameters.items(): + if name == "dtype": + return pos + if parameter.default is not inspect._empty: + pos += 1 + + raise Exception("dtype is not kwarg") + + +def _update_default_dtypes(): + """Update default dtype of functions. + + How it works? + ------------- + "dtype" is updated in __defaults__ or __kwdefaults__ to default dtype. + + Every time default dtype is changed, all the functions that follow this + strategy will have their default dtype updated. + + It (mutably) changes function defaults. For external functions, copy the + function first to avoid surprising users. + """ + for func in _TO_UPDATE_FUNCS_DTYPE: + pos = _get_dtype_pos_in_defaults(func) + defaults = list(func.__defaults__) + defaults[pos] = _config.DEFAULT_DTYPE + func.__defaults__ = tuple(defaults) + + for func in _TO_UPDATE_FUNCS_KW_DTYPE: + func.__kwdefaults__["dtype"] = _config.DEFAULT_DTYPE + + +def _modify_func_default_dtype(copy=True, kw_only=False, target=None): + """Modify function default dtype by acting directly in the target object. + + Parameters + ---------- + copy: bool + If true, copies function before changing dtype. + kw_only : bool + If true, it is assumed dtype is kwarg only argument. + + How it works? + ------------- + This decorator only collects functions. Default dtype is modified only + when default dtype is changed (see `_update_default_dtypes`). + """ + + def _decorator(func): + new_func = _copy_func(func) if copy else func + + if kw_only: + _TO_UPDATE_FUNCS_KW_DTYPE.append(new_func) + else: + _TO_UPDATE_FUNCS_DTYPE.append(new_func) + + return new_func + + if target is None: + return _decorator + + return _decorator(target) + + +def get_default_dtype(): + """Get backend default float dtype.""" + return _config.DEFAULT_DTYPE + + +def get_default_cdtype(): + """Get backend default complex dtype.""" + return _config.DEFAULT_COMPLEX_DTYPE + + +def _dyn_update_dtype(dtype_pos=None, target=None): + """Update (dynamically) function dtype. + + Parameters + ---------- + dtype_pos : int + Position of "dtype" argument. + + How it works? + ------------- + When the function is called, it verifies if dtype is passed. If not, it + uses default dtype. + """ + + def _decorator(func): + @functools.wraps(func) + def _wrapped(*args, **kwargs): + if dtype_pos is not None and len(args) > dtype_pos: + args = list(args) + args[dtype_pos] = _config.DEFAULT_DTYPE + + else: + if kwargs.get("dtype") is None: + kwargs["dtype"] = _config.DEFAULT_DTYPE + + return func(*args, **kwargs) + + return _wrapped + + if target is None: + return _decorator + + return _decorator(target) + + +def _pre_set_default_dtype(as_dtype): + def set_default_dtype(value): + """Set backend default dtype. + + Parameters + ---------- + value : str + Possible values are "float32" as "float64". + """ + _config.DEFAULT_DTYPE = as_dtype(value) + _config.DEFAULT_COMPLEX_DTYPE = as_dtype(_MAP_FLOAT_TO_COMPLEX[value]) + + _update_default_dtypes() + + return get_default_dtype() + + return set_default_dtype + + +def _pre_cast_out_from_dtype(cast, is_floating, is_complex): + def _cast_out_from_dtype(dtype_pos=None, target=None): + """Cast output based on default dtype. + + Useful to wrap functions which output dtype cannot be (fully) controlled + or for which is useful to run it without controlling dtype and cast + afterwards (e.g. array). + + Parameters + ---------- + dtype_pos : int + Position of "dtype" argument. + + How it works? + ------------- + Function is called normally. If output is float or complex, then it + checks if is of expected dtype. If not, cast is performed. + """ + + def _decorator(func): + @functools.wraps(func) + def _wrapped(*args, **kwargs): + out = func(*args, **kwargs) + + if is_floating(out) or is_complex(out): + if dtype_pos is not None and len(args) > dtype_pos: + dtype = args[dtype_pos] + else: + dtype = kwargs.get( + "dtype", + _config.DEFAULT_DTYPE + if is_floating(out) + else _config.DEFAULT_COMPLEX_DTYPE, + ) + + if out.dtype != dtype: + return cast(out, dtype) + + return out + + return _wrapped + + if target is None: + return _decorator + + return _decorator(target) + + return _cast_out_from_dtype + + +def _pre_add_default_dtype_by_casting(cast): + def _add_default_dtype_by_casting(target=None): + """Add default dtype as function argument. + + Behavior is achieved by casting output (not ideal, but impoosible to + avoid without acting directly in the backends themselves). + + How it works? + ------------- + Function is called normally. If output is float or complex, then it + checks if is of expected dtype. If not, cast is performed. + + The difference to `_cast_out_from_dtype` is that wrapped functions do + not accept dtype. + """ + + def _decorator(func): + @functools.wraps(func) + def _wrapped(*args, dtype=None, **kwargs): + if dtype is None: + dtype = _config.DEFAULT_DTYPE + + out = func(*args, **kwargs) + if out.dtype != dtype: + return cast(out, dtype) + return out + + return _wrapped + + if target is None: + return _decorator + + return _decorator(target) + + return _add_default_dtype_by_casting + + +def _pre_cast_fout_to_input_dtype(cast, is_floating): + def _cast_fout_to_input_dtype(target=None): + """Cast out func if float and not accordingly to input. + + It is required e.g. for scipy when result is innacurate. + + How it works? + ------------- + Function is called normally. If output is float, then it + checks if is of expected dtype (input dtype). If not, cast is performed. + + The difference to `_cast_out_from_dtype` is that output is expected to + have same type as input. + """ + + def _decorator(func): + @functools.wraps(func) + def _wrapped(x, *args, **kwargs): + out = func(x, *args, **kwargs) + if is_floating(out) and out.dtype != x.dtype: + return cast(out, x.dtype) + return out + + return _wrapped + + if target is None: + return _decorator + + return _decorator(target) + + return _cast_fout_to_input_dtype + + +def _pre_cast_out_to_input_dtype(cast, is_floating, is_complex, as_dtype, dtype_as_str): + def _cast_out_to_input_dtype(target=None): + """Cast out func if float or complex and not accordingly to input. + + How it works? + ------------- + Function is called normally. + If output is float, then it checks if is of expected dtype + (input dtype). If not, cast is performed. + If output is complex, then if first check if input is complex, if not + it verifies the required precision for complex dtype and casts + accordingly (if necessary) + """ + + def _decorator(func): + @functools.wraps(func) + def _wrapped(x, *args, **kwargs): + out = func(x, *args, **kwargs) + + if is_floating(out): + if out.dtype != x.dtype: + return cast(out, x.dtype) + elif is_complex(out): + if is_complex(x): + cmp_dtype = x.dtype + else: + float_name = dtype_as_str(x.dtype) + cmp_dtype = as_dtype(f"complex{int((float_name[-2:]))*2}") + + if out.dtype != cmp_dtype: + return cast(out, cmp_dtype) + + return out + + return _wrapped + + if target is None: + return _decorator + + return _decorator(target) + + return _cast_out_to_input_dtype + + +def _pre_allow_complex_dtype(cast, complex_dtypes): + def _allow_complex_dtype(target=None): + """Allow complex type by calling the function twice. + + Assumes function do not support dtype. + + How it works? + ------------- + Function is called twice if dtype is complex. + Output is casted if not corresponding to expected dtype. + """ + + def _decorator(func): + @functools.wraps(func) + def _wrapped(*args, dtype=None, **kwargs): + out = func(*args, **kwargs) + if dtype in complex_dtypes: + out = out + 1j * func(*args, **kwargs) + + if out.dtype != dtype: + return cast(out, dtype) + + return out + + return _wrapped + + if target is None: + return _decorator + + return _decorator(target) + + return _allow_complex_dtype + + +def _np_box_unary_scalar(target=None): + """Update dtype if input is float in unary operations. + + How it works? + ------------- + If dtype is float, then default dtype is passed as argument. + """ + + def _decorator(func): + @functools.wraps(func) + def _wrapped(x, *args, **kwargs): + if type(x) is float: + return func(x, *args, dtype=_config.DEFAULT_DTYPE, **kwargs) + + return func(x, *args, **kwargs) + + return _wrapped + + if target is None: + return _decorator + + return _decorator(target) + + +def _np_box_binary_scalar(target=None): + """Update dtype if input is float in binary operations. + + How it works? + ------------- + If dtype is float, then default dtype is passed as argument. + """ + + def _decorator(func): + @functools.wraps(func) + def _wrapped(x1, x2, *args, **kwargs): + if type(x1) is float: + return func(x1, x2, *args, dtype=_config.DEFAULT_DTYPE, **kwargs) + + return func(x1, x2, *args, **kwargs) + + return _wrapped + + if target is None: + return _decorator + + return _decorator(target) diff --git a/pyrecest/_backend/_shared_numpy/__init__.py b/pyrecest/_backend/_shared_numpy/__init__.py new file mode 100644 index 00000000..9857cad0 --- /dev/null +++ b/pyrecest/_backend/_shared_numpy/__init__.py @@ -0,0 +1,422 @@ +from ._dispatch import BACKEND_NAME, _common +from ._dispatch import numpy as _np + +_is_iterable = _common._is_iterable +_is_boolean = _common._is_boolean +_get_wider_dtype = _common._get_wider_dtype +array = _common.array +cast = _common.cast +convert_to_wider_dtype = _common.convert_to_wider_dtype +eye = _common.eye +is_array = _common.is_array +get_default_dtype = _common.get_default_dtype +zeros = _common.zeros +_box_unary_scalar = _common._box_unary_scalar +_box_binary_scalar = _common._box_binary_scalar + +abs = _box_unary_scalar(target=_np.abs) +arccos = _box_unary_scalar(target=_np.arccos) +arccosh = _box_unary_scalar(target=_np.arccosh) +arcsin = _box_unary_scalar(target=_np.arcsin) +arctanh = _box_unary_scalar(target=_np.arctanh) +ceil = _box_unary_scalar(target=_np.ceil) +cos = _box_unary_scalar(target=_np.cos) +cosh = _box_unary_scalar(target=_np.cosh) +exp = _box_unary_scalar(target=_np.exp) +floor = _box_unary_scalar(target=_np.floor) +log = _box_unary_scalar(target=_np.log) +sign = _box_unary_scalar(target=_np.sign) +sin = _box_unary_scalar(target=_np.sin) +sinh = _box_unary_scalar(target=_np.sinh) +sqrt = _box_unary_scalar(target=_np.sqrt) +tan = _box_unary_scalar(target=_np.tan) +tanh = _box_unary_scalar(target=_np.tanh) + +arctan2 = _box_binary_scalar(target=_np.arctan2) +mod = _box_binary_scalar(target=_np.mod) +power = _box_binary_scalar(target=_np.power) + + +def angle(z, deg=False): + out = _np.angle(z, deg=deg) + if type(z) is float: + return cast(out, get_default_dtype()) + + return out + + +def imag(x): + out = _np.imag(x) + if is_array(x): + return out + + return get_default_dtype().type(out) + + +def real(x): + out = _np.real(x) + if is_array(x): + return out + + return array(out) + + +def arange(start_or_stop, /, stop=None, step=1, dtype=None, **kwargs): + if dtype is None and ( + type(stop) is float or type(step) is float or type(start_or_stop) is float + ): + dtype = get_default_dtype() + + if stop is None: + return _np.arange(start_or_stop, step=step, dtype=dtype) + + return _np.arange(start_or_stop, stop, step=step, dtype=dtype) + + +def to_numpy(x): + return x + + +def from_numpy(x): + return x + + +def squeeze(x, axis=None): + if axis is None: + return _np.squeeze(x) + if x.shape[axis] != 1: + return x + return _np.squeeze(x, axis=axis) + + +def flatten(x): + return x.flatten() + + +def one_hot(labels, num_classes): + return eye(num_classes, dtype=_np.dtype("uint8"))[labels] + + +def assignment(x, values, indices, axis=0): + """Assign values at given indices of an array. + + Parameters + ---------- + x: array-like, shape=[dim] + Initial array. + values: {float, list(float)} + Value or list of values to be assigned. + indices: {int, tuple, list(int), list(tuple)} + Single int or tuple, or list of ints or tuples of indices where value + is assigned. + If the length of the tuples is shorter than ndim(x), values are + assigned to each copy along axis. + axis: int, optional + Axis along which values are assigned, if vectorized. + + Returns + ------- + x_new : array-like, shape=[dim] + Copy of x with the values assigned at the given indices. + + Notes + ----- + If a single value is provided, it is assigned at all the indices. + If a list is given, it must have the same length as indices. + """ + x_new = copy(x) + + use_vectorization = hasattr(indices, "__len__") and len(indices) < ndim(x) + if _is_boolean(indices): + x_new[indices] = values + return x_new + zip_indices = _is_iterable(indices) and _is_iterable(indices[0]) + len_indices = len(indices) if _is_iterable(indices) else 1 + if zip_indices: + indices = tuple(zip(*indices)) + if not use_vectorization: + if not zip_indices: + len_indices = len(indices) if _is_iterable(indices) else 1 + len_values = len(values) if _is_iterable(values) else 1 + if len_values > 1 and len_values != len_indices: + raise ValueError("Either one value or as many values as indices") + x_new[indices] = values + else: + indices = tuple(list(indices[:axis]) + [slice(None)] + list(indices[axis:])) + x_new[indices] = values + return x_new + + +def assignment_by_sum(x, values, indices, axis=0): + """Add values at given indices of an array. + + Parameters + ---------- + x : array-like, shape=[dim] + Initial array. + values : {float, list(float)} + Value or list of values to be assigned. + indices : {int, tuple, list(int), list(tuple)} + Single int or tuple, or list of ints or tuples of indices where value + is assigned. + If the length of the tuples is shorter than ndim(x), values are + assigned to each copy along axis. + axis: int, optional + Axis along which values are assigned, if vectorized. + + Returns + ------- + x_new : array-like, shape=[dim] + Copy of x with the values assigned at the given indices. + + Notes + ----- + If a single value is provided, it is assigned at all the indices. + If a list is given, it must have the same length as indices. + """ + x_new = copy(x) + + use_vectorization = hasattr(indices, "__len__") and len(indices) < ndim(x) + if _is_boolean(indices): + x_new[indices] += values + return x_new + zip_indices = _is_iterable(indices) and _is_iterable(indices[0]) + if zip_indices: + indices = tuple(zip(*indices)) + if not use_vectorization: + len_indices = len(indices) if _is_iterable(indices) else 1 + len_values = len(values) if _is_iterable(values) else 1 + if len_values > 1 and len_values != len_indices: + raise ValueError("Either one value or as many values as indices") + x_new[indices] += values + else: + indices = tuple(list(indices[:axis]) + [slice(None)] + list(indices[axis:])) + x_new[indices] += values + return x_new + + +def ndim(x): + return x.ndim + + +def get_slice(x, indices): + """Return a slice of an array, following Numpy's style. + + Parameters + ---------- + x : array-like, shape=[dim] + Initial array. + indices : iterable(iterable(int)) + Indices which are kept along each axis, starting from 0. + + Returns + ------- + slice : array-like + Slice of x given by indices. + + Notes + ----- + This follows Numpy's convention: indices are grouped by axis. + + Examples + -------- + >>> a = np.array(range(30)).reshape(3,10) + >>> get_slice(a, ((0, 2), (8, 9))) + array([8, 29]) + """ + return x[indices] + + +def vectorize(x, pyfunc, multiple_args=False, signature=None, **kwargs): + if multiple_args: + return _np.vectorize(pyfunc, signature=signature)(*x) + return _np.vectorize(pyfunc, signature=signature)(x) + + +def set_diag(x, new_diag): + """Set the diagonal along the last two axis. + + Parameters + ---------- + x : array-like, shape=[dim] + Initial array. + new_diag : array-like, shape=[dim[-2]] + Values to set on the diagonal. + + Returns + ------- + None + + Notes + ----- + This mimics tensorflow.linalg.set_diag(x, new_diag), when new_diag is a + 1-D array, but modifies x instead of creating a copy. + """ + arr_shape = x.shape + x[..., range(arr_shape[-2]), range(arr_shape[-1])] = new_diag + return x + + +def copy(x): + return x.copy() + + +def array_from_sparse(indices, data, target_shape): + """Create an array of given shape, with values at specific indices. + + The rest of the array will be filled with zeros. + + Parameters + ---------- + indices : iterable(tuple(int)) + Index of each element which will be assigned a specific value. + data : iterable(scalar) + Value associated at each index. + target_shape : tuple(int) + Shape of the output array. + + Returns + ------- + a : array, shape=target_shape + Array of zeros with specified values assigned to specified indices. + """ + data = array(data) + out = zeros(target_shape, dtype=data.dtype) + out.put(_np.ravel_multi_index(_np.array(indices).T, target_shape), data) + return out + + +def vec_to_diag(vec): + """Convert vector to diagonal matrix.""" + d = vec.shape[-1] + return _np.squeeze(vec[..., None, :] * eye(d, dtype=vec.dtype)[None, :, :]) + + +def tril_to_vec(x, k=0): + n = x.shape[-1] + rows, cols = _np.tril_indices(n, k=k) + return x[..., rows, cols] + + +def triu_to_vec(x, k=0): + n = x.shape[-1] + rows, cols = _np.triu_indices(n, k=k) + return x[..., rows, cols] + + +def mat_from_diag_triu_tril(diag, tri_upp, tri_low): + """Build matrix from given components. + + Forms a matrix from diagonal, strictly upper triangular and + strictly lower traingular parts. + + Parameters + ---------- + diag : array_like, shape=[..., n] + tri_upp : array_like, shape=[..., (n * (n - 1)) / 2] + tri_low : array_like, shape=[..., (n * (n - 1)) / 2] + + Returns + ------- + mat : array_like, shape=[..., n, n] + """ + diag, tri_upp, tri_low = convert_to_wider_dtype([diag, tri_upp, tri_low]) + + n = diag.shape[-1] + (i,) = _np.diag_indices(n, ndim=1) + j, k = _np.triu_indices(n, k=1) + mat = zeros(diag.shape + (n,), dtype=diag.dtype) + mat[..., i, i] = diag + mat[..., j, k] = tri_upp + mat[..., k, j] = tri_low + return mat + + +def divide(a, b, ignore_div_zero=False): + if ignore_div_zero is False: + return _np.divide(a, b) + + wider_dtype, _ = _get_wider_dtype([a, b]) + return _np.divide(a, b, out=zeros(a.shape, dtype=wider_dtype), where=b != 0) + + +def ravel_tril_indices(n, k=0, m=None): + if m is None: + size = (n, n) + else: + size = (n, m) + idxs = _np.tril_indices(n, k, m) + return _np.ravel_multi_index(idxs, size) + + +def matmul(*ar_gs, **kwar_gs): + for arg in ar_gs: + if arg.ndim == 1: + raise ValueError("ndims must be >=2") + return _np.matmul(*ar_gs, **kwar_gs) + + +def outer(a, b): + if a.ndim == 2 and b.ndim == 2: + return _np.einsum("...i,...j->...ij", a, b) + + out = _np.multiply.outer(a, b) + if b.ndim == 2: + out = out.swapaxes(-3, -2) + + return out + + +def matvec(A, b): + if b.ndim == 1: + return _np.matmul(A, b) + if A.ndim == 2: + return _np.matmul(A, b.T).T + return _np.einsum("...ij,...j->...i", A, b) + + +def dot(a, b): + if b.ndim == 1: + return _np.dot(a, b) + + if a.ndim == 1: + return _np.dot(a, b.T) + + return _np.einsum("...i,...i->...", a, b) + + +def trace(a): + return _np.trace(a, axis1=-2, axis2=-1) + + +def scatter_add(input, dim, index, src): + """Add values from src into input at the indices specified in index. + + Parameters + ---------- + input : array-like + Tensor to scatter values into. + dim : int + The axis along which to index. + index : array-like + The indices of elements to scatter. + src : array-like + The source element(s) to scatter. + + Returns + ------- + input : array-like + Modified input array. + """ + if dim == 0: + for i, val in zip(index, src): + input[i] += val + return input + if dim == 1: + for j in range(len(input)): + for i, val in zip(index[j], src[j]): + if not isinstance(val, _np.float64) and BACKEND_NAME == "autograd": + val = float(val._value) + input[j, i] += float(val) + return input + raise NotImplementedError diff --git a/pyrecest/_backend/_shared_numpy/_common.py b/pyrecest/_backend/_shared_numpy/_common.py new file mode 100644 index 00000000..172fe318 --- /dev/null +++ b/pyrecest/_backend/_shared_numpy/_common.py @@ -0,0 +1,117 @@ +from pyrecest._backend._dtype_utils import _np_box_binary_scalar as _box_binary_scalar +from pyrecest._backend._dtype_utils import _np_box_unary_scalar as _box_unary_scalar +from pyrecest._backend._dtype_utils import ( + _pre_add_default_dtype_by_casting, + _pre_allow_complex_dtype, + _pre_cast_fout_to_input_dtype, + _pre_cast_out_from_dtype, + _pre_cast_out_to_input_dtype, + _pre_set_default_dtype, +) + +from .._backend_config import np_atol as atol +from .._backend_config import np_rtol as rtol +from ._dispatch import numpy as _np + +_DTYPES = { + _np.dtype("int32"): 0, + _np.dtype("int64"): 1, + _np.dtype("float32"): 2, + _np.dtype("float64"): 3, + _np.dtype("complex64"): 4, + _np.dtype("complex128"): 5, +} + +_COMPLEX_DTYPES = [ + _np.complex64, + _np.complex128, +] + + +def is_floating(x): + return x.dtype.kind == "f" + + +def is_complex(x): + return x.dtype.kind == "c" + + +def is_bool(x): + return x.dtype.kind == "b" + + +def as_dtype(value): + """Transform string representing dtype in dtype.""" + return _np.dtype(value) + + +def _dtype_as_str(dtype): + return dtype.name + + +def cast(x, dtype): + return x.astype(dtype) + + +set_default_dtype = _pre_set_default_dtype(as_dtype) + +_add_default_dtype_by_casting = _pre_add_default_dtype_by_casting(cast) +_cast_fout_to_input_dtype = _pre_cast_fout_to_input_dtype(cast, is_floating) +_cast_out_to_input_dtype = _pre_cast_out_to_input_dtype( + cast, is_floating, is_complex, as_dtype, _dtype_as_str +) + + +_cast_out_from_dtype = _pre_cast_out_from_dtype(cast, is_floating, is_complex) +_allow_complex_dtype = _pre_allow_complex_dtype(cast, _COMPLEX_DTYPES) + + +def is_array(x): + return type(x) is _np.ndarray + + +def to_ndarray(x, to_ndim, axis=0): + x = _np.array(x) + if x.ndim == to_ndim - 1: + x = _np.expand_dims(x, axis=axis) + + if x.ndim != 0 and x.ndim < to_ndim: + raise ValueError("The ndim was not adapted properly.") + return x + + +def _get_wider_dtype(tensor_list): + dtype_list = [_DTYPES.get(x.dtype, -1) for x in tensor_list] + if len(dtype_list) == 1: + return dtype_list[0], True + + wider_dtype_index = max(dtype_list) + wider_dtype = list(_DTYPES.keys())[wider_dtype_index] + + return wider_dtype, False + + +def convert_to_wider_dtype(tensor_list): + wider_dtype, same = _get_wider_dtype(tensor_list) + if same: + return tensor_list + + return [cast(x, dtype=wider_dtype) for x in tensor_list] + + +def _is_boolean(x): + if isinstance(x, bool): + return True + if isinstance(x, (tuple, list)): + return _is_boolean(x[0]) + if isinstance(x, _np.ndarray): + return x.dtype == bool + return False + + +def _is_iterable(x): + if isinstance(x, (list, tuple)): + return True + if isinstance(x, _np.ndarray): + return x.ndim > 0 + return False diff --git a/pyrecest/_backend/_shared_numpy/_dispatch.py b/pyrecest/_backend/_shared_numpy/_dispatch.py new file mode 100644 index 00000000..4ad650f6 --- /dev/null +++ b/pyrecest/_backend/_shared_numpy/_dispatch.py @@ -0,0 +1,12 @@ +from pyrecest._backend import BACKEND_NAME + +if BACKEND_NAME == "autograd": + from autograd import numpy, scipy + + from ..autograd import _common + +else: + import numpy + import scipy + + from ..numpy import _common diff --git a/pyrecest/_backend/_shared_numpy/linalg.py b/pyrecest/_backend/_shared_numpy/linalg.py new file mode 100644 index 00000000..6e1284c7 --- /dev/null +++ b/pyrecest/_backend/_shared_numpy/linalg.py @@ -0,0 +1,105 @@ +from ._dispatch import _common +from ._dispatch import numpy as _np +from ._dispatch import scipy as _scipy + +_to_ndarray = _common.to_ndarray +_cast_fout_to_input_dtype = _common._cast_fout_to_input_dtype +_cast_out_to_input_dtype = _common._cast_out_to_input_dtype +atol = _common.atol + + +def _is_symmetric(x, tol=atol): + new_x = _to_ndarray(x, to_ndim=3) + return (_np.abs(new_x - _np.transpose(new_x, axes=(0, 2, 1))) < tol).all() + + +def _is_hermitian(x, tol=atol): + new_x = _to_ndarray(x, to_ndim=3) + return (_np.abs(new_x - _np.conj(_np.transpose(new_x, axes=(0, 2, 1)))) < tol).all() + + +_diag_vec = _np.vectorize(_np.diag, signature="(n)->(n,n)") + +_logm_vec = _cast_fout_to_input_dtype( + target=_np.vectorize(_scipy.linalg.logm, signature="(n,m)->(n,m)") +) + + +def logm(x): + ndim = x.ndim + new_x = _to_ndarray(x, to_ndim=3) + + if _is_symmetric(new_x) and new_x.dtype not in [_np.complex64, _np.complex128]: + eigvals, eigvecs = _np.linalg.eigh(new_x) + if (eigvals > 0).all(): + eigvals = _np.log(eigvals) + eigvals = _diag_vec(eigvals) + transp_eigvecs = _np.transpose(eigvecs, axes=(0, 2, 1)) + result = _np.matmul(eigvecs, eigvals) + result = _np.matmul(result, transp_eigvecs) + else: + result = _logm_vec(new_x) + else: + result = _logm_vec(new_x) + + if ndim == 2: + return result[0] + return result + + +def solve_sylvester(a, b, q, tol=atol): + if a.shape == b.shape: + axes = (0, 2, 1) if a.ndim == 3 else (1, 0) + if _np.all(_np.isclose(a, b)) and _np.all( + _np.abs(a - _np.transpose(a, axes)) < tol + ): + eigvals, eigvecs = _np.linalg.eigh(a) + if _np.all(eigvals >= tol): + tilde_q = _np.transpose(eigvecs, axes) @ q @ eigvecs + tilde_x = tilde_q / (eigvals[..., :, None] + eigvals[..., None, :]) + return eigvecs @ tilde_x @ _np.transpose(eigvecs, axes) + + return _np.vectorize( + _scipy.linalg.solve_sylvester, signature="(m,m),(n,n),(m,n)->(m,n)" + )(a, b, q) + + +@_cast_fout_to_input_dtype +def sqrtm(x): + return _np.vectorize(_scipy.linalg.sqrtm, signature="(n,m)->(n,m)")(x) + + +def quadratic_assignment(a, b, options): + return list(_scipy.optimize.quadratic_assignment(a, b, options=options).col_ind) + + +def qr(*args, **kwargs): + return _np.vectorize( + _np.linalg.qr, signature="(n,m)->(n,k),(k,m)", excluded=["mode"] + )(*args, **kwargs) + + +def is_single_matrix_pd(mat): + """Check if 2D square matrix is positive definite.""" + if mat.shape[0] != mat.shape[1]: + return False + if mat.dtype in [_np.complex64, _np.complex128]: + if not _is_hermitian(mat): + return False + eigvals = _np.linalg.eigvalsh(mat) + return _np.min(_np.real(eigvals)) > 0 + try: + _np.linalg.cholesky(mat) + return True + except _np.linalg.LinAlgError as e: + if e.args[0] == "Matrix is not positive definite": + return False + raise e + + +@_cast_out_to_input_dtype +def fractional_matrix_power(A, t): + if A.ndim == 2: + return _scipy.linalg.fractional_matrix_power(A, t) + + return _np.stack([_scipy.linalg.fractional_matrix_power(A_, t) for A_ in A]) diff --git a/pyrecest/_backend/_shared_numpy/random.py b/pyrecest/_backend/_shared_numpy/random.py new file mode 100644 index 00000000..00ec08f6 --- /dev/null +++ b/pyrecest/_backend/_shared_numpy/random.py @@ -0,0 +1,29 @@ +from ._dispatch import _common +from ._dispatch import numpy as _np + +_modify_func_default_dtype = _common._modify_func_default_dtype +_allow_complex_dtype = _common._allow_complex_dtype + + +rand = _modify_func_default_dtype( + copy=False, kw_only=True, target=_allow_complex_dtype(target=_np.random.rand) +) + +uniform = _modify_func_default_dtype( + copy=False, kw_only=True, target=_allow_complex_dtype(target=_np.random.uniform) +) + + +normal = _modify_func_default_dtype( + copy=False, kw_only=True, target=_allow_complex_dtype(target=_np.random.normal) +) + +multivariate_normal = _modify_func_default_dtype( + copy=False, + kw_only=True, + target=_allow_complex_dtype(target=_np.random.multivariate_normal), +) + + +def choice(*args, **kwargs): + return _np.random.default_rng().choice(*args, **kwargs) diff --git a/pyrecest/_backend/autograd/__init__.py b/pyrecest/_backend/autograd/__init__.py new file mode 100644 index 00000000..9023cf3b --- /dev/null +++ b/pyrecest/_backend/autograd/__init__.py @@ -0,0 +1,175 @@ +"""Autograd based computation backend.""" + +import autograd.numpy as _np +from autograd.numpy import ( + all, + allclose, + amax, + amin, + any, + argmax, + argmin, + broadcast_arrays, + broadcast_to, + clip, + complex64, + complex128, + concatenate, + conj, + cross, + cumprod, + cumsum, + diag_indices, + diagonal, + einsum, + empty_like, + equal, + expand_dims, + flip, + float32, + float64, + greater, + hsplit, + hstack, + int32, + int64, + isclose, + isnan, + kron, + less, + less_equal, + logical_and, + logical_or, + maximum, + mean, + meshgrid, + minimum, + moveaxis, + ones_like, + pad, + prod, + quantile, + repeat, + reshape, + searchsorted, + shape, + sort, + split, + stack, + std, + sum, + take, + tile, + transpose, + trapz, + tril, + tril_indices, + triu, + triu_indices, + uint8, + unique, + vstack, + where, + zeros_like, +) +from autograd.scipy.special import erf, gamma, polygamma # NOQA + +from .._shared_numpy import ( + abs, + angle, + arange, + arccos, + arccosh, + arcsin, + arctan2, + arctanh, + array_from_sparse, + assignment, + assignment_by_sum, + ceil, + cos, + cosh, + divide, + dot, + exp, + flatten, + floor, + from_numpy, + get_slice, + log, + mat_from_diag_triu_tril, + matmul, + matvec, + mod, + ndim, + one_hot, + power, + ravel_tril_indices, + real, + scatter_add, + set_diag, + sign, + sin, + sinh, + sqrt, + squeeze, + tan, + tanh, + to_numpy, + trace, + tril_to_vec, + triu_to_vec, + vec_to_diag, + vectorize, +) +from . import autodiff # NOQA +from . import linalg # NOQA +from . import random # NOQA +from ._common import ( + _box_binary_scalar, + _box_unary_scalar, + _dyn_update_dtype, + array, + as_dtype, + atol, + cast, + convert_to_wider_dtype, + eye, + get_default_cdtype, + get_default_dtype, + is_array, + is_bool, + is_complex, + is_floating, + rtol, + set_default_dtype, + to_ndarray, + zeros, +) + +ones = _dyn_update_dtype(target=_np.ones) +linspace = _dyn_update_dtype(target=_np.linspace) +empty = _dyn_update_dtype(target=_np.empty) + + +def imag(x): + out = _np.imag(x) + if is_array(x): + return out + + return array(out) + + +def copy(x): + return _np.array(x, copy=True) + + +def outer(a, b): + if a.ndim == 2 and b.ndim == 2: + return _np.einsum("...i,...j->...ij", a, b) + + out = _np.outer(a, b).reshape(a.shape + b.shape) + if b.ndim == 2: + out = out.swapaxes(-3, -2) + + return out diff --git a/pyrecest/_backend/autograd/_common.py b/pyrecest/_backend/autograd/_common.py new file mode 100644 index 00000000..d09fae5c --- /dev/null +++ b/pyrecest/_backend/autograd/_common.py @@ -0,0 +1,36 @@ +import autograd.numpy as _np + +from pyrecest._backend._dtype_utils import ( + _dyn_update_dtype, + _modify_func_default_dtype, + get_default_cdtype, + get_default_dtype, +) + +from .._shared_numpy._common import ( + _add_default_dtype_by_casting, + _allow_complex_dtype, + _box_binary_scalar, + _box_unary_scalar, + _cast_fout_to_input_dtype, + _cast_out_from_dtype, + _cast_out_to_input_dtype, + _get_wider_dtype, + _is_boolean, + _is_iterable, + as_dtype, + atol, + cast, + convert_to_wider_dtype, + is_array, + is_bool, + is_complex, + is_floating, + rtol, + set_default_dtype, + to_ndarray, +) + +zeros = _dyn_update_dtype(target=_np.zeros) +eye = _dyn_update_dtype(target=_np.eye) +array = _cast_out_from_dtype(target=_np.array) diff --git a/pyrecest/_backend/autograd/_dtype.py b/pyrecest/_backend/autograd/_dtype.py new file mode 100644 index 00000000..e69de29b diff --git a/pyrecest/_backend/autograd/autodiff.py b/pyrecest/_backend/autograd/autodiff.py new file mode 100644 index 00000000..e8a08caf --- /dev/null +++ b/pyrecest/_backend/autograd/autodiff.py @@ -0,0 +1,301 @@ +"""Wrapper around autograd functions to be consistent with backends.""" + +import autograd as _autograd +import autograd.numpy as _np +from autograd import jacobian + + +def custom_gradient(*grad_funcs): + """Create a decorator that allows a function to define its custom gradient(s). + + Parameters + ---------- + *grad_funcs : callables + Custom gradient functions. + + Returns + ------- + decorator : callable + This decorator, used on any function func, associates the + input grad_funcs as the gradients of func. + """ + + def decorator(func): + """Decorate a function to define its custome gradient(s). + + Parameters + ---------- + func : callable + Function whose gradients will be assigned by grad_funcs. + + Returns + ------- + wrapped_function : callable + Function func with gradients specified by grad_funcs. + """ + wrapped_function = _autograd.extend.primitive(func) + + def wrapped_grad_func(i, ans, *args, **kwargs): + grads = grad_funcs[i](*args, **kwargs) + if isinstance(grads, float): + return lambda g: g * grads + if grads.ndim == 2: + return lambda g: g[..., None] * grads + if grads.ndim == 3: + return lambda g: g[..., None, None] * grads + return lambda g: g * grads + + if len(grad_funcs) == 1: + _autograd.extend.defvjp( + wrapped_function, + lambda ans, *args, **kwargs: wrapped_grad_func(0, ans, *args, **kwargs), + ) + elif len(grad_funcs) == 2: + _autograd.extend.defvjp( + wrapped_function, + lambda ans, *args, **kwargs: wrapped_grad_func(0, ans, *args, **kwargs), + lambda ans, *args, **kwargs: wrapped_grad_func(1, ans, *args, **kwargs), + ) + elif len(grad_funcs) == 3: + _autograd.extend.defvjp( + wrapped_function, + lambda ans, *args, **kwargs: wrapped_grad_func(0, ans, *args, **kwargs), + lambda ans, *args, **kwargs: wrapped_grad_func(1, ans, *args, **kwargs), + lambda ans, *args, **kwargs: wrapped_grad_func(2, ans, *args, **kwargs), + ) + else: + raise NotImplementedError( + "custom_gradient is not yet implemented " "for more than 3 gradients." + ) + + return wrapped_function + + return decorator + + +def _grad(func, argnums=0): + def _wrapped_grad(*x, **kwargs): + if not hasattr(x[0], "ndim") or x[0].ndim < 2: + return _autograd.grad(func, argnum=argnums)(*x, **kwargs) + + return _autograd.elementwise_grad(func, argnum=argnums)(*x, **kwargs) + + return _wrapped_grad + + +@_autograd.differential_operators.unary_to_nary +def _elementwise_value_and_grad(fun, x): + # same as autograd.elementwise_grad, but also returning ans + vjp, ans = _autograd.differential_operators._make_vjp(fun, x) + if _autograd.differential_operators.vspace(ans).iscomplex: + raise TypeError("Elementwise_grad only applies to real-output functions.") + + return ans, vjp(_autograd.differential_operators.vspace(ans).ones()) + + +def value_and_grad(func, argnums=0, to_numpy=False): + """Wrap autograd value_and_grad function. + + Parameters + ---------- + func : callable + Function whose value and gradient values + will be computed. + to_numpy : bool + Unused. Here for API consistency. + + Returns + ------- + value_and_grad : callable + Function that returns func's value and + func's gradients' values at its inputs args. + """ + + def _value_and_grad(*x, **kwargs): + if not hasattr(x[0], "ndim") or x[0].ndim < 2: + return _autograd.value_and_grad(func, argnum=argnums)(*x, **kwargs) + return _elementwise_value_and_grad(func, argnum=argnums)(*x, **kwargs) + + return _value_and_grad + + +@_autograd.differential_operators.unary_to_nary +def _value_and_jacobian_op(fun, x): + # same as autograd.jacobian, but also returning ans + vjp, ans = _autograd.differential_operators._make_vjp(fun, x) + ans_vspace = _autograd.differential_operators.vspace(ans) + jacobian_shape = ans_vspace.shape + _autograd.differential_operators.vspace(x).shape + grads = map(vjp, ans_vspace.standard_basis()) + return ans, _np.reshape(_np.stack(grads), jacobian_shape) + + +def _value_and_jacobian(fun, point_ndim=1): + def _value_and_jacobian_vec(x): + if x.ndim == point_ndim: + return _value_and_jacobian_op(fun)(x) + + ans = [] + jac = [] + for one_x in x: + ans_, jac_ = _value_and_jacobian_op(fun)(one_x) + ans.append(ans_) + jac.append(jac_) + + return _np.stack(ans), _np.stack(jac) + + return _value_and_jacobian_vec + + +def jacobian_vec(fun, point_ndim=1): + """Wrap autograd jacobian function. + + We note that the jacobian function of autograd is not vectorized + by default, thus we modify its behavior here. + + Default autograd behavior: + + If the jacobian for one point of shape (2,) is of shape (3, 2), + then calling the jacobian on 4 points with shape (4, 2) will + be of shape (3, 2, 4, 2). + + Modified behavior: + + Calling the jacobian on 4 points gives a tensor of shape (4, 3, 2). + + We use a for-loop to allow this function to be vectorized with + respect to several inputs in point, because the flag vectorize=True + fails. + + Parameters + ---------- + fun : callable + Function whose jacobian values + will be computed. + + Returns + ------- + func_with_jacobian : callable + Function that returns func's jacobian + values at its inputs args. + """ + + def _jac(x): + if x.ndim == point_ndim: + return jacobian(fun)(x) + return _np.stack([jacobian(fun)(one_x) for one_x in x]) + + return _jac + + +def hessian(fun, func_out_ndim=None): + """Wrap autograd hessian function. + + For consistency with the other backend, we convert this to a tensor + of shape (dim, dim). + + Parameters + ---------- + func : callable + Function whose hessian values + will be computed. + func_out_ndim : int + Unused. Here for API consistency. + + Returns + ------- + func_with_hessian : callable + Function that returns func's hessian + values at its inputs args. + """ + + def _hess(x): + return _autograd.hessian(fun)(x) + + return _hess + + +def hessian_vec(func, point_ndim=1, func_out_ndim=None): + """Wrap autograd hessian function. + + We note that the hessian function of autograd is not vectorized + by default, thus we modify its behavior here. + + We force the hessian to return a tensor of shape (n_points, dim, dim) + when several points are given as inputs. + + Parameters + ---------- + func : callable + Function whose hessian values + will be computed. + func_out_ndim : int + Unused. Here for API consistency. + + Returns + ------- + func_with_hessian : callable + Function that returns func's hessian + values at its inputs args. + """ + hessian_func = hessian(func) + + def _hess(x): + if x.ndim == point_ndim: + return hessian_func(x) + return _np.stack([hessian_func(one_x) for one_x in x]) + + return _hess + + +def jacobian_and_hessian(func, func_out_ndim=None): + """Wrap autograd jacobian and hessian functions. + + Parameters + ---------- + func : callable + Function whose jacobian and hessian values + will be computed. + func_out_ndim : int + Unused. Here for API consistency. + + Returns + ------- + func_with_jacobian_and_hessian : callable + Function that returns func's jacobian and + func's hessian values at its inputs args. + """ + return _value_and_jacobian(jacobian_vec(func)) + + +def value_jacobian_and_hessian(func, func_out_ndim=None): + """Compute value, jacobian and hessian. + + func is only called once. + + Parameters + ---------- + func : callable + Function whose jacobian and hessian values + will be computed. + func_out_ndim : int + Unused. Here for API consistency. + """ + cache = [] + + def _cached_value_and_jacobian(fun, return_cached=False): + def _jac(x): + ans, jac = _value_and_jacobian(fun)(x) + if not return_cached: + cache.append(ans) + return jac + + value = _np.stack(cache)._value if len(cache) > 1 else cache[0]._value + cache.clear() + + return value, ans, jac + + return _jac + + return _cached_value_and_jacobian( + _cached_value_and_jacobian(func), return_cached=True + ) diff --git a/pyrecest/_backend/autograd/linalg.py b/pyrecest/_backend/autograd/linalg.py new file mode 100644 index 00000000..4872864b --- /dev/null +++ b/pyrecest/_backend/autograd/linalg.py @@ -0,0 +1,50 @@ +"""Autograd based linear algebra backend.""" + +import functools as _functools + +import autograd.numpy as _np +from autograd.extend import defvjp as _defvjp +from autograd.extend import primitive as _primitive +from autograd.numpy.linalg import ( + cholesky, + det, + eig, + eigh, + eigvalsh, + inv, + matrix_rank, + norm, + solve, + svd, +) +from autograd.scipy.linalg import expm + +from .._shared_numpy.linalg import fractional_matrix_power, is_single_matrix_pd +from .._shared_numpy.linalg import logm as _logm +from .._shared_numpy.linalg import qr, quadratic_assignment, solve_sylvester, sqrtm + + +def _adjoint(_ans, x, fn): + vectorized = x.ndim == 3 + axes = (0, 2, 1) if vectorized else (1, 0) + + def vjp(g): + n = x.shape[-1] + size_m = x.shape[:-2] + (2 * n, 2 * n) + mat = _np.zeros(size_m) + mat[..., :n, :n] = x.transpose(axes) + mat[..., n:, n:] = x.transpose(axes) + mat[..., :n, n:] = g + return fn(mat)[..., :n, n:] + + return vjp + + +_expm_vjp = _functools.partial(_adjoint, fn=expm) +_defvjp(expm, _expm_vjp) + + +logm = _primitive(_logm) + +_logm_vjp = _functools.partial(_adjoint, fn=logm) +_defvjp(logm, _logm_vjp) diff --git a/pyrecest/_backend/autograd/random.py b/pyrecest/_backend/autograd/random.py new file mode 100644 index 00000000..f1f97d90 --- /dev/null +++ b/pyrecest/_backend/autograd/random.py @@ -0,0 +1,5 @@ +"""Autograd based random backend.""" +import autograd.numpy as _np +from autograd.numpy.random import randint, seed + +from .._shared_numpy.random import choice, multivariate_normal, normal, rand, uniform diff --git a/pyrecest/_backend/numpy/__init__.py b/pyrecest/_backend/numpy/__init__.py new file mode 100644 index 00000000..ecffcab1 --- /dev/null +++ b/pyrecest/_backend/numpy/__init__.py @@ -0,0 +1,156 @@ +"""Numpy based computation backend.""" + +import numpy as _np +from numpy import ( + all, + allclose, + amax, + amin, + any, + argmax, + argmin, + broadcast_arrays, + broadcast_to, + clip, + complex64, + complex128, + concatenate, + conj, + cross, + cumprod, + cumsum, + diag_indices, + diagonal, + einsum, + empty_like, + equal, + expand_dims, + flip, + float32, + float64, + greater, + hsplit, + hstack, + int32, + int64, + isclose, + isnan, + kron, + less, + less_equal, + logical_and, + logical_or, + maximum, + mean, + meshgrid, + minimum, + moveaxis, + ones_like, + pad, + prod, + quantile, + repeat, + reshape, + searchsorted, + shape, + sort, + split, + stack, + std, + sum, + take, + tile, + transpose, + trapz, + tril, + tril_indices, + triu, + triu_indices, + uint8, + unique, + vstack, + where, + zeros_like, +) +from scipy.special import erf, gamma, polygamma # NOQA + +from .._shared_numpy import ( + abs, + angle, + arange, + arccos, + arccosh, + arcsin, + arctan2, + arctanh, + array_from_sparse, + assignment, + assignment_by_sum, + ceil, + copy, + cos, + cosh, + divide, + dot, + exp, + flatten, + floor, + from_numpy, + get_slice, + imag, + log, + mat_from_diag_triu_tril, + matmul, + matvec, + mod, + ndim, + one_hot, + outer, + power, + ravel_tril_indices, + real, + scatter_add, + set_diag, + sign, + sin, + sinh, + sqrt, + squeeze, + tan, + tanh, + to_numpy, + trace, + tril_to_vec, + triu_to_vec, + vec_to_diag, + vectorize, +) +from . import autodiff # NOQA +from . import linalg # NOQA +from . import random # NOQA +from ._common import ( + _box_binary_scalar, + _box_unary_scalar, + _dyn_update_dtype, + _modify_func_default_dtype, + array, + as_dtype, + atol, + cast, + convert_to_wider_dtype, + eye, + get_default_cdtype, + get_default_dtype, + is_array, + is_bool, + is_complex, + is_floating, + rtol, + set_default_dtype, + to_ndarray, + zeros, +) + +ones = _modify_func_default_dtype(target=_np.ones) +linspace = _dyn_update_dtype(target=_np.linspace, dtype_pos=5) +empty = _dyn_update_dtype(target=_np.empty, dtype_pos=1) diff --git a/pyrecest/_backend/numpy/_common.py b/pyrecest/_backend/numpy/_common.py new file mode 100644 index 00000000..857af64e --- /dev/null +++ b/pyrecest/_backend/numpy/_common.py @@ -0,0 +1,36 @@ +import numpy as _np + +from pyrecest._backend._dtype_utils import ( + _dyn_update_dtype, + _modify_func_default_dtype, + get_default_cdtype, + get_default_dtype, +) + +from .._shared_numpy._common import ( + _add_default_dtype_by_casting, + _allow_complex_dtype, + _box_binary_scalar, + _box_unary_scalar, + _cast_fout_to_input_dtype, + _cast_out_from_dtype, + _cast_out_to_input_dtype, + _get_wider_dtype, + _is_boolean, + _is_iterable, + as_dtype, + atol, + cast, + convert_to_wider_dtype, + is_array, + is_bool, + is_complex, + is_floating, + rtol, + set_default_dtype, + to_ndarray, +) + +array = _cast_out_from_dtype(target=_np.array, dtype_pos=1) +eye = _modify_func_default_dtype(target=_np.eye) +zeros = _dyn_update_dtype(target=_np.zeros, dtype_pos=1) diff --git a/pyrecest/_backend/numpy/_dtype.py b/pyrecest/_backend/numpy/_dtype.py new file mode 100644 index 00000000..e69de29b diff --git a/pyrecest/_backend/numpy/autodiff.py b/pyrecest/_backend/numpy/autodiff.py new file mode 100644 index 00000000..761f47ac --- /dev/null +++ b/pyrecest/_backend/numpy/autodiff.py @@ -0,0 +1,61 @@ +"""Placeholders with error messages. + +NumPy backend does not offer automatic differentiation. +The following functions return error messages. +""" + +class AutodiffNotImplementedError(RuntimeError): + """Raised when autodiff is not implemented.""" + +_USE_OTHER_BACKEND_MSG = ( + "Automatic differentiation is not supported with numpy backend. " + "Use autograd or pytorch backend instead.\n" + "Change backend via the command " + "export PYRECEST_BACKEND=autograd in a terminal." +) + + +def value_and_grad(*args, **kwargs): + """Return an error when using automatic differentiation with numpy.""" + raise AutodiffNotImplementedError(_USE_OTHER_BACKEND_MSG) + + +def jacobian(*args, **kwargs): + """Return an error when using automatic differentiation with numpy.""" + raise AutodiffNotImplementedError(_USE_OTHER_BACKEND_MSG) + + +def jacobian_vec(*args, **kwargs): + """Return an error when using automatic differentiation with numpy.""" + raise AutodiffNotImplementedError(_USE_OTHER_BACKEND_MSG) + + +def hessian(*args, **kwargs): + """Return an error when using automatic differentiation with numpy.""" + raise AutodiffNotImplementedError(_USE_OTHER_BACKEND_MSG) + + +def hessian_vec(*args, **kwargs): + """Return an error when using automatic differentiation with numpy.""" + raise AutodiffNotImplementedError(_USE_OTHER_BACKEND_MSG) + + +def jacobian_and_hessian(*args, **kwargs): + """Return an error when using automatic differentiation with numpy.""" + raise AutodiffNotImplementedError(_USE_OTHER_BACKEND_MSG) + + +def custom_gradient(*grad_funcs): + """Decorate a function to define its custom gradient(s). + + This is a placeholder in order to have consistent backend APIs. + """ + + def decorator(func): + return func + + return decorator + + +def value_jacobian_and_hessian(*args, **kwargs): + raise AutodiffNotImplementedError(_USE_OTHER_BACKEND_MSG) diff --git a/pyrecest/_backend/numpy/linalg.py b/pyrecest/_backend/numpy/linalg.py new file mode 100644 index 00000000..30305ee8 --- /dev/null +++ b/pyrecest/_backend/numpy/linalg.py @@ -0,0 +1,27 @@ +"""Numpy based linear algebra backend.""" + +import numpy as _np +import scipy as _scipy +from numpy.linalg import ( # NOQA + cholesky, + det, + eig, + eigh, + eigvalsh, + inv, + matrix_rank, + norm, + solve, + svd, +) +from scipy.linalg import expm + +from .._shared_numpy.linalg import ( + fractional_matrix_power, + is_single_matrix_pd, + logm, + qr, + quadratic_assignment, + solve_sylvester, + sqrtm, +) diff --git a/pyrecest/_backend/numpy/random.py b/pyrecest/_backend/numpy/random.py new file mode 100644 index 00000000..0ddb064a --- /dev/null +++ b/pyrecest/_backend/numpy/random.py @@ -0,0 +1,7 @@ +"""Numpy based random backend.""" + +import numpy as _np +from numpy.random import default_rng as _default_rng +from numpy.random import randint, seed + +from .._shared_numpy.random import choice, multivariate_normal, normal, rand, uniform diff --git a/pyrecest/_backend/pytorch/__init__.py b/pyrecest/_backend/pytorch/__init__.py new file mode 100644 index 00000000..54a9b249 --- /dev/null +++ b/pyrecest/_backend/pytorch/__init__.py @@ -0,0 +1,804 @@ +"""Pytorch based computation backend.""" + +from collections.abc import Iterable as _Iterable + +import numpy as _np +import torch as _torch +from torch import arange, argmin +from torch import broadcast_tensors as broadcast_arrays +from torch import ( + clip, + complex64, + complex128, + conj, + empty, + empty_like, + erf, + eye, + flatten, + float32, + float64, + greater, + hstack, + int32, + int64, + isnan, + kron, + less, + logical_or, + mean, + meshgrid, + moveaxis, + ones, + ones_like, + polygamma, + quantile, +) +from torch import repeat_interleave as repeat +from torch import ( + reshape, + scatter_add, + stack, + trapz, + uint8, + unique, + vstack, + zeros, + zeros_like, +) +from torch.special import gammaln as _gammaln + +from .._backend_config import pytorch_atol as atol +from .._backend_config import pytorch_rtol as rtol +from . import autodiff # NOQA +from . import linalg # NOQA +from . import random # NOQA +from ._common import array, cast, from_numpy +from ._dtype import ( + _add_default_dtype_by_casting, + _box_binary_scalar, + _box_unary_scalar, + _preserve_input_dtype, + as_dtype, + get_default_cdtype, + get_default_dtype, + is_bool, + is_complex, + is_floating, + set_default_dtype, +) + +_DTYPES = { + int32: 0, + int64: 1, + float32: 2, + float64: 3, + complex64: 4, + complex128: 5, +} + + +def _raise_not_implemented_error(*args, **kwargs): + raise NotImplementedError + + +searchsorted = _raise_not_implemented_error + + +abs = _box_unary_scalar(target=_torch.abs) +angle = _box_unary_scalar(target=_torch.angle) +arccos = _box_unary_scalar(target=_torch.arccos) +arccosh = _box_unary_scalar(target=_torch.arccosh) +arcsin = _box_unary_scalar(target=_torch.arcsin) +arctanh = _box_unary_scalar(target=_torch.arctanh) +ceil = _box_unary_scalar(target=_torch.ceil) +cos = _box_unary_scalar(target=_torch.cos) +cosh = _box_unary_scalar(target=_torch.cosh) +exp = _box_unary_scalar(target=_torch.exp) +floor = _box_unary_scalar(target=_torch.floor) +log = _box_unary_scalar(target=_torch.log) +real = _box_unary_scalar(target=_torch.real) +sign = _box_unary_scalar(target=_torch.sign) +sin = _box_unary_scalar(target=_torch.sin) +sinh = _box_unary_scalar(target=_torch.sinh) +sqrt = _box_unary_scalar(target=_torch.sqrt) +tan = _box_unary_scalar(target=_torch.tan) +tanh = _box_unary_scalar(target=_torch.tanh) + + +arctan2 = _box_binary_scalar(target=_torch.atan2) +mod = _box_binary_scalar(target=_torch.fmod, box_x2=False) +power = _box_binary_scalar(target=_torch.pow, box_x2=False) + + +std = _preserve_input_dtype(_add_default_dtype_by_casting(target=_torch.std)) + + +def matmul(x, y, out=None): + for array_ in [x, y]: + if array_.ndim == 1: + raise ValueError("ndims must be >=2") + + x, y = convert_to_wider_dtype([x, y]) + return _torch.matmul(x, y, out=out) + + +def to_numpy(x): + return x.numpy() + + +def one_hot(labels, num_classes): + if not _torch.is_tensor(labels): + labels = _torch.LongTensor(labels) + return _torch.nn.functional.one_hot(labels, num_classes).type(_torch.uint8) + + +def argmax(a, **kwargs): + if a.dtype == _torch.bool: + return _torch.as_tensor(_np.argmax(a.data.numpy(), **kwargs)) + return _torch.argmax(a, **kwargs) + + +def convert_to_wider_dtype(tensor_list): + dtype_list = [_DTYPES.get(x.dtype, -1) for x in tensor_list] + if len(set(dtype_list)) == 1: + return tensor_list + + wider_dtype_index = max(dtype_list) + + wider_dtype = list(_DTYPES.keys())[wider_dtype_index] + + tensor_list = [cast(x, dtype=wider_dtype) for x in tensor_list] + return tensor_list + + +def less_equal(x, y, **kwargs): + if not _torch.is_tensor(x): + x = _torch.tensor(x) + if not _torch.is_tensor(y): + y = _torch.tensor(y) + return _torch.le(x, y, **kwargs) + + +def split(x, indices_or_sections, axis=0): + if isinstance(indices_or_sections, int): + indices_or_sections = x.shape[axis] // indices_or_sections + return _torch.split(x, indices_or_sections, dim=axis) + indices_or_sections = _np.array(indices_or_sections) + intervals_length = indices_or_sections[1:] - indices_or_sections[:-1] + last_interval_length = x.shape[axis] - indices_or_sections[-1] + if last_interval_length > 0: + intervals_length = _np.append(intervals_length, last_interval_length) + intervals_length = _np.insert(intervals_length, 0, indices_or_sections[0]) + return _torch.split(x, tuple(intervals_length), dim=axis) + + +def logical_and(x, y): + if _torch.is_tensor(x) or _torch.is_tensor(y): + return x * y + return x and y + + +def any(x, axis=None): + if not _torch.is_tensor(x): + x = _torch.tensor(x) + if axis is None: + return _torch.any(x) + if isinstance(axis, int): + return _torch.any(x.bool(), axis) + if len(axis) == 1: + return _torch.any(x, *axis) + axis = list(axis) + for i_axis, one_axis in enumerate(axis): + if one_axis < 0: + axis[i_axis] = ndim(x) + one_axis + new_axis = tuple(k - 1 if k >= 0 else k for k in axis[1:]) + return any(_torch.any(x.bool(), axis[0]), new_axis) + + +def flip(x, axis): + if isinstance(axis, int): + axis = [axis] + if axis is None: + axis = list(range(x.ndim)) + return _torch.flip(x, dims=axis) + + +def concatenate(seq, axis=0, out=None): + seq = convert_to_wider_dtype(seq) + return _torch.cat(seq, dim=axis, out=out) + + +def all(x, axis=None): + if not _torch.is_tensor(x): + x = _torch.tensor(x) + if axis is None: + return x.bool().all() + if isinstance(axis, int): + return _torch.all(x.bool(), axis) + if len(axis) == 1: + return _torch.all(x, *axis) + axis = list(axis) + for i_axis, one_axis in enumerate(axis): + if one_axis < 0: + axis[i_axis] = ndim(x) + one_axis + new_axis = tuple(k - 1 if k >= 0 else k for k in axis[1:]) + return all(_torch.all(x.bool(), axis[0]), new_axis) + + +def get_slice(x, indices): + """Return a slice of an array, following Numpy's style. + + Parameters + ---------- + x : array-like, shape=[dim] + Initial array. + indices : iterable(iterable(int)) + Indices which are kept along each axis, starting from 0. + + Returns + ------- + slice : array-like + Slice of x given by indices. + + Notes + ----- + This follows Numpy's convention: indices are grouped by axis. + + Examples + -------- + >>> a = torch.tensor(range(30)).reshape(3,10) + >>> get_slice(a, ((0, 2), (8, 9))) + tensor([8, 29]) + """ + return x[indices] + + +def allclose(a, b, atol=atol, rtol=rtol): + if not isinstance(a, _torch.Tensor): + a = _torch.tensor(a) + if not isinstance(b, _torch.Tensor): + b = _torch.tensor(b) + a = to_ndarray(a.float(), to_ndim=1) + b = to_ndarray(b.float(), to_ndim=1) + n_a = a.shape[0] + n_b = b.shape[0] + nb_dim = a.dim() + if n_a > n_b: + reps = (int(n_a / n_b),) + (nb_dim - 1) * (1,) + b = tile(b, reps) + elif n_a < n_b: + reps = (int(n_b / n_a),) + (nb_dim - 1) * (1,) + a = tile(a, reps) + return _torch.allclose(a, b, atol=atol, rtol=rtol) + + +def shape(val): + if not is_array(val): + val = array(val) + return val.shape + + +def amax(a, axis=None): + if axis is None: + return _torch.max(array(a)) + return _torch.max(array(a), dim=axis).values + + +def maximum(a, b): + return _torch.max(array(a), array(b)) + + +def minimum(a, b): + return _torch.min(array(a), array(b)) + + +def to_ndarray(x, to_ndim, axis=0): + if not _torch.is_tensor(x): + x = array(x) + + if x.dim() == to_ndim - 1: + x = _torch.unsqueeze(x, dim=axis) + return x + + +def broadcast_to(x, shape): + if not _torch.is_tensor(x): + x = _torch.tensor(x) + return x.expand(shape) + + +def isclose(x, y, rtol=rtol, atol=atol): + if not _torch.is_tensor(x): + x = _torch.tensor(x) + if not _torch.is_tensor(y): + y = _torch.tensor(y) + return _torch.isclose(x, y, atol=atol, rtol=rtol) + + +def sum(x, axis=None, keepdims=None, dtype=None): + if axis is None: + if keepdims is None: + return _torch.sum(x, dtype=dtype) + return _torch.sum(x, keepdim=keepdims, dtype=dtype) + if keepdims is None: + return _torch.sum(x, dim=axis, dtype=dtype) + return _torch.sum(x, dim=axis, keepdim=keepdims, dtype=dtype) + + +def einsum(equation, *inputs): + input_tensors_list = [arg if is_array(arg) else array(arg) for arg in inputs] + input_tensors_list = convert_to_wider_dtype(input_tensors_list) + + return _torch.einsum(equation, *input_tensors_list) + + +def transpose(x, axes=None): + if axes: + return x.permute(axes) + if x.dim() == 1: + return x + if x.dim() > 2 and axes is None: + return x.permute(tuple(range(x.ndim)[::-1])) + return x.t() + + +def squeeze(x, axis=None): + if not is_array(x): + return x + if axis is None: + return _torch.squeeze(x) + return _torch.squeeze(x, dim=axis) + + +def trace(x): + if x.ndim == 2: + return _torch.trace(x) + + return _torch.einsum("...ii", x) + + +def linspace(start, stop, num=50, dtype=None): + start_is_array = _torch.is_tensor(start) + stop_is_array = _torch.is_tensor(stop) + + if not (start_is_array or stop_is_array): + return _torch.linspace(start=start, end=stop, steps=num, dtype=dtype) + + if not start_is_array: + start = _torch.tensor(start) + if not stop_is_array: + stop = _torch.tensor(stop) + start, stop = _torch.broadcast_tensors(start, stop) + result_shape = (num, *start.shape) + start = _torch.flatten(start) + stop = _torch.flatten(stop) + + return _torch.reshape( + _torch.vstack( + [ + _torch.linspace(start=start[i], end=stop[i], steps=num, dtype=dtype) + for i in range(start.shape[0]) + ] + ).T, + result_shape, + ) + + +def equal(a, b, **kwargs): + if not is_array(a): + a = array(a) + + if not is_array(b): + b = array(b) + return _torch.eq(a, b, **kwargs) + + +def diag_indices(*args, **kwargs): + return tuple(map(_torch.from_numpy, _np.diag_indices(*args, **kwargs))) + + +def tril(mat, k=0): + return _torch.tril(mat, diagonal=k) + + +def triu(mat, k=0): + return _torch.triu(mat, diagonal=k) + + +def tril_indices(n, k=0, m=None): + if m is None: + m = n + return _torch.tril_indices(row=n, col=m, offset=k) + + +def triu_indices(n, k=0, m=None): + if m is None: + m = n + return _torch.triu_indices(row=n, col=m, offset=k) + + +def tile(x, y): + if not _torch.is_tensor(x): + x = _torch.tensor(x) + return x.repeat(y) + + +def expand_dims(x, axis=0): + return _torch.unsqueeze(x, dim=axis) + + +def ndim(x): + return x.dim() + + +def hsplit(x, indices_or_section): + if isinstance(indices_or_section, int): + indices_or_section = x.shape[-1] // indices_or_section + return _torch.split(x, indices_or_section, dim=-1) + + +def diagonal(x, offset=0, axis1=0, axis2=1): + return _torch.diagonal(x, offset=offset, dim1=axis1, dim2=axis2) + + +def set_diag(x, new_diag): + """Set the diagonal along the last two axis. + + Parameters + ---------- + x : array-like, shape=[dim] + Initial array. + new_diag : array-like, shape=[dim[-2]] + Values to set on the diagonal. + + Returns + ------- + None + + Notes + ----- + This mimics tensorflow.linalg.set_diag(x, new_diag), when new_diag is a + 1-D array, but modifies x instead of creating a copy. + """ + arr_shape = x.shape + off_diag = (1 - _torch.eye(arr_shape[-1])) * x + diag = _torch.einsum("ij,...i->...ij", _torch.eye(new_diag.shape[-1]), new_diag) + return diag + off_diag + + +def prod(x, axis=None): + if axis is None: + axis = 0 + return _torch.prod(x, axis) + + +def where(condition, x=None, y=None): + if not _torch.is_tensor(condition): + condition = array(condition) + + if x is None and y is None: + return _torch.where(condition) + if not _torch.is_tensor(x): + x = _torch.tensor(x) + if not _torch.is_tensor(y): + y = _torch.tensor(y) + y = cast(y, x.dtype) + return _torch.where(condition, x, y) + + +def _is_boolean(x): + if isinstance(x, bool): + return True + if isinstance(x, (tuple, list)): + return _is_boolean(x[0]) + if _torch.is_tensor(x): + return x.dtype in [_torch.bool, _torch.uint8] + return False + + +def _is_iterable(x): + if isinstance(x, (list, tuple)): + return True + if _torch.is_tensor(x): + return ndim(x) > 0 + return False + + +def assignment(x, values, indices, axis=0): + """Assign values at given indices of an array. + + Parameters + ---------- + x: array-like, shape=[dim] + Initial array. + values: {float, list(float)} + Value or list of values to be assigned. + indices: {int, tuple, list(int), list(tuple)} + Single int or tuple, or list of ints or tuples of indices where value + is assigned. + If the length of the tuples is shorter than ndim(x), values are + assigned to each copy along axis. + axis: int, optional + Axis along which values are assigned, if vectorized. + + Returns + ------- + x_new : array-like, shape=[dim] + Copy of x with the values assigned at the given indices. + + Notes + ----- + If a single value is provided, it is assigned at all the indices. + If a list is given, it must have the same length as indices. + """ + x_new = copy(x) + + use_vectorization = hasattr(indices, "__len__") and len(indices) < ndim(x) + if _is_boolean(indices): + x_new[indices] = values + return x_new + zip_indices = _is_iterable(indices) and _is_iterable(indices[0]) + len_indices = len(indices) if _is_iterable(indices) else 1 + if zip_indices: + indices = tuple(zip(*indices)) + if not use_vectorization: + if not zip_indices: + len_indices = len(indices) if _is_iterable(indices) else 1 + len_values = len(values) if _is_iterable(values) else 1 + if len_values > 1 and len_values != len_indices: + raise ValueError("Either one value or as many values as indices") + x_new[indices] = values + else: + indices = tuple(list(indices[:axis]) + [slice(None)] + list(indices[axis:])) + x_new[indices] = values + return x_new + + +def assignment_by_sum(x, values, indices, axis=0): + """Add values at given indices of an array. + + Parameters + ---------- + x: array-like, shape=[dim] + Initial array. + values: {float, list(float)} + Value or list of values to be assigned. + indices: {int, tuple, list(int), list(tuple)} + Single int or tuple, or list of ints or tuples of indices where value + is assigned. + If the length of the tuples is shorter than ndim(x), values are + assigned to each copy along axis. + axis: int, optional + Axis along which values are assigned, if vectorized. + + Returns + ------- + x_new : array-like, shape=[dim] + Copy of x with the values assigned at the given indices. + + Notes + ----- + If a single value is provided, it is assigned at all the indices. + If a list is given, it must have the same length as indices. + """ + x_new = copy(x) + values = array(values) + use_vectorization = hasattr(indices, "__len__") and len(indices) < ndim(x) + if _is_boolean(indices): + x_new[indices] += values + return x_new + zip_indices = _is_iterable(indices) and _is_iterable(indices[0]) + if zip_indices: + indices = list(zip(*indices)) + if not use_vectorization: + len_indices = len(indices) if _is_iterable(indices) else 1 + len_values = len(values) if _is_iterable(values) else 1 + if len_values > 1 and len_values != len_indices: + raise ValueError("Either one value or as many values as indices") + x_new[indices] += values + else: + indices = tuple(list(indices[:axis]) + [slice(None)] + list(indices[axis:])) + x_new[indices] += values + return x_new + + +def copy(x): + return x.clone() + + +def cumsum(x, axis=None, dtype=None): + if not _torch.is_tensor(x): + x = array(x, dtype=dtype) + if axis is None: + return x.flatten().cumsum(dim=0, dtype=dtype) + return _torch.cumsum(x, dim=axis, dtype=dtype) + + +def cumprod(x, axis=None, dtype=None): + if axis is None: + axis = 0 + return _torch.cumprod(x, axis, dtype=dtype) + + +def array_from_sparse(indices, data, target_shape): + """Create an array of given shape, with values at specific indices. + + The rest of the array will be filled with zeros. + + Parameters + ---------- + indices : iterable(tuple(int)) + Index of each element which will be assigned a specific value. + data : iterable(scalar) + Value associated at each index. + target_shape : tuple(int) + Shape of the output array. + + Returns + ------- + a : array, shape=target_shape + Array of zeros with specified values assigned to specified indices. + """ + return _torch.sparse.FloatTensor( + _torch.LongTensor(indices).t(), + array(data), + _torch.Size(target_shape), + ).to_dense() + + +def vectorize(x, pyfunc, multiple_args=False, **kwargs): + if multiple_args: + return stack(list(map(lambda y: pyfunc(*y), zip(*x)))) + return stack(list(map(pyfunc, x))) + + +def vec_to_diag(vec): + return _torch.diag_embed(vec, offset=0) + + +def tril_to_vec(x, k=0): + n = x.shape[-1] + rows, cols = tril_indices(n, k=k) + return x[..., rows, cols] + + +def triu_to_vec(x, k=0): + n = x.shape[-1] + rows, cols = triu_indices(n, k=k) + return x[..., rows, cols] + + +def mat_from_diag_triu_tril(diag, tri_upp, tri_low): + """Build matrix from given components. + + Forms a matrix from diagonal, strictly upper triangular and + strictly lower traingular parts. + + Parameters + ---------- + diag : array_like, shape=[..., n] + tri_upp : array_like, shape=[..., (n * (n - 1)) / 2] + tri_low : array_like, shape=[..., (n * (n - 1)) / 2] + + Returns + ------- + mat : array_like, shape=[..., n, n] + """ + diag, tri_upp, tri_low = convert_to_wider_dtype([diag, tri_upp, tri_low]) + + n = diag.shape[-1] + (i,) = diag_indices(n, ndim=1) + j, k = triu_indices(n, k=1) + mat = _torch.zeros((diag.shape + (n,)), dtype=diag.dtype) + mat[..., i, i] = diag + mat[..., j, k] = tri_upp + mat[..., k, j] = tri_low + return mat + + +def divide(a, b, ignore_div_zero=False): + if ignore_div_zero is False: + return _torch.divide(a, b) + quo = _torch.divide(a, b) + return _torch.nan_to_num(quo, nan=0.0, posinf=0.0, neginf=0.0) + + +def ravel_tril_indices(n, k=0, m=None): + if m is None: + size = (n, n) + else: + size = (n, m) + idxs = _np.tril_indices(n, k, m) + return _torch.from_numpy(_np.ravel_multi_index(idxs, size)) + + +def sort(a, axis=-1): + sorted_a, _ = _torch.sort(a, dim=axis) + return sorted_a + + +def amin(a, axis=-1): + (values, _) = _torch.min(a, dim=axis) + return values + + +def take(a, indices, axis=0): + if not _torch.is_tensor(indices): + indices = _torch.as_tensor(indices) + + return _torch.squeeze(_torch.index_select(a, axis, indices)) + + +def _unnest_iterable(ls): + out = [] + if isinstance(ls, _Iterable): + for inner_ls in ls: + out.extend(_unnest_iterable(inner_ls)) + else: + out.append(ls) + + return out + + +def pad(a, pad_width, constant_value=0.0): + return _torch.nn.functional.pad( + a, _unnest_iterable(reversed(pad_width)), value=constant_value + ) + + +def is_array(x): + return _torch.is_tensor(x) + + +def outer(a, b): + # TODO: improve for torch > 1.9 (dims=0 fails in 1.9) + return _torch.einsum("...i,...j->...ij", a, b) + + +def matvec(A, b): + A, b = convert_to_wider_dtype([A, b]) + + if A.ndim == 2 and b.ndim == 1: + return _torch.mv(A, b) + + if b.ndim == 1: # A.ndim > 2 + return _torch.matmul(A, b) + + if A.ndim == 2: # b.ndim > 1 + return _torch.matmul(A, b.T).T + + return _torch.einsum("...ij,...j->...i", A, b) + + +def dot(a, b): + a, b = convert_to_wider_dtype([a, b]) + + if a.ndim == 1 and b.ndim == 1: + return _torch.dot(a, b) + + if b.ndim == 1: + return _torch.tensordot(a, b, dims=1) + + if a.ndim == 1: + return _torch.tensordot(a, b.T, dims=1) + + return _torch.einsum("...i,...i->...", a, b) + + +def cross(a, b): + if a.ndim + b.ndim == 3 or a.ndim == b.ndim == 2 and a.shape[0] != b.shape[0]: + a, b = broadcast_arrays(a, b) + return _torch.cross(*convert_to_wider_dtype([a, b])) + + +def gamma(a): + return _torch.exp(_gammaln(a)) + + +def imag(a): + if not _torch.is_tensor(a): + a = _torch.tensor(a) + if is_complex(a): + return _torch.imag(a) + return _torch.zeros(a.shape, dtype=a.dtype) diff --git a/pyrecest/_backend/pytorch/_common.py b/pyrecest/_backend/pytorch/_common.py new file mode 100644 index 00000000..79c8268c --- /dev/null +++ b/pyrecest/_backend/pytorch/_common.py @@ -0,0 +1,33 @@ +import numpy as _np +import torch as _torch + + +def from_numpy(x): + return _torch.from_numpy(x) + + +def array(val, dtype=None): + if _torch.is_tensor(val): + if dtype is None or val.dtype == dtype: + return val.clone() + + return cast(val, dtype=dtype) + + if isinstance(val, _np.ndarray): + tensor = from_numpy(val) + if dtype is not None and tensor.dtype != dtype: + tensor = cast(tensor, dtype=dtype) + + return tensor + + if isinstance(val, (list, tuple)) and len(val): + tensors = [array(tensor, dtype=dtype) for tensor in val] + return _torch.stack(tensors) + + return _torch.tensor(val, dtype=dtype) + + +def cast(x, dtype): + if _torch.is_tensor(x): + return x.to(dtype=dtype) + return array(x, dtype=dtype) diff --git a/pyrecest/_backend/pytorch/_dtype.py b/pyrecest/_backend/pytorch/_dtype.py new file mode 100644 index 00000000..91a999a4 --- /dev/null +++ b/pyrecest/_backend/pytorch/_dtype.py @@ -0,0 +1,148 @@ +import functools + +import torch as _torch +from torch import complex64, complex128, float32, float64 + +from pyrecest._backend import _backend_config as _config +from pyrecest._backend._dtype_utils import ( + _MAP_FLOAT_TO_COMPLEX, + _modify_func_default_dtype, + _pre_add_default_dtype_by_casting, + _pre_allow_complex_dtype, + _pre_cast_out_to_input_dtype, + _update_default_dtypes, + get_default_cdtype, + get_default_dtype, +) + +from ._common import cast + +MAP_DTYPE = { + "float32": float32, + "float64": float64, + "complex64": complex64, + "complex128": complex128, +} + +_COMPLEX_DTYPES = (complex64, complex128) + + +def is_floating(x): + return x.dtype.is_floating_point + + +def is_complex(x): + return x.dtype.is_complex + + +def is_bool(x): + return x.dtype is _torch.bool + + +def as_dtype(value): + """Transform string representing dtype in dtype.""" + return MAP_DTYPE[value] + + +def _dtype_as_str(dtype): + return str(dtype).split(".")[-1] + + +def set_default_dtype(value): + """Set backend default dtype. + + Parameters + ---------- + value : str + Possible values are "float32" as "float64". + """ + _config.DEFAULT_DTYPE = as_dtype(value) + _config.DEFAULT_COMPLEX_DTYPE = as_dtype(_MAP_FLOAT_TO_COMPLEX.get(value)) + _torch.set_default_dtype(_config.DEFAULT_DTYPE) + + _update_default_dtypes() + + return _config.DEFAULT_DTYPE + + +_add_default_dtype_by_casting = _pre_add_default_dtype_by_casting(cast) +_cast_out_to_input_dtype = _pre_cast_out_to_input_dtype( + cast, is_floating, is_complex, as_dtype, _dtype_as_str +) +_allow_complex_dtype = _pre_allow_complex_dtype(cast, _COMPLEX_DTYPES) + + +def _preserve_input_dtype(target=None): + """Ensure input dtype is preserved. + + How it works? + ------------- + Only acts on input. Assumes dtype is kwarg and function accepts dtype. + Passes dtype as input dtype. + + Use together with `_add_default_dtype_by_casting`. + """ + + def _decorator(func): + @functools.wraps(func) + def _wrapped(x, *args, dtype=None, **kwargs): + if dtype is None: + dtype = x.dtype + + return func(x, *args, dtype=dtype, **kwargs) + + return _wrapped + + if target is None: + return _decorator + + return _decorator(target) + + +def _box_unary_scalar(target=None): + """Update dtype if input is float in unary operations. + + How it works? + ------------- + Promotes input to tensor if not the case. + """ + + def _decorator(func): + @functools.wraps(func) + def _wrapped(x, *args, **kwargs): + if not _torch.is_tensor(x): + x = _torch.tensor(x) + return func(x, *args, **kwargs) + + return _wrapped + + if target is None: + return _decorator + + return _decorator(target) + + +def _box_binary_scalar(target=None, box_x1=True, box_x2=True): + """Update dtype if input is float in binary operations. + + How it works? + ------------- + Promotes inputs to tensor if not the case. + """ + + def _decorator(func): + @functools.wraps(func) + def _wrapped(x1, x2, *args, **kwargs): + if box_x1 and not _torch.is_tensor(x1): + x1 = _torch.tensor(x1) + if box_x2 and not _torch.is_tensor(x2): + x2 = _torch.tensor(x2) + + return func(x1, x2, *args, **kwargs) + + return _wrapped + + if target is None: + return _decorator + + return _decorator(target) diff --git a/pyrecest/_backend/pytorch/autodiff.py b/pyrecest/_backend/pytorch/autodiff.py new file mode 100644 index 00000000..c111c8ad --- /dev/null +++ b/pyrecest/_backend/pytorch/autodiff.py @@ -0,0 +1,364 @@ +"""Automatic differentiation in PyTorch.""" + +import functools + +import numpy as _np +import torch as _torch +from torch.autograd.functional import hessian as _torch_hessian +from torch.autograd.functional import jacobian as _torch_jacobian + + +def custom_gradient(*grad_funcs): + """Create a decorator that allows a function to define its custom gradient(s). + + Parameters + ---------- + *grad_funcs : callables + Custom gradient functions. + + Returns + ------- + decorator : callable + This decorator, used on any function func, associates the + input grad_funcs as the gradients of func. + """ + + def decorator(func): + """Decorate a function to define its custome gradient(s). + + Parameters + ---------- + func : callable + Function whose gradients will be assigned by grad_funcs. + + Returns + ------- + wrapped_function : callable + Function func with gradients specified by grad_funcs. + """ + + class func_with_grad(_torch.autograd.Function): + """Wrapper class for a function with custom grad.""" + + @staticmethod + def forward(ctx, *args): + ctx.save_for_backward(*args) + return func(*args) + + @staticmethod + def backward(ctx, grad_output): + inputs = ctx.saved_tensors + + grads = () + for custom_grad in grad_funcs: + grads = (*grads, grad_output * custom_grad(*inputs)) + + if len(grads) == 1: + return grads[0] + return grads + + def wrapped_function(*args, **kwargs): + new_inputs = args + tuple(kwargs.values()) + return func_with_grad.apply(*new_inputs) + + return wrapped_function + + return decorator + + +def jacobian(func): + """Return a function that returns the jacobian of func. + + Parameters + ---------- + func : callable + Function whose jacobian is computed. + + Returns + ------- + _ : callable + Function taking point as input and returning + the jacobian of func at point. + """ + + def _jacobian(point): + return _torch_jacobian(func=lambda x: func(x), inputs=point) + + return _jacobian + + +def jacobian_vec(func, point_ndim=1): + """Return a function that returns the jacobian of func. + + We note that the jacobian function of torch is not vectorized + by default, thus we modify its behavior here. + + Default pytorch behavior: + + If the jacobian for one point of shape (2,) is of shape (3, 2), + then calling the jacobian on 4 points with shape (4, 2) will + be of shape (3, 2, 4, 2). + + Modified behavior: + + Calling the jacobian on 4 points gives a tensor of shape (4, 3, 2). + + We use a for-loop to allow this function to be vectorized with + respect to several inputs in point, because the flag vectorize=True + fails. + + Parameters + ---------- + func : callable + Function whose jacobian is computed. + + Returns + ------- + _ : callable + Function taking point as input and returning + the jacobian of func at point. + """ + + def _jacobian(point): + if point.ndim == point_ndim: + return _torch_jacobian(func=lambda x: func(x), inputs=point) + return _torch.stack( + [ + _torch_jacobian(func=lambda x: func(x), inputs=one_point) + for one_point in point + ], + axis=0, + ) + + return _jacobian + + +def hessian(func, func_out_ndim=0): + """Return a function that returns the hessian of func. + + Parameters + ---------- + func : callable + Function whose Hessian is computed. + func_out_ndim : dim + func output ndim. + + Returns + ------- + _ : callable + Function taking point as input and returning + the hessian of func at point. + """ + + def _hessian(point): + return _torch_hessian(func=lambda x: func(x), inputs=point, strict=True) + + def _hessian_vector_valued(point): + def scalar_func(point, a): + return func(point)[a] + + return _torch.stack( + [ + hessian(functools.partial(scalar_func, a=a))(point) + for a in range(func_out_ndim) + ] + ) + + if func_out_ndim: + return _hessian_vector_valued + + return _hessian + + +def hessian_vec(func, point_ndim=1, func_out_ndim=0): + """Return a function that returns the hessian of func. + + We modify the default behavior of the hessian function of torch + to return a tensor of shape (n_points, dim, dim) when several + points are given as inputs. + + Parameters + ---------- + func : callable + Function whose Hessian is computed. + func_out_ndim : dim + func output ndim. + + Returns + ------- + _ : callable + Function taking point as input and returning + the hessian of func at point. + """ + hessian_func = hessian(func, func_out_ndim=func_out_ndim) + + def _hessian(point): + if point.ndim == point_ndim: + return hessian_func(point) + return _torch.stack( + [hessian_func(one_point) for one_point in point], + axis=0, + ) + + return _hessian + + +def jacobian_and_hessian(func, func_out_ndim=0): + """Return a function that returns func's jacobian and hessian. + + Parameters + ---------- + func : callable + Function whose jacobian and hessian + will be computed. It must be real-valued. + func_out_ndim : dim + func output ndim. + + Returns + ------- + func_with_jacobian_and_hessian : callable + Function that returns func's jacobian and + func's hessian at its inputs args. + """ + + def _jacobian_and_hessian(*args, **kwargs): + """Return func's jacobian and func's hessian at args. + + Parameters + ---------- + args : list + Argument to function func and its gradients. + kwargs : dict + Keyword arguments to function func and its gradients. + + Returns + ------- + jacobian : any + Value of func's jacobian at input arguments args. + hessian : any + Value of func's hessian at input arguments args. + """ + return jacobian(func)(*args), hessian(func, func_out_ndim=func_out_ndim)(*args) + + return _jacobian_and_hessian + + +def value_and_grad(func, argnums=0, to_numpy=False): + """Return a function that returns func's value and gradients' values. + + Suitable for use in scipy.optimize with to_numpy=True. + + Parameters + ---------- + func : callable + Function whose value and gradient values + will be computed. It must be real-valued. + to_numpy : bool + Determines if the outputs value and grad will be cast + to numpy arrays. Set to "True" when using scipy.optimize. + Optional, default: False. + + Returns + ------- + func_with_grad : callable + Function that returns func's value and + func's gradients' values at its inputs args. + """ + if isinstance(argnums, int): + argnums = (argnums,) + + def func_with_grad(*args, **kwargs): + """Return func's value and func's gradients' values at args. + + Parameters + ---------- + args : list + Argument to function func and its gradients. + kwargs : dict + Keyword arguments to function func and its gradients. + + Returns + ------- + value : any + Value of func at input arguments args. + all_grads : list or any + Values of func's gradients at input arguments args. + """ + new_args = [] + for i_arg, one_arg in enumerate(args): + if isinstance(one_arg, float): + one_arg = _torch.from_numpy(_np.array(one_arg)) + if isinstance(one_arg, _np.ndarray): + one_arg = _torch.from_numpy(one_arg) + + requires_grad = i_arg in argnums + one_arg = one_arg.detach().requires_grad_(requires_grad) + new_args.append(one_arg) + + value = func(*new_args, **kwargs) + value = value.requires_grad_(True) + + if value.ndim > 0: + sum_value = value.sum() + sum_value.backward() + else: + value.backward() + + all_grads = [] + for i_arg, one_arg in enumerate(new_args): + if i_arg in argnums: + all_grads.append( + one_arg.grad, + ) + + if to_numpy: + value = value.detach().numpy() + all_grads = [one_grad.detach().numpy() for one_grad in all_grads] + + if len(new_args) == 1: + return value, all_grads[0] + return value, tuple(all_grads) + + return func_with_grad + + +def value_jacobian_and_hessian(func, func_out_ndim=0): + """Compute value, jacobian and hessian. + + func is called as many times as the output dim. + + Parameters + ---------- + func : callable + Function whose jacobian and hessian values + will be computed. + func_out_ndim : int + func output ndim. + """ + + def _value_jacobian_and_hessian(*args, **kwargs): + """Return func's jacobian and func's hessian at args. + + Parameters + ---------- + args : list + Argument to function func and its gradients. + kwargs : dict + Keyword arguments to function func and its gradients. + + Returns + ------- + value : array-like + Value of func at input arguments args. + jacobian : array-like + Value of func's jacobian at input arguments args. + hessian : array-like + Value of func's hessian at input arguments args. + """ + return ( + func(*args, **kwargs), + jacobian_vec(func)(*args, **kwargs), + hessian_vec(func, func_out_ndim=func_out_ndim)(*args, **kwargs), + ) + + return _value_jacobian_and_hessian diff --git a/pyrecest/_backend/pytorch/linalg.py b/pyrecest/_backend/pytorch/linalg.py new file mode 100644 index 00000000..41afe2ae --- /dev/null +++ b/pyrecest/_backend/pytorch/linalg.py @@ -0,0 +1,149 @@ +"""Pytorch based linear algebra backend.""" + +import numpy as _np +import scipy as _scipy +import torch as _torch + +from .._backend_config import np_atol as atol +from ..numpy import linalg as _gsnplinalg +from ._dtype import _cast_out_to_input_dtype + + +class _Logm(_torch.autograd.Function): + """Torch autograd function for matrix logarithm. + + Implementation based on: + https://github.com/pytorch/pytorch/issues/9983#issuecomment-891777620 + """ + + @staticmethod + def _logm(x): + np_logm = _gsnplinalg.logm(x.detach().cpu()) + torch_logm = _torch.from_numpy(np_logm).to(x.device, dtype=x.dtype) + return torch_logm + + @staticmethod + def forward(ctx, tensor): + """Apply matrix logarithm to a tensor.""" + ctx.save_for_backward(tensor) + return _Logm._logm(tensor) + + @staticmethod + def backward(ctx, grad): + """Run gradients backward.""" + (tensor,) = ctx.saved_tensors + + vectorized = tensor.ndim == 3 + axes = (0, 2, 1) if vectorized else (1, 0) + tensor_H = tensor.permute(axes).conj().to(grad.dtype) + n = tensor.size(-1) + bshape = tensor.shape[:-2] + (2 * n, 2 * n) + backward_tensor = _torch.zeros(*bshape, dtype=grad.dtype, device=grad.device) + backward_tensor[..., :n, :n] = tensor_H + backward_tensor[..., n:, n:] = tensor_H + backward_tensor[..., :n, n:] = grad + + return _Logm._logm(backward_tensor).to(tensor.dtype)[..., :n, n:] + + +cholesky = _torch.linalg.cholesky +eig = _torch.linalg.eig +eigh = _torch.linalg.eigh +eigvalsh = _torch.linalg.eigvalsh +expm = _torch.matrix_exp +inv = _torch.inverse +det = _torch.det +solve = _torch.linalg.solve +qr = _torch.linalg.qr +logm = _Logm.apply + + +def sqrtm(x): + np_sqrtm = _np.vectorize(_scipy.linalg.sqrtm, signature="(n,m)->(n,m)")(x) + if np_sqrtm.dtype.kind == "c": + np_sqrtm = np_sqrtm.astype(f"complex{int(np_sqrtm.dtype.name[7:]) // 2}") + + return _torch.from_numpy(np_sqrtm) + + +def svd(x, full_matrices=True, compute_uv=True): + if compute_uv: + return _torch.linalg.svd(x, full_matrices=full_matrices) + + return _torch.linalg.svdvals(x) + + +def norm(x, ord=None, axis=None): + if axis is None: + return _torch.linalg.norm(x, ord=ord) + return _torch.linalg.norm(x, ord=ord, dim=axis) + + +def matrix_rank(a, hermitian=False, **_unused_kwargs): + return _torch.linalg.matrix_rank(a, hermitian=hermitian) + + +def quadratic_assignment(a, b, options): + return list(_scipy.optimize.quadratic_assignment(a, b, options=options).col_ind) + + +def solve_sylvester(a, b, q): + if ( + a.shape == b.shape + and _torch.all(a == b) + and _torch.all(_torch.abs(a - a.transpose(-2, -1)) < 1e-6) + ): + eigvals, eigvecs = eigh(a) + if _torch.all(eigvals >= 1e-6): + tilde_q = eigvecs.transpose(-2, -1) @ q @ eigvecs + tilde_x = tilde_q / (eigvals[..., :, None] + eigvals[..., None, :]) + return eigvecs @ tilde_x @ eigvecs.transpose(-2, -1) + + conditions = _torch.all(eigvals >= 1e-6) or ( + a.shape[-1] >= 2.0 + and _torch.all(eigvals[..., 0] > -1e-6) + and _torch.all(eigvals[..., 1] >= 1e-6) + and _torch.all(_torch.abs(q + q.transpose(-2, -1)) < 1e-6) + ) + if conditions: + tilde_q = eigvecs.transpose(-2, -1) @ q @ eigvecs + tilde_x = tilde_q / ( + eigvals[..., :, None] + eigvals[..., None, :] + _torch.eye(a.shape[-1]) + ) + return eigvecs @ tilde_x @ eigvecs.transpose(-2, -1) + + solution = _np.vectorize( + _scipy.linalg.solve_sylvester, signature="(m,m),(n,n),(m,n)->(m,n)" + )(a, b, q) + return _torch.from_numpy(solution) + + +# (TODO) (sait) _torch.linalg.cholesky_ex for even faster way +def is_single_matrix_pd(mat): + """Check if 2D square matrix is positive definite.""" + if mat.shape[0] != mat.shape[1]: + return False + if mat.dtype in [_torch.complex64, _torch.complex128]: + is_hermitian = _torch.all( + _torch.abs(mat - _torch.conj(_torch.transpose(mat, 0, 1))) < atol + ) + if not is_hermitian: + return False + eigvals = _torch.linalg.eigvalsh(mat) + return _torch.min(_torch.real(eigvals)) > 0 + try: + _torch.linalg.cholesky(mat) + return True + except RuntimeError: + return False + + +@_cast_out_to_input_dtype +def fractional_matrix_power(A, t): + """Compute the fractional power of a matrix.""" + if A.ndim == 2: + out = _scipy.linalg.fractional_matrix_power(A, t) + else: + out = _np.stack([_scipy.linalg.fractional_matrix_power(A_, t) for A_ in A]) + + return _torch.tensor(out) diff --git a/pyrecest/_backend/pytorch/random.py b/pyrecest/_backend/pytorch/random.py new file mode 100644 index 00000000..17569156 --- /dev/null +++ b/pyrecest/_backend/pytorch/random.py @@ -0,0 +1,44 @@ +"""Torch based random backend.""" + +import torch as _torch +from torch import rand, randint +from torch.distributions.multivariate_normal import ( + MultivariateNormal as _MultivariateNormal, +) + +from ._dtype import _allow_complex_dtype, _modify_func_default_dtype + + +def choice(x, a): + """Generate a random sample from an array of given size.""" + if _torch.is_tensor(x): + return x[_torch.randint(len(x), (a,))] + + return x + + +def seed(*args, **kwargs): + return _torch.manual_seed(*args, **kwargs) + + +@_allow_complex_dtype +def normal(loc=0.0, scale=1.0, size=(1,)): + if not hasattr(size, "__iter__"): + size = (size,) + return _torch.normal(mean=loc, std=scale, size=size) + + +def uniform(low=0.0, high=1.0, size=(1,), dtype=None): + if not hasattr(size, "__iter__"): + size = (size,) + if low >= high: + raise ValueError("Upper bound must be higher than lower bound") + return (high - low) * rand(*size, dtype=dtype) + low + + +@_modify_func_default_dtype(copy=False, kw_only=True) +@_allow_complex_dtype +def multivariate_normal(mean, cov, size=(1,)): + if not hasattr(size, "__iter__"): + size = (size,) + return _MultivariateNormal(mean, cov).sample(size) diff --git a/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py b/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py index d6a60548..9319f48b 100644 --- a/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py +++ b/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py @@ -11,6 +11,7 @@ from ..abstract_manifold_specific_distribution import ( AbstractManifoldSpecificDistribution, ) +from pyrecest.backend import empty, ones class AbstractLinearDistribution(AbstractManifoldSpecificDistribution): @@ -148,19 +149,19 @@ def integrand3(x, y): def integrate(self, left=None, right=None): if left is None: - left = -np.inf * np.ones(self.dim) + left = -np.inf * ones(self.dim) if right is None: - right = np.inf * np.ones(self.dim) + right = np.inf * ones(self.dim) result = self.integrate_numerically(left, right) return result def integrate_numerically(self, left=None, right=None): if left is None: - left = np.empty(self.dim) + left = empty(self.dim) left.fill(-np.inf) if right is None: - right = np.empty(self.dim) + right = empty(self.dim) right.fill(np.inf) return AbstractLinearDistribution.integrate_fun_over_domain( self.pdf, self.dim, left, right @@ -217,7 +218,7 @@ def plot(self, *args, plot_range=None, **kwargs): if plot_range is None: scaling = np.sqrt(chi2.ppf(0.99, self.dim)) - plot_range = np.empty(2 * self.dim) + plot_range = empty(2 * self.dim) for i in range(0, 2 * self.dim, 2): plot_range[i] = mu[int(i / 2)] - scaling * np.sqrt( C[int(i / 2), int(i / 2)] diff --git a/pyrecest/distributions/nonperiodic/custom_linear_distribution.py b/pyrecest/distributions/nonperiodic/custom_linear_distribution.py index 5f1d9ff2..01cfa085 100644 --- a/pyrecest/distributions/nonperiodic/custom_linear_distribution.py +++ b/pyrecest/distributions/nonperiodic/custom_linear_distribution.py @@ -7,6 +7,7 @@ ) from .abstract_linear_distribution import AbstractLinearDistribution +from pyrecest.backend import zeros class CustomLinearDistribution( AbstractLinearDistribution, AbstractCustomNonPeriodicDistribution @@ -31,7 +32,7 @@ def __init__(self, f, dim, scale_by=1, shift_by=None): if shift_by is not None: self.shift_by = shift_by else: - self.shift_by = np.zeros(dim) + self.shift_by = zeros(dim) def shift(self, shift_by): assert self.dim == np.size(shift_by) and shift_by.ndim <= 1 From 0b7e23c9f9eaecc8e7d8474ef9a77ad7cabeb076 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 16 Oct 2023 19:30:11 +0100 Subject: [PATCH 002/232] Using and testing all backends --- .../workflows/{tests_numpy.yml => tests.yml} | 22 +- .github/workflows/tests_pytorch.yml | 53 --- .github/workflows/update-requirements.yml | 2 +- .jscpd.json | 6 + poetry.lock | 222 ++++++++- pyproject.toml | 2 + pyrecest/_backend/.pylintrc | 2 + pyrecest/_backend/_shared_numpy/__init__.py | 2 +- .../abstract_dirac_distribution.py | 28 +- .../abstract_disk_distribution.py | 4 +- .../abstract_ellipsoidal_ball_distribution.py | 3 +- ...abstract_manifold_specific_distribution.py | 16 +- pyrecest/distributions/abstract_mixture.py | 18 +- .../abstract_orthogonal_basis_distribution.py | 10 +- .../abstract_periodic_distribution.py | 4 +- .../abstract_se3_distribution.py | 11 +- .../abstract_uniform_distribution.py | 3 +- .../abstract_hypercylindrical_distribution.py | 56 ++- ...ract_lin_bounded_cart_prod_distribution.py | 4 +- .../cart_prod_stacked_distribution.py | 14 +- .../hypercylindrical_dirac_distribution.py | 16 +- ...in_bounded_cart_prod_dirac_distribution.py | 3 +- ...ypersphere_cart_prod_dirac_distribution.py | 3 +- ...n_hypersphere_subset_dirac_distribution.py | 4 +- .../partially_wrapped_normal_distribution.py | 59 ++- .../circle/abstract_circular_distribution.py | 15 +- .../circle/circular_dirac_distribution.py | 6 +- .../circle/circular_fourier_distribution.py | 59 ++- .../distributions/circle/circular_mixture.py | 6 +- .../circle/custom_circular_distribution.py | 6 +- .../circle/von_mises_distribution.py | 36 +- .../circle/wrapped_cauchy_distribution.py | 22 +- .../circle/wrapped_laplace_distribution.py | 15 +- .../circle/wrapped_normal_distribution.py | 54 ++- .../disk_uniform_distribution.py | 4 +- .../ellipsoidal_ball_uniform_distribution.py | 14 +- ...bstract_hyperhemispherical_distribution.py | 40 +- ...t_hypersphere_subset_dirac_distribution.py | 4 +- ...bstract_hypersphere_subset_distribution.py | 66 +-- ...hypersphere_subset_uniform_distribution.py | 3 +- .../abstract_hyperspherical_distribution.py | 51 ++- .../abstract_sphere_subset_distribution.py | 42 +- ...stract_spherical_harmonics_distribution.py | 29 +- .../bingham_distribution.py | 19 +- .../custom_hyperhemispherical_distribution.py | 4 +- ...hyperhemispherical_uniform_distribution.py | 4 +- .../hyperhemispherical_watson_distribution.py | 11 +- .../hyperspherical_dirac_distribution.py | 4 +- .../hyperspherical_uniform_distribution.py | 18 +- ...pherical_harmonics_distribution_complex.py | 65 +-- .../spherical_harmonics_distribution_real.py | 19 +- .../von_mises_fisher_distribution.py | 47 +- .../hypersphere_subset/watson_distribution.py | 28 +- .../abstract_hypertoroidal_distribution.py | 85 ++-- .../abstract_toroidal_distribution.py | 33 +- .../custom_hypertoroidal_distribution.py | 6 +- .../hypertoroidal_dirac_distribution.py | 26 +- .../hypertorus/hypertoroidal_mixture.py | 7 +- .../hypertoroidal_uniform_distribution.py | 29 +- ...pertoroidal_wrapped_normal_distribution.py | 33 +- .../hypertorus/toroidal_dirac_distribution.py | 28 +- .../toroidal_von_mises_sine_distribution.py | 22 +- .../toroidal_wrapped_normal_distribution.py | 9 +- .../abstract_hyperrectangular_distribution.py | 9 +- .../abstract_linear_distribution.py | 63 +-- .../nonperiodic/custom_linear_distribution.py | 6 +- .../nonperiodic/gaussian_distribution.py | 8 +- .../nonperiodic/gaussian_mixture.py | 19 +- .../nonperiodic/linear_dirac_distribution.py | 8 +- .../distributions/se3_dirac_distribution.py | 3 +- .../evaluation/determine_all_deviations.py | 14 +- pyrecest/evaluation/eot_shape_database.py | 35 +- pyrecest/evaluation/evaluate_for_file.py | 9 +- pyrecest/evaluation/generate_groundtruth.py | 12 +- pyrecest/evaluation/generate_measurements.py | 38 +- .../generate_simulated_scenarios.py | 5 +- pyrecest/evaluation/get_distance_function.py | 8 +- .../evaluation/iterate_configs_and_runs.py | 8 +- .../perform_predict_update_cycles.py | 11 +- pyrecest/evaluation/plot_results.py | 17 +- pyrecest/evaluation/simulation_database.py | 7 +- .../evaluation/summarize_filter_results.py | 21 +- .../abstract_nearest_neighbor_tracker.py | 13 +- pyrecest/filters/abstract_particle_filter.py | 17 +- .../filters/abstract_tracker_with_logging.py | 6 +- pyrecest/filters/circular_particle_filter.py | 10 +- pyrecest/filters/euclidean_particle_filter.py | 9 +- pyrecest/filters/global_nearest_neighbor.py | 26 +- .../filters/hypertoroidal_particle_filter.py | 29 +- pyrecest/filters/kalman_filter.py | 9 +- pyrecest/filters/random_matrix_tracker.py | 12 +- pyrecest/filters/toroidal_particle_filter.py | 4 +- .../filters/toroidal_wrapped_normal_filter.py | 4 +- pyrecest/filters/von_mises_filter.py | 3 +- pyrecest/filters/von_mises_fisher_filter.py | 6 +- pyrecest/filters/wrapped_normal_filter.py | 11 +- pyrecest/sampling/euclidean_sampler.py | 4 +- pyrecest/sampling/hyperspherical_sampler.py | 45 +- pyrecest/sampling/hypertoroidal_sampler.py | 3 +- .../test_abstract_circular_distribution.py | 15 +- ..._abstract_hypercylindrical_distribution.py | 52 ++- ...bstract_hyperhemispherical_distribution.py | 9 +- ...bstract_hypersphere_subset_distribution.py | 35 +- ...st_abstract_hyperspherical_distribution.py | 10 +- .../test_abstract_linear_distribution.py | 29 +- .../distributions/test_abstract_mixture.py | 19 +- .../test_bingham_distribution.py | 7 +- .../test_circular_fourier_distribution.py | 25 +- .../test_circular_uniform_distribution.py | 14 +- .../test_custom_hemispherical_distribution.py | 12 +- ...st_custom_hypercylindrical_distribution.py | 9 +- ...st_custom_hyperrectangular_distribution.py | 14 +- ...test_custom_hyperspherical_distribution.py | 7 +- .../test_custom_linear_distribution.py | 12 +- .../test_disk_uniform_distribution.py | 17 +- ...t_ellipsoidal_ball_uniform_distribution.py | 7 +- .../test_gaussian_distribution.py | 38 +- ...test_hemispherical_uniform_distribution.py | 7 +- ...est_hypercylindrical_dirac_distribution.py | 55 ++- ...hyperhemispherical_uniform_distribution.py | 14 +- .../test_hyperspherical_dirac_distribution.py | 21 +- .../test_hyperspherical_mixture.py | 24 +- ...est_hyperspherical_uniform_distribution.py | 5 +- .../test_hypertoroidal_dirac_distribution.py | 38 +- ...pertoroidal_wrapped_normal_distribution.py | 9 +- .../test_linear_dirac_distribution.py | 18 +- .../distributions/test_linear_mixture.py | 17 +- ...t_partially_wrapped_normal_distribution.py | 12 +- .../test_se3_dirac_distribution.py | 16 +- .../test_sphere_subset_distribution.py | 11 +- ...pherical_harmonics_distribution_complex.py | 427 +++++++++--------- ...t_spherical_harmonics_distribution_real.py | 65 +-- .../test_toroidal_uniform_distribution.py | 32 +- ...st_toroidal_von_mises_sine_distribution.py | 33 +- ...st_toroidal_wrapped_normal_distribution.py | 16 +- .../test_von_mises_distribution.py | 6 +- .../test_von_mises_fisher_distribution.py | 59 +-- .../distributions/test_watson_distribution.py | 13 +- .../test_wrapped_cauchy_distribution.py | 8 +- .../test_wrapped_laplace_distribution.py | 11 +- .../test_wrapped_normal_distribution.py | 30 +- .../filters/test_circular_particle_filter.py | 14 +- .../filters/test_euclidean_particle_filter.py | 23 +- .../filters/test_global_nearest_neighbor.py | 108 ++--- .../test_hypertoroidal_particle_filter.py | 12 +- pyrecest/tests/filters/test_kalman_filter.py | 40 +- .../filters/test_random_matrix_tracker.py | 45 +- .../filters/test_toroidal_particle_filter.py | 15 +- .../test_toroidal_wrapped_normal_filter.py | 8 +- .../filters/test_von_mises_fisher_filter.py | 15 +- pyrecest/tests/test_euclidean_sampler.py | 14 +- pyrecest/tests/test_evaluation_basic.py | 82 ++-- pyrecest/tests/test_hyperspherical_sampler.py | 7 +- pyrecest/tests/test_hypertoroidal_sampler.py | 12 +- pyrecest/tests/test_metrics.py | 12 +- pyrecest/utils/metrics.py | 6 +- pyrecest/utils/plotting.py | 30 +- requirements-dev.txt | 15 +- requirements.txt | 8 +- 159 files changed, 2335 insertions(+), 1457 deletions(-) rename .github/workflows/{tests_numpy.yml => tests.yml} (56%) delete mode 100644 .github/workflows/tests_pytorch.yml create mode 100644 .jscpd.json create mode 100644 pyrecest/_backend/.pylintrc diff --git a/.github/workflows/tests_numpy.yml b/.github/workflows/tests.yml similarity index 56% rename from .github/workflows/tests_numpy.yml rename to .github/workflows/tests.yml index 651ac8aa..b1e774c6 100644 --- a/.github/workflows/tests_numpy.yml +++ b/.github/workflows/tests.yml @@ -27,20 +27,32 @@ jobs: - name: Install dependencies run: | + export CUDA_VISIBLE_DEVICES="" python -m pip install --upgrade pip python -m pip install poetry - poetry install --extras healpy_support + poetry install --extras healpy_support --extras pytorch_support - name: List files and check Python and package versions run: | ls -al + pip3 install --upgrade --force-reinstall torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu python -c 'import sys; print(sys.version_info[:])' python -m pip freeze - - name: Run tests + - name: Run tests with numpy backend + run: | + #poetry env use python + #export PYRECEST_BACKEND=numpy + #poetry run python -m pytest --rootdir . -v --strict-config --junitxml=junit_test_results_numpy.xml ./pyrecest + env: + PYTHONPATH: ${{ github.workspace }} + + - name: Run tests with pytorch backend + if: always() run: | poetry env use python - poetry run python -m pytest --rootdir . -v --strict-config --junitxml=junit_test_results.xml ./pyrecest + export PYRECEST_BACKEND=pytorch + poetry run python -m pytest --rootdir . -v --strict-config --junitxml=junit_test_results_pytorch.xml ./pyrecest env: PYTHONPATH: ${{ github.workspace }} @@ -48,4 +60,6 @@ jobs: if: always() uses: EnricoMi/publish-unit-test-result-action@v2 with: - files: junit_test_results.xml + files: | + junit_test_results_numpy.xml + junit_test_results_pytorch.xml diff --git a/.github/workflows/tests_pytorch.yml b/.github/workflows/tests_pytorch.yml deleted file mode 100644 index 42def008..00000000 --- a/.github/workflows/tests_pytorch.yml +++ /dev/null @@ -1,53 +0,0 @@ ---- - name: Test workflow - - permissions: read-all - - on: # yamllint disable-line rule:truthy - push: - pull_request: - branches: - - main - - jobs: - test: - runs-on: ubuntu-latest - permissions: - checks: write - pull-requests: write - - steps: - - name: Check out repository - uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: "3.11" - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - python -m pip install poetry - poetry install --extras healpy_support - - - name: List files and check Python and package versions - run: | - ls -al - python -c 'import sys; print(sys.version_info[:])' - python -m pip freeze - - - name: Run tests - run: | - poetry env use python - PYRECEST_BACKEND=pytorch - poetry run python -m pytest --rootdir . -v --strict-config --junitxml=junit_test_results.xml ./pyrecest - env: - PYTHONPATH: ${{ github.workspace }} - - - name: Publish test results - if: always() - uses: EnricoMi/publish-unit-test-result-action@v2 - with: - files: junit_test_results.xml - \ No newline at end of file diff --git a/.github/workflows/update-requirements.yml b/.github/workflows/update-requirements.yml index 2a69fa6d..942f7a8c 100644 --- a/.github/workflows/update-requirements.yml +++ b/.github/workflows/update-requirements.yml @@ -35,7 +35,7 @@ jobs: run: python -m poetry update - name: Update requirements.txt - run: python -m poetry export --format requirements.txt --output requirements.txt --extras healpy_support --without-hashes + run: python -m poetry export --format requirements.txt --output requirements.txt --extras healpy_support --extras pytorch_support --without-hashes - name: Update requirements-dev.txt run: python -m poetry export --with dev --format requirements.txt --output requirements-dev.txt --without-hashes diff --git a/.jscpd.json b/.jscpd.json new file mode 100644 index 00000000..227ac63f --- /dev/null +++ b/.jscpd.json @@ -0,0 +1,6 @@ +{ + "ignore": [ + "pyrecest/_backend/**" + ] +} + \ No newline at end of file diff --git a/poetry.lock b/poetry.lock index 675112be..cb246bec 100644 --- a/poetry.lock +++ b/poetry.lock @@ -308,6 +308,22 @@ files = [ [package.extras] test = ["pytest (>=6)"] +[[package]] +name = "filelock" +version = "3.12.4" +description = "A platform independent file lock." +optional = false +python-versions = ">=3.8" +files = [ + {file = "filelock-3.12.4-py3-none-any.whl", hash = "sha256:08c21d87ded6e2b9da6728c3dff51baf1dcecf973b768ef35bcbc3447edb9ad4"}, + {file = "filelock-3.12.4.tar.gz", hash = "sha256:2e6f249f1f3654291606e046b09f1fd5eac39b360664c27f5aad072012f8bcbd"}, +] + +[package.extras] +docs = ["furo (>=2023.7.26)", "sphinx (>=7.1.2)", "sphinx-autodoc-typehints (>=1.24)"] +testing = ["covdefaults (>=2.3)", "coverage (>=7.3)", "diff-cover (>=7.7)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)", "pytest-timeout (>=2.1)"] +typing = ["typing-extensions (>=4.7.1)"] + [[package]] name = "filterpy" version = "1.4.5" @@ -388,6 +404,41 @@ ufo = ["fs (>=2.2.0,<3)"] unicode = ["unicodedata2 (>=15.0.0)"] woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] +[[package]] +name = "fsspec" +version = "2023.9.2" +description = "File-system specification" +optional = false +python-versions = ">=3.8" +files = [ + {file = "fsspec-2023.9.2-py3-none-any.whl", hash = "sha256:603dbc52c75b84da501b9b2ec8c11e1f61c25984c4a0dda1f129ef391fbfc9b4"}, + {file = "fsspec-2023.9.2.tar.gz", hash = "sha256:80bfb8c70cc27b2178cc62a935ecf242fc6e8c3fb801f9c571fc01b1e715ba7d"}, +] + +[package.extras] +abfs = ["adlfs"] +adl = ["adlfs"] +arrow = ["pyarrow (>=1)"] +dask = ["dask", "distributed"] +devel = ["pytest", "pytest-cov"] +dropbox = ["dropbox", "dropboxdrivefs", "requests"] +full = ["adlfs", "aiohttp (!=4.0.0a0,!=4.0.0a1)", "dask", "distributed", "dropbox", "dropboxdrivefs", "fusepy", "gcsfs", "libarchive-c", "ocifs", "panel", "paramiko", "pyarrow (>=1)", "pygit2", "requests", "s3fs", "smbprotocol", "tqdm"] +fuse = ["fusepy"] +gcs = ["gcsfs"] +git = ["pygit2"] +github = ["requests"] +gs = ["gcsfs"] +gui = ["panel"] +hdfs = ["pyarrow (>=1)"] +http = ["aiohttp (!=4.0.0a0,!=4.0.0a1)", "requests"] +libarchive = ["libarchive-c"] +oci = ["ocifs"] +s3 = ["s3fs"] +sftp = ["paramiko"] +smb = ["smbprotocol"] +ssh = ["paramiko"] +tqdm = ["tqdm"] + [[package]] name = "healpy" version = "1.16.6" @@ -441,6 +492,23 @@ files = [ {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, ] +[[package]] +name = "jinja2" +version = "3.1.2" +description = "A very fast and expressive template engine." +optional = false +python-versions = ">=3.7" +files = [ + {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, + {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, +] + +[package.dependencies] +MarkupSafe = ">=2.0" + +[package.extras] +i18n = ["Babel (>=2.7)"] + [[package]] name = "kiwisolver" version = "1.4.5" @@ -554,6 +622,75 @@ files = [ {file = "kiwisolver-1.4.5.tar.gz", hash = "sha256:e57e563a57fb22a142da34f38acc2fc1a5c864bc29ca1517a88abc963e60d6ec"}, ] +[[package]] +name = "markupsafe" +version = "2.1.3" +description = "Safely add untrusted strings to HTML/XML markup." +optional = false +python-versions = ">=3.7" +files = [ + {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-win32.whl", hash = "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-win32.whl", hash = "sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-win32.whl", hash = "sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-win_amd64.whl", hash = "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-win32.whl", hash = "sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-win_amd64.whl", hash = "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-win32.whl", hash = "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-win_amd64.whl", hash = "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba"}, + {file = "MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad"}, +] + [[package]] name = "matplotlib" version = "3.8.0" @@ -620,6 +757,24 @@ docs = ["sphinx"] gmpy = ["gmpy2 (>=2.1.0a4)"] tests = ["pytest (>=4.6)"] +[[package]] +name = "networkx" +version = "3.1" +description = "Python package for creating and manipulating graphs and networks" +optional = false +python-versions = ">=3.8" +files = [ + {file = "networkx-3.1-py3-none-any.whl", hash = "sha256:4f33f68cb2afcf86f28a45f43efc27a9386b535d567d2127f8f61d51dec58d36"}, + {file = "networkx-3.1.tar.gz", hash = "sha256:de346335408f84de0eada6ff9fafafff9bcda11f0a0dfaa931133debb146ab61"}, +] + +[package.extras] +default = ["matplotlib (>=3.4)", "numpy (>=1.20)", "pandas (>=1.3)", "scipy (>=1.8)"] +developer = ["mypy (>=1.1)", "pre-commit (>=3.2)"] +doc = ["nb2plots (>=0.6)", "numpydoc (>=1.5)", "pillow (>=9.4)", "pydata-sphinx-theme (>=0.13)", "sphinx (>=6.1)", "sphinx-gallery (>=0.12)", "texext (>=0.6.7)"] +extra = ["lxml (>=4.6)", "pydot (>=1.4.2)", "pygraphviz (>=1.10)", "sympy (>=1.10)"] +test = ["codecov (>=2.1)", "pytest (>=7.2)", "pytest-cov (>=4.0)"] + [[package]] name = "numpy" version = "1.26.1" @@ -1206,25 +1361,25 @@ testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jar [[package]] name = "setuptools-scm" -version = "8.0.3" +version = "8.0.4" description = "the blessed package to manage your versions by scm tags" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-scm-8.0.3.tar.gz", hash = "sha256:0169fd70197efda2f8c4d0b2a7a3d614431b488116f37b79d031e9e7ec884d8c"}, - {file = "setuptools_scm-8.0.3-py3-none-any.whl", hash = "sha256:813822234453438a13c78d05c8af29918fbc06f88efb33d38f065340bbb48c39"}, + {file = "setuptools-scm-8.0.4.tar.gz", hash = "sha256:b5f43ff6800669595193fd09891564ee9d1d7dcb196cab4b2506d53a2e1c95c7"}, + {file = "setuptools_scm-8.0.4-py3-none-any.whl", hash = "sha256:b47844cd2a84b83b3187a5782c71128c28b4c94cad8bfb871da2784a5cb54c4f"}, ] [package.dependencies] packaging = ">=20" setuptools = "*" tomli = {version = ">=1", markers = "python_version < \"3.11\""} -typing-extensions = {version = "*", markers = "python_version < \"3.11\""} +typing-extensions = "*" [package.extras] docs = ["entangled-cli[rich]", "mkdocs", "mkdocs-entangled-plugin", "mkdocs-material", "mkdocstrings[python]", "pygments"] rich = ["rich"] -test = ["pytest", "rich", "virtualenv (>20)"] +test = ["build", "pytest", "rich", "wheel"] [[package]] name = "shapely" @@ -1294,6 +1449,20 @@ files = [ {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, ] +[[package]] +name = "sympy" +version = "1.12" +description = "Computer algebra system (CAS) in Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "sympy-1.12-py3-none-any.whl", hash = "sha256:c3588cd4295d0c0f603d0f2ae780587e64e2efeedb3521e46b9bb1d08d184fa5"}, + {file = "sympy-1.12.tar.gz", hash = "sha256:ebf595c8dac3e0fdc4152c51878b498396ec7f30e7a914d6071e674d49420fb8"}, +] + +[package.dependencies] +mpmath = ">=0.19" + [[package]] name = "tomli" version = "2.0.1" @@ -1305,6 +1474,46 @@ files = [ {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, ] +[[package]] +name = "torch" +version = "2.1.0" +description = "Tensors and Dynamic neural networks in Python with strong GPU acceleration" +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "torch-2.1.0-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:bf57f8184b2c317ef81fb33dc233ce4d850cd98ef3f4a38be59c7c1572d175db"}, + {file = "torch-2.1.0-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:a04a0296d47f28960f51c18c5489a8c3472f624ec3b5bcc8e2096314df8c3342"}, + {file = "torch-2.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:0bd691efea319b14ef239ede16d8a45c246916456fa3ed4f217d8af679433cc6"}, + {file = "torch-2.1.0-cp310-none-macosx_10_9_x86_64.whl", hash = "sha256:101c139152959cb20ab370fc192672c50093747906ee4ceace44d8dd703f29af"}, + {file = "torch-2.1.0-cp310-none-macosx_11_0_arm64.whl", hash = "sha256:a6b7438a90a870e4cdeb15301519ae6c043c883fcd224d303c5b118082814767"}, + {file = "torch-2.1.0-cp311-cp311-manylinux1_x86_64.whl", hash = "sha256:2224622407ca52611cbc5b628106fde22ed8e679031f5a99ce286629fc696128"}, + {file = "torch-2.1.0-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:8132efb782cd181cc2dcca5e58effbe4217cdb2581206ac71466d535bf778867"}, + {file = "torch-2.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:5c3bfa91ce25ba10116c224c59d5b64cdcce07161321d978bd5a1f15e1ebce72"}, + {file = "torch-2.1.0-cp311-none-macosx_10_9_x86_64.whl", hash = "sha256:601b0a2a9d9233fb4b81f7d47dca9680d4f3a78ca3f781078b6ad1ced8a90523"}, + {file = "torch-2.1.0-cp311-none-macosx_11_0_arm64.whl", hash = "sha256:3cd1dedff13884d890f18eea620184fb4cd8fd3c68ce3300498f427ae93aa962"}, + {file = "torch-2.1.0-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:fb7bf0cc1a3db484eb5d713942a93172f3bac026fcb377a0cd107093d2eba777"}, + {file = "torch-2.1.0-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:761822761fffaa1c18a62c5deb13abaa780862577d3eadc428f1daa632536905"}, + {file = "torch-2.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:458a6d6d8f7d2ccc348ac4d62ea661b39a3592ad15be385bebd0a31ced7e00f4"}, + {file = "torch-2.1.0-cp38-none-macosx_10_9_x86_64.whl", hash = "sha256:c8bf7eaf9514465e5d9101e05195183470a6215bb50295c61b52302a04edb690"}, + {file = "torch-2.1.0-cp38-none-macosx_11_0_arm64.whl", hash = "sha256:05661c32ec14bc3a157193d0f19a7b19d8e61eb787b33353cad30202c295e83b"}, + {file = "torch-2.1.0-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:556d8dd3e0c290ed9d4d7de598a213fb9f7c59135b4fee144364a8a887016a55"}, + {file = "torch-2.1.0-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:de7d63c6ecece118684415a3dbd4805af4a4c1ee1490cccf7405d8c240a481b4"}, + {file = "torch-2.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:2419cf49aaf3b2336c7aa7a54a1b949fa295b1ae36f77e2aecb3a74e3a947255"}, + {file = "torch-2.1.0-cp39-none-macosx_10_9_x86_64.whl", hash = "sha256:6ad491e70dbe4288d17fdbfc7fbfa766d66cbe219bc4871c7a8096f4a37c98df"}, + {file = "torch-2.1.0-cp39-none-macosx_11_0_arm64.whl", hash = "sha256:421739685eba5e0beba42cb649740b15d44b0d565c04e6ed667b41148734a75b"}, +] + +[package.dependencies] +filelock = "*" +fsspec = "*" +jinja2 = "*" +networkx = "*" +sympy = "*" +typing-extensions = "*" + +[package.extras] +opt-einsum = ["opt-einsum (>=3.3)"] + [[package]] name = "tqdm" version = "4.66.1" @@ -1389,8 +1598,9 @@ viz = ["matplotlib", "nc-time-axis", "seaborn"] [extras] healpy-support = [] +pytorch-support = [] [metadata] lock-version = "2.0" python-versions = ">=3.10,<3.13" -content-hash = "3c2b20f1c9a36843fc6cb583ea2521f785d7504ccdf4677cbb1b25e816c7498d" +content-hash = "0999488f2868769e363292457227ed356e9167576ec5163ca347b800776d1b4d" diff --git a/pyproject.toml b/pyproject.toml index 0d5ddd9c..495cb6de 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,9 +19,11 @@ shapely = "*" [tool.poetry.extras] healpy_support = ["healpy"] +pytorch_support = ["torch"] [tool.poetry.group.dev.dependencies] healpy = "*" +torch = "*" autopep8 = "^2.0.2" pytest = "*" parameterized = "*" diff --git a/pyrecest/_backend/.pylintrc b/pyrecest/_backend/.pylintrc new file mode 100644 index 00000000..8a8618c8 --- /dev/null +++ b/pyrecest/_backend/.pylintrc @@ -0,0 +1,2 @@ +[MESSAGES CONTROL] +disable=all \ No newline at end of file diff --git a/pyrecest/_backend/_shared_numpy/__init__.py b/pyrecest/_backend/_shared_numpy/__init__.py index 9857cad0..ff3ac99b 100644 --- a/pyrecest/_backend/_shared_numpy/__init__.py +++ b/pyrecest/_backend/_shared_numpy/__init__.py @@ -196,7 +196,7 @@ def assignment_by_sum(x, values, indices, axis=0): def ndim(x): - return x.ndim + return _np.ndim(x) def get_slice(x, indices): diff --git a/pyrecest/distributions/abstract_dirac_distribution.py b/pyrecest/distributions/abstract_dirac_distribution.py index 22c6dedc..fff62321 100644 --- a/pyrecest/distributions/abstract_dirac_distribution.py +++ b/pyrecest/distributions/abstract_dirac_distribution.py @@ -1,3 +1,11 @@ +from pyrecest.backend import sum +from pyrecest.backend import ones +from pyrecest.backend import log +from pyrecest.backend import isclose +from pyrecest.backend import argmax +from pyrecest.backend import all +from pyrecest.backend import int64 +from pyrecest.backend import int32 import copy import warnings from collections.abc import Callable @@ -22,7 +30,7 @@ def __init__(self, d: np.ndarray, w: np.ndarray | None = None): :param w: Weights of Dirac locations as a numpy array. If not provided, defaults to uniform weights. """ if w is None: - w = np.ones(d.shape[0]) / d.shape[0] + w = ones(d.shape[0]) / d.shape[0] assert d.shape[0] == np.size(w), "Number of Diracs and weights must match." self.d = copy.copy(d) @@ -34,9 +42,9 @@ def normalize_in_place(self): """ Normalize the weights in-place to ensure they sum to 1. """ - if not np.isclose(np.sum(self.w), 1, atol=1e-10): + if not isclose(sum(self.w), 1, atol=1e-10): warnings.warn("Weights are not normalized.", RuntimeWarning) - self.w = self.w / np.sum(self.w) + self.w = self.w / sum(self.w) @beartype def normalize(self) -> "AbstractDiracDistribution": @@ -67,28 +75,28 @@ def reweigh(self, f: Callable) -> "AbstractDiracDistribution": wNew = f(dist.d) assert wNew.shape == dist.w.shape, "Function returned wrong output dimensions." - assert np.all(wNew >= 0), "All weights should be greater than or equal to 0." - assert np.sum(wNew) > 0, "The sum of all weights should be greater than 0." + assert all(wNew >= 0), "All weights should be greater than or equal to 0." + assert sum(wNew) > 0, "The sum of all weights should be greater than 0." dist.w = wNew * dist.w - dist.w = dist.w / np.sum(dist.w) + dist.w = dist.w / sum(dist.w) return dist @beartype - def sample(self, n: int | np.int32 | np.int64) -> np.ndarray: + def sample(self, n: int | int32 | int64) -> np.ndarray: ids = np.random.choice(np.size(self.w), size=n, p=self.w) return self.d[ids] def entropy(self) -> float: warnings.warn("Entropy is not defined in a continuous sense") - return -np.sum(self.w * np.log(self.w)) + return -sum(self.w * log(self.w)) def integrate(self, left=None, right=None) -> np.ndarray: assert ( left is None and right is None ), "Must overwrite in child class to use integral limits" - return np.sum(self.w) + return sum(self.w) def log_likelihood(self, *args): raise NotImplementedError("PDF:UNDEFINED, not supported") @@ -112,7 +120,7 @@ def kld_numerical(self, *args): raise NotImplementedError("PDF:UNDEFINED, not supported") def mode(self, rel_tol=0.001): - highest_val, ind = np.max(self.w), np.argmax(self.w) + highest_val, ind = np.max(self.w), argmax(self.w) if (highest_val / self.w.size) < (1 + rel_tol): warnings.warn( "The samples may be equally weighted, .mode is likely to return a bad result." diff --git a/pyrecest/distributions/abstract_disk_distribution.py b/pyrecest/distributions/abstract_disk_distribution.py index c59a5494..73c74c0b 100644 --- a/pyrecest/distributions/abstract_disk_distribution.py +++ b/pyrecest/distributions/abstract_disk_distribution.py @@ -1,3 +1,5 @@ +from pyrecest.backend import eye +from pyrecest.backend import array import numpy as np from .abstract_ellipsoidal_ball_distribution import AbstractEllipsoidalBallDistribution @@ -10,7 +12,7 @@ class AbstractDiskDistribution(AbstractEllipsoidalBallDistribution): # We index it using 2-D Euclidean vectors (is zero everywhere else) def __init__(self): - super().__init__(np.array([0, 0]), np.eye(2)) + super().__init__(array([0, 0]), eye(2)) def mean(self): raise TypeError("Mean not defined for distributions on the disk.") diff --git a/pyrecest/distributions/abstract_ellipsoidal_ball_distribution.py b/pyrecest/distributions/abstract_ellipsoidal_ball_distribution.py index ad98c07f..fe3f39a3 100644 --- a/pyrecest/distributions/abstract_ellipsoidal_ball_distribution.py +++ b/pyrecest/distributions/abstract_ellipsoidal_ball_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import sqrt import numbers import numpy as np @@ -50,4 +51,4 @@ def get_manifold_size(self) -> np.number | numbers.Real: else: c = (np.pi ** (self.dim / 2)) / gamma((self.dim / 2) + 1) - return c * np.sqrt(np.linalg.det(self.shape_matrix)) + return c * sqrt(np.linalg.det(self.shape_matrix)) diff --git a/pyrecest/distributions/abstract_manifold_specific_distribution.py b/pyrecest/distributions/abstract_manifold_specific_distribution.py index 3ecac616..6016399b 100644 --- a/pyrecest/distributions/abstract_manifold_specific_distribution.py +++ b/pyrecest/distributions/abstract_manifold_specific_distribution.py @@ -1,3 +1,7 @@ +from pyrecest.backend import squeeze +from pyrecest.backend import int64 +from pyrecest.backend import int32 +from pyrecest.backend import empty import numbers from abc import ABC, abstractmethod from collections.abc import Callable @@ -60,7 +64,7 @@ def set_mode(self, _): raise NotImplementedError("set_mode is not implemented for this distribution") @beartype - def sample(self, n: int | np.int32 | np.int64) -> np.ndarray: + def sample(self, n: int | int32 | int64) -> np.ndarray: """Obtain n samples from the distribution.""" return self.sample_metropolis_hastings(n) @@ -68,9 +72,9 @@ def sample(self, n: int | np.int32 | np.int64) -> np.ndarray: @beartype def sample_metropolis_hastings( self, - n: int | np.int32 | np.int64, - burn_in: int | np.int32 | np.int64 = 10, - skipping: int | np.int32 | np.int64 = 5, + n: int | int32 | int64, + burn_in: int | int32 | int64 = 10, + skipping: int | int32 | int64 = 5, proposal: Callable | None = None, start_point: np.number | numbers.Real | np.ndarray | None = None, ) -> np.ndarray: @@ -83,7 +87,7 @@ def sample_metropolis_hastings( ) total_samples = burn_in + n * skipping - s = np.empty( + s = empty( ( total_samples, self.input_dim, @@ -105,4 +109,4 @@ def sample_metropolis_hastings( i += 1 relevant_samples = s[burn_in::skipping, :] - return np.squeeze(relevant_samples) + return squeeze(relevant_samples) diff --git a/pyrecest/distributions/abstract_mixture.py b/pyrecest/distributions/abstract_mixture.py index 0dcb1467..e19ea199 100644 --- a/pyrecest/distributions/abstract_mixture.py +++ b/pyrecest/distributions/abstract_mixture.py @@ -1,3 +1,9 @@ +from pyrecest.backend import sum +from pyrecest.backend import ones +from pyrecest.backend import int64 +from pyrecest.backend import int32 +from pyrecest.backend import empty +from pyrecest.backend import zeros import collections import copy import warnings @@ -27,7 +33,7 @@ def __init__( num_distributions = len(dists) if weights is None: - weights = np.ones(num_distributions) / num_distributions + weights = ones(num_distributions) / num_distributions else: weights = np.asarray(weights) @@ -48,9 +54,9 @@ def __init__( self.dists = dists - if abs(np.sum(weights) - 1) > 1e-10: + if abs(sum(weights) - 1) > 1e-10: warnings.warn("Weights of mixture do not sum to one.") - self.w = weights / np.sum(weights) + self.w = weights / sum(weights) else: self.w = weights @@ -59,12 +65,12 @@ def input_dim(self) -> int: return self.dists[0].input_dim @beartype - def sample(self, n: int | np.int32 | np.int64) -> np.ndarray: + def sample(self, n: int | int32 | int64) -> np.ndarray: d = np.random.choice(len(self.w), size=n, p=self.w) occurrences = np.bincount(d, minlength=len(self.dists)) count = 0 - s = np.empty((n, self.input_dim)) + s = empty((n, self.input_dim)) for i, occ in enumerate(occurrences): if occ != 0: s[count : count + occ, :] = self.dists[i].sample(occ) # noqa: E203 @@ -79,7 +85,7 @@ def sample(self, n: int | np.int32 | np.int64) -> np.ndarray: def pdf(self, xs: np.ndarray) -> np.ndarray: assert xs.shape[-1] == self.input_dim, "Dimension mismatch" - p = np.zeros(1) if xs.ndim == 1 else np.zeros(xs.shape[0]) + p = zeros(1) if xs.ndim == 1 else zeros(xs.shape[0]) for i, dist in enumerate(self.dists): p += self.w[i] * dist.pdf(xs) diff --git a/pyrecest/distributions/abstract_orthogonal_basis_distribution.py b/pyrecest/distributions/abstract_orthogonal_basis_distribution.py index f77cb17f..4cfed29a 100644 --- a/pyrecest/distributions/abstract_orthogonal_basis_distribution.py +++ b/pyrecest/distributions/abstract_orthogonal_basis_distribution.py @@ -1,3 +1,7 @@ +from pyrecest.backend import real +from pyrecest.backend import imag +from pyrecest.backend import exp +from pyrecest.backend import all import copy import warnings from abc import abstractmethod @@ -57,14 +61,14 @@ def pdf(self, xs: np.ndarray | np.number) -> np.ndarray | np.number: """ val = self.value(xs) if self.transformation == "sqrt": - assert np.all(np.imag(val) < 0.0001) - return np.real(val) ** 2 + assert all(imag(val) < 0.0001) + return real(val) ** 2 if self.transformation == "identity": return val if self.transformation == "log": warnings.warn("Density may not be normalized") - return np.exp(val) + return exp(val) raise ValueError("Transformation not recognized or unsupported") diff --git a/pyrecest/distributions/abstract_periodic_distribution.py b/pyrecest/distributions/abstract_periodic_distribution.py index dab7eca4..00495ed3 100644 --- a/pyrecest/distributions/abstract_periodic_distribution.py +++ b/pyrecest/distributions/abstract_periodic_distribution.py @@ -1,3 +1,5 @@ +from pyrecest.backend import int64 +from pyrecest.backend import int32 from abc import abstractmethod import numpy as np @@ -10,7 +12,7 @@ class AbstractPeriodicDistribution(AbstractBoundedDomainDistribution): """Abstract class for a distributions on periodic manifolds.""" @beartype - def __init__(self, dim: int | np.int32 | np.int64): + def __init__(self, dim: int | int32 | int64): super().__init__(dim=dim) @beartype diff --git a/pyrecest/distributions/abstract_se3_distribution.py b/pyrecest/distributions/abstract_se3_distribution.py index 084cdf39..c76b4361 100644 --- a/pyrecest/distributions/abstract_se3_distribution.py +++ b/pyrecest/distributions/abstract_se3_distribution.py @@ -1,3 +1,6 @@ +from pyrecest.backend import concatenate +from pyrecest.backend import int64 +from pyrecest.backend import int32 import time from abc import abstractmethod @@ -29,7 +32,7 @@ def plot_mode(self): def plot_state( self, - orientationSamples: int | np.int32 | np.int64 = 10, + orientationSamples: int | int32 | int64 = 10, showMarginalized: bool = True, ): samples = self.sample(orientationSamples) @@ -44,7 +47,7 @@ def plot_state( linearPart = samples[4:, i] h.append( AbstractSE3Distribution.plot_point( - np.concatenate((samples[:4, i], linearPart), axis=0) + concatenate((samples[:4, i], linearPart), axis=0) ) ) return h @@ -68,7 +71,7 @@ def plot_point(se3point): # pylint: disable=too-many-locals pos[0], pos[1], pos[2], rotMat[2, 0], rotMat[2, 1], rotMat[2, 2], color="b" ) h = [h1, h2, h3] - relevant_coords = np.concatenate((pos.reshape(-1, 1), pos + rotMat), axis=1) + relevant_coords = concatenate((pos.reshape(-1, 1), pos + rotMat), axis=1) needed_boundaries = np.column_stack( (np.min(relevant_coords, axis=1), np.max(relevant_coords, axis=1)) ) @@ -98,7 +101,7 @@ def plot_trajectory(periodicStates, linStates, animate=False, delay=0.05): for i in range(periodicStates.shape[1]): h.append( AbstractSE3Distribution.plot_point( - np.concatenate((periodicStates[:, i], linStates[:, i]), axis=0) + concatenate((periodicStates[:, i], linStates[:, i]), axis=0) ) ) if animate: diff --git a/pyrecest/distributions/abstract_uniform_distribution.py b/pyrecest/distributions/abstract_uniform_distribution.py index 58a85f9d..bcae3375 100644 --- a/pyrecest/distributions/abstract_uniform_distribution.py +++ b/pyrecest/distributions/abstract_uniform_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import ones from abc import abstractmethod import numpy as np @@ -19,7 +20,7 @@ def pdf(self, xs: np.ndarray) -> np.ndarray: :return: The pdf evaluated at each point in xs. :rtype: np.ndarray """ - return 1 / self.get_manifold_size() * np.ones(xs.shape[0]) + return 1 / self.get_manifold_size() * ones(xs.shape[0]) @abstractmethod def get_manifold_size(self) -> np.ndarray: diff --git a/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py b/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py index 2d2c29a8..4b701db4 100644 --- a/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py +++ b/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py @@ -1,3 +1,19 @@ +from pyrecest.backend import vstack +from pyrecest.backend import tile +from pyrecest.backend import sqrt +from pyrecest.backend import ones +from pyrecest.backend import ndim +from pyrecest.backend import mod +from pyrecest.backend import isnan +from pyrecest.backend import concatenate +from pyrecest.backend import array +from pyrecest.backend import any +from pyrecest.backend import allclose +from pyrecest.backend import all +from pyrecest.backend import int64 +from pyrecest.backend import int32 +from pyrecest.backend import empty +from pyrecest.backend import zeros from abc import abstractmethod import numpy as np @@ -17,7 +33,7 @@ class AbstractHypercylindricalDistribution(AbstractLinPeriodicCartProdDistribution): def __init__( - self, bound_dim: int | np.int32 | np.int64, lin_dim: int | np.int32 | np.int64 + self, bound_dim: int | int32 | int64, lin_dim: int | int32 | int64 ): AbstractLinPeriodicCartProdDistribution.__init__(self, bound_dim, lin_dim) @@ -33,7 +49,7 @@ def integrate_numerically(self, integration_boundaries=None): integration_boundaries = self.get_reasonable_integration_boundaries() def f(*args): - return self.pdf(np.array(args)) + return self.pdf(array(args)) integration_result = nquad(f, integration_boundaries)[0] @@ -45,20 +61,20 @@ def get_reasonable_integration_boundaries(self, scalingFactor=10) -> np.ndarray: Returns reasonable integration boundaries for the specific distribution based on the mode and covariance. """ - left = np.empty((self.bound_dim + self.lin_dim, 1)) - right = np.empty((self.bound_dim + self.lin_dim, 1)) + left = empty((self.bound_dim + self.lin_dim, 1)) + right = empty((self.bound_dim + self.lin_dim, 1)) P = self.linear_covariance() m = self.mode() for i in range(self.bound_dim, self.bound_dim + self.lin_dim): - left[i] = m[i] - scalingFactor * np.sqrt( + left[i] = m[i] - scalingFactor * sqrt( P[i - self.bound_dim, i - self.bound_dim] ) - right[i] = m[i] + scalingFactor * np.sqrt( + right[i] = m[i] + scalingFactor * sqrt( P[i - self.bound_dim, i - self.bound_dim] ) - return np.vstack((left, right)) + return vstack((left, right)) def mode(self): """Find the mode of the distribution by calling mode_numerical.""" @@ -96,7 +112,7 @@ def linear_covariance_numerical(self, approximate_mean=None): - C : ndarray The linear covariance. """ - if approximate_mean is None or np.any(np.isnan(approximate_mean)): + if approximate_mean is None or any(isnan(approximate_mean)): approximate_mean = self.linear_mean_numerical() if self.bound_dim == 1 and self.lin_dim == 1: @@ -110,7 +126,7 @@ def linear_covariance_numerical(self, approximate_mean=None): [[0, 2 * np.pi], [0, 2 * np.pi], [-np.inf, np.inf]], ) elif self.bound_dim == 1 and self.lin_dim == 2: - C = np.empty((2, 2)) + C = empty((2, 2)) C[0, 0], _ = nquad( lambda x, y, z: (y - approximate_mean[0]) ** 2 * self.pdf([x, y, z]), [[0, 2 * np.pi], [-np.inf, np.inf], [-np.inf, np.inf]], @@ -146,12 +162,12 @@ def condition_on_linear(self, input_lin, normalize=True): The distribution after conditioning. """ assert ( - np.size(input_lin) == self.lin_dim and np.ndim(input_lin) <= 1 + np.size(input_lin) == self.lin_dim and ndim(input_lin) <= 1 ), "Input should be of size (lin_dim,)." def f_cond_unnorm(x, input_lin=input_lin): - n_inputs = np.size(x) // x.shape[-1] if np.ndim(x) > 1 else np.size(x) - input_repeated = np.tile(input_lin, (n_inputs, 1)) + n_inputs = np.size(x) // x.shape[-1] if ndim(x) > 1 else np.size(x) + input_repeated = tile(input_lin, (n_inputs, 1)) return self.pdf(np.column_stack((x, input_repeated))) dist = CustomHypertoroidalDistribution(f_cond_unnorm, self.bound_dim) @@ -176,14 +192,14 @@ def condition_on_periodic(self, input_periodic, normalize=True): CustomLinearDistribution instance """ assert ( - np.size(input_periodic) == self.bound_dim and np.ndim(input_periodic) <= 1 + np.size(input_periodic) == self.bound_dim and ndim(input_periodic) <= 1 ), "Input should be of size (lin_dim,)." - input_periodic = np.mod(input_periodic, 2 * np.pi) + input_periodic = mod(input_periodic, 2 * np.pi) def f_cond_unnorm(x, input_periodic=input_periodic): - n_inputs = np.size(x) // x.shape[-1] if np.ndim(x) > 1 else np.size(x) - input_repeated = np.tile(input_periodic, (n_inputs, 1)) + n_inputs = np.size(x) // x.shape[-1] if ndim(x) > 1 else np.size(x) + input_repeated = tile(input_periodic, (n_inputs, 1)) return self.pdf(np.column_stack((input_repeated, x))) dist = CustomLinearDistribution(f_cond_unnorm, self.lin_dim) @@ -206,7 +222,7 @@ def linear_mean_numerical(self): [[0, 2 * np.pi], [0, 2 * np.pi], [-np.inf, np.inf]], )[0] elif self.bound_dim == 1 and self.lin_dim == 2: - mu = np.empty(2) + mu = empty(2) mu[0] = scipy.integrate.nquad( lambda x, y, z: (y * self.pdf([x, y, z]))[0], [[0, 2 * np.pi], [-np.inf, np.inf], [-np.inf, np.inf]], @@ -234,8 +250,8 @@ def mode_numerical(self, starting_point=None): The mode of the distribution. """ if starting_point is None: - starting_point = np.concatenate( - [np.pi * np.ones(self.bound_dim), np.zeros(self.lin_dim)] + starting_point = concatenate( + [np.pi * ones(self.bound_dim), zeros(self.lin_dim)] ) # Define bounds for the optimization @@ -250,7 +266,7 @@ def mode_numerical(self, starting_point=None): ) # Check if the optimization might have stopped early - if np.allclose(res.x, starting_point): + if allclose(res.x, starting_point): print( "Warning: Mode was at the starting point. This may indicate the optimizer stopped early." ) diff --git a/pyrecest/distributions/cart_prod/abstract_lin_bounded_cart_prod_distribution.py b/pyrecest/distributions/cart_prod/abstract_lin_bounded_cart_prod_distribution.py index 8226f817..7b451099 100644 --- a/pyrecest/distributions/cart_prod/abstract_lin_bounded_cart_prod_distribution.py +++ b/pyrecest/distributions/cart_prod/abstract_lin_bounded_cart_prod_distribution.py @@ -1,3 +1,5 @@ +from pyrecest.backend import int64 +from pyrecest.backend import int32 from abc import abstractmethod import numpy as np @@ -15,7 +17,7 @@ class AbstractLinBoundedCartProdDistribution(AbstractCartProdDistribution): @beartype def __init__( - self, bound_dim: int | np.int32 | np.int64, lin_dim: int | np.int32 | np.int64 + self, bound_dim: int | int32 | int64, lin_dim: int | int32 | int64 ): """ Parameters: diff --git a/pyrecest/distributions/cart_prod/cart_prod_stacked_distribution.py b/pyrecest/distributions/cart_prod/cart_prod_stacked_distribution.py index 5c4b4e8f..8bcb1f81 100644 --- a/pyrecest/distributions/cart_prod/cart_prod_stacked_distribution.py +++ b/pyrecest/distributions/cart_prod/cart_prod_stacked_distribution.py @@ -1,3 +1,7 @@ +from pyrecest.backend import prod +from pyrecest.backend import hstack +from pyrecest.backend import concatenate +from pyrecest.backend import empty import numpy as np from .abstract_cart_prod_distribution import AbstractCartProdDistribution @@ -10,15 +14,15 @@ def __init__(self, dists): def sample(self, n): assert n > 0 and isinstance(n, int), "n must be a positive integer" - return np.hstack([dist.sample(n) for dist in self.dists]) + return hstack([dist.sample(n) for dist in self.dists]) def pdf(self, xs): - ps = np.empty((len(self.dists), xs.shape[1])) + ps = empty((len(self.dists), xs.shape[1])) next_dim = 0 for i, dist in enumerate(self.dists): ps[i, :] = dist.pdf(xs[next_dim : next_dim + dist.dim, :]) # noqa: E203 next_dim += dist.dim - return np.prod(ps, axis=0) + return prod(ps, axis=0) def shift(self, shift_by): assert len(shift_by) == self.dim, "Incorrect number of offsets" @@ -39,7 +43,7 @@ def set_mode(self, new_mode): return CartProdStackedDistribution(new_dists) def hybrid_mean(self): - return np.concatenate([dist.mean() for dist in self.dists]) + return concatenate([dist.mean() for dist in self.dists]) def mean(self): """ @@ -52,4 +56,4 @@ def mean(self): return self.hybrid_mean() def mode(self): - return np.concatenate([dist.mode() for dist in self.dists]) + return concatenate([dist.mode() for dist in self.dists]) diff --git a/pyrecest/distributions/cart_prod/hypercylindrical_dirac_distribution.py b/pyrecest/distributions/cart_prod/hypercylindrical_dirac_distribution.py index 00461d4b..c73d6e78 100644 --- a/pyrecest/distributions/cart_prod/hypercylindrical_dirac_distribution.py +++ b/pyrecest/distributions/cart_prod/hypercylindrical_dirac_distribution.py @@ -1,3 +1,9 @@ +from pyrecest.backend import tile +from pyrecest.backend import sum +from pyrecest.backend import sin +from pyrecest.backend import cos +from pyrecest.backend import int64 +from pyrecest.backend import int32 import numpy as np from ..hypertorus.hypertoroidal_dirac_distribution import HypertoroidalDiracDistribution @@ -10,7 +16,7 @@ class HypercylindricalDiracDistribution( LinBoundedCartProdDiracDistribution, AbstractHypercylindricalDistribution ): - def __init__(self, bound_dim: int | np.int32 | np.int64, d, w=None): + def __init__(self, bound_dim: int | int32 | int64, d, w=None): AbstractHypercylindricalDistribution.__init__( self, bound_dim, d.shape[-1] - bound_dim ) @@ -33,9 +39,9 @@ def hybrid_moment(self): S[2 * self.bound_dim :, :] = self.d[:, self.bound_dim :].T # noqa: E203 for i in range(self.bound_dim): - S[2 * i, :] = np.cos(self.d[:, i]) # noqa: E203 - S[2 * i + 1, :] = np.sin(self.d[:, i]) # noqa: E203 + S[2 * i, :] = cos(self.d[:, i]) # noqa: E203 + S[2 * i + 1, :] = sin(self.d[:, i]) # noqa: E203 - return np.sum( - np.tile(self.w, (self.lin_dim + 2 * self.bound_dim, 1)) * S, axis=1 + return sum( + tile(self.w, (self.lin_dim + 2 * self.bound_dim, 1)) * S, axis=1 ) diff --git a/pyrecest/distributions/cart_prod/lin_bounded_cart_prod_dirac_distribution.py b/pyrecest/distributions/cart_prod/lin_bounded_cart_prod_dirac_distribution.py index fea20f24..b0915604 100644 --- a/pyrecest/distributions/cart_prod/lin_bounded_cart_prod_dirac_distribution.py +++ b/pyrecest/distributions/cart_prod/lin_bounded_cart_prod_dirac_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import concatenate import warnings from abc import abstractmethod @@ -38,7 +39,7 @@ def hybrid_mean(self): periodic = self.marginalize_linear() linear = self.marginalize_periodic() - return np.concatenate((periodic.mean_direction(), linear.mean())) + return concatenate((periodic.mean_direction(), linear.mean())) @classmethod def from_distribution(cls, distribution, n_particles): diff --git a/pyrecest/distributions/cart_prod/lin_hypersphere_cart_prod_dirac_distribution.py b/pyrecest/distributions/cart_prod/lin_hypersphere_cart_prod_dirac_distribution.py index b39e8540..f66a86df 100644 --- a/pyrecest/distributions/cart_prod/lin_hypersphere_cart_prod_dirac_distribution.py +++ b/pyrecest/distributions/cart_prod/lin_hypersphere_cart_prod_dirac_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import abs import numpy as np from ..abstract_se3_distribution import AbstractSE3Distribution @@ -11,7 +12,7 @@ class LinHypersphereCartProdDiracDistribution( ): def __init__(self, bound_dim, d, w=None): assert ( - np.max(np.abs(np.linalg.norm(d[:, : (bound_dim + 1)], axis=-1) - 1)) < 1e-5 + np.max(abs(np.linalg.norm(d[:, : (bound_dim + 1)], axis=-1) - 1)) < 1e-5 ), "The hypersphere ssubset part of d must be normalized" AbstractSE3Distribution.__init__(self) LinBoundedCartProdDiracDistribution.__init__(self, d, w) diff --git a/pyrecest/distributions/cart_prod/lin_hypersphere_subset_dirac_distribution.py b/pyrecest/distributions/cart_prod/lin_hypersphere_subset_dirac_distribution.py index 176a9851..6d95b36f 100644 --- a/pyrecest/distributions/cart_prod/lin_hypersphere_subset_dirac_distribution.py +++ b/pyrecest/distributions/cart_prod/lin_hypersphere_subset_dirac_distribution.py @@ -1,3 +1,5 @@ +from pyrecest.backend import int64 +from pyrecest.backend import int32 import numpy as np from .abstract_lin_hyperhemisphere_cart_prod_distribution import ( @@ -12,7 +14,7 @@ class LinHypersphereSubsetCartProdDiracDistribution( LinBoundedCartProdDiracDistribution, AbstractLinHypersphereSubsetCartProdDistribution, ): - def __init__(self, bound_dim: int | np.int32 | np.int64, d, w=None): + def __init__(self, bound_dim: int | int32 | int64, d, w=None): AbstractLinHypersphereSubsetCartProdDistribution.__init__( self, bound_dim, d.shape[-1] - bound_dim - 1 ) diff --git a/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py b/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py index fa075eaf..1d1ccd32 100644 --- a/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py +++ b/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py @@ -1,3 +1,20 @@ +from pyrecest.backend import tile +from pyrecest.backend import sum +from pyrecest.backend import sin +from pyrecest.backend import shape +from pyrecest.backend import repeat +from pyrecest.backend import ndim +from pyrecest.backend import mod +from pyrecest.backend import meshgrid +from pyrecest.backend import exp +from pyrecest.backend import cos +from pyrecest.backend import concatenate +from pyrecest.backend import array +from pyrecest.backend import allclose +from pyrecest.backend import all +from pyrecest.backend import int64 +from pyrecest.backend import int32 +from pyrecest.backend import empty import copy import numpy as np @@ -14,50 +31,50 @@ class PartiallyWrappedNormalDistribution(AbstractHypercylindricalDistribution): @beartype def __init__( - self, mu: np.ndarray, C: np.ndarray, bound_dim: int | np.int32 | np.int64 + self, mu: np.ndarray, C: np.ndarray, bound_dim: int | int32 | int64 ): assert bound_dim >= 0, "bound_dim must be non-negative" - assert np.ndim(mu) == 1, "mu must be a 1-dimensional array" - assert np.shape(C) == (np.size(mu), np.size(mu)), "C must match size of mu" - assert np.allclose(C, C.T), "C must be symmetric" - assert np.all(np.linalg.eigvals(C) > 0), "C must be positive definite" + assert ndim(mu) == 1, "mu must be a 1-dimensional array" + assert shape(C) == (np.size(mu), np.size(mu)), "C must match size of mu" + assert allclose(C, C.T), "C must be symmetric" + assert all(np.linalg.eigvals(C) > 0), "C must be positive definite" assert bound_dim <= np.size(mu) - assert np.ndim(mu) == 1 + assert ndim(mu) == 1 if bound_dim > 0: # This decreases the need for many wrappings - mu[:bound_dim] = np.mod(mu[:bound_dim], 2 * np.pi) + mu[:bound_dim] = mod(mu[:bound_dim], 2 * np.pi) AbstractHypercylindricalDistribution.__init__( self, bound_dim=bound_dim, lin_dim=np.size(mu) - bound_dim ) self.mu = mu - self.mu[:bound_dim] = np.mod(self.mu[:bound_dim], 2 * np.pi) + self.mu[:bound_dim] = mod(self.mu[:bound_dim], 2 * np.pi) self.C = C - def pdf(self, xs: np.ndarray, m: int | np.int32 | np.int64 = 3): + def pdf(self, xs: np.ndarray, m: int | int32 | int64 = 3): xs = np.atleast_2d(xs) if self.bound_dim > 0: - xs[:, : self.bound_dim] = np.mod(xs[:, : self.bound_dim], 2 * np.pi) + xs[:, : self.bound_dim] = mod(xs[:, : self.bound_dim], 2 * np.pi) assert xs.shape[-1] == self.input_dim # generate multiples for wrapping - multiples = np.array(range(-m, m + 1)) * 2 * np.pi + multiples = array(range(-m, m + 1)) * 2 * np.pi # create meshgrid for all combinations of multiples - mesh = np.array(np.meshgrid(*[multiples] * self.bound_dim)).reshape( + mesh = array(meshgrid(*[multiples] * self.bound_dim)).reshape( -1, self.bound_dim ) # reshape xs for broadcasting - xs_reshaped = np.tile(xs[:, : self.bound_dim], (mesh.shape[0], 1)) # noqa: E203 + xs_reshaped = tile(xs[:, : self.bound_dim], (mesh.shape[0], 1)) # noqa: E203 # prepare data for wrapping (not applied to linear dimensions) - xs_wrapped = xs_reshaped + np.repeat(mesh, xs.shape[0], axis=0) - xs_wrapped = np.concatenate( + xs_wrapped = xs_reshaped + repeat(mesh, xs.shape[0], axis=0) + xs_wrapped = concatenate( [ xs_wrapped, - np.tile(xs[:, self.bound_dim :], (mesh.shape[0], 1)), # noqa: E203 + tile(xs[:, self.bound_dim :], (mesh.shape[0], 1)), # noqa: E203 ], axis=1, ) @@ -67,7 +84,7 @@ def pdf(self, xs: np.ndarray, m: int | np.int32 | np.int64 = 3): evals = mvn.pdf(xs_wrapped) # sum evaluations for the wrapped dimensions - summed_evals = np.sum(evals.reshape(-1, (2 * m + 1) ** self.bound_dim), axis=1) + summed_evals = sum(evals.reshape(-1, (2 * m + 1) ** self.bound_dim), axis=1) return summed_evals @@ -89,11 +106,11 @@ def hybrid_moment(self): Returns: mu (linD+2): expectation value of [x1, x2, .., x_lin_dim, cos(x_(lin_dim+1), sin(x_(lin_dim+1)), ..., cos(x_(lin_dim+bound_dim), sin(x_(lin_dim+bound_dim))] """ - mu = np.empty(2 * self.bound_dim + self.lin_dim) + mu = empty(2 * self.bound_dim + self.lin_dim) mu[2 * self.bound_dim :] = self.mu[self.bound_dim :] # noqa: E203 for i in range(self.bound_dim): - mu[2 * i] = np.cos(self.mu[i]) * np.exp(-self.C[i, i] / 2) # noqa: E203 - mu[2 * i + 1] = np.sin(self.mu[i]) * np.exp(-self.C[i, i] / 2) # noqa: E203 + mu[2 * i] = cos(self.mu[i]) * exp(-self.C[i, i] / 2) # noqa: E203 + mu[2 * i + 1] = sin(self.mu[i]) * exp(-self.C[i, i] / 2) # noqa: E203 return mu def hybrid_mean(self): @@ -113,7 +130,7 @@ def sample(self, n: int): """ assert n > 0, "n must be positive" s = np.random.multivariate_normal(self.mu, self.C, n) - s[:, : self.bound_dim] = np.mod(s[:, : self.bound_dim], 2 * np.pi) # noqa: E203 + s[:, : self.bound_dim] = mod(s[:, : self.bound_dim], 2 * np.pi) # noqa: E203 return s def to_gaussian(self): diff --git a/pyrecest/distributions/circle/abstract_circular_distribution.py b/pyrecest/distributions/circle/abstract_circular_distribution.py index bed6676a..181ca579 100644 --- a/pyrecest/distributions/circle/abstract_circular_distribution.py +++ b/pyrecest/distributions/circle/abstract_circular_distribution.py @@ -1,3 +1,8 @@ +from pyrecest.backend import sin +from pyrecest.backend import mod +from pyrecest.backend import linspace +from pyrecest.backend import cos +from pyrecest.backend import array import numbers import matplotlib.pyplot as plt @@ -28,7 +33,7 @@ def cdf_numerical(self, xs: np.ndarray, starting_point: float = 0.0) -> np.ndarr """ assert xs.ndim == 1, "xs must be a 1D array" - return np.array([self._cdf_numerical_single(x, starting_point) for x in xs]) + return array([self._cdf_numerical_single(x, starting_point) for x in xs]) @beartype def _cdf_numerical_single( @@ -37,8 +42,8 @@ def _cdf_numerical_single( starting_point: np.number | numbers.Real, ) -> np.number | numbers.Real: """Helper method for cdf_numerical""" - starting_point_mod = np.mod(starting_point, 2 * np.pi) - x_mod = np.mod(x, 2 * np.pi) + starting_point_mod = mod(starting_point, 2 * np.pi) + x_mod = mod(x, 2 * np.pi) if x_mod < starting_point_mod: return 1 - self.integrate_numerically([x_mod, starting_point_mod]) @@ -71,6 +76,6 @@ def to_wn(self): @staticmethod def plot_circle(*args, **kwargs): - theta = np.append(np.linspace(0, 2 * np.pi, 320), 0) - p = plt.plot(np.cos(theta), np.sin(theta), *args, **kwargs) + theta = np.append(linspace(0, 2 * np.pi, 320), 0) + p = plt.plot(cos(theta), sin(theta), *args, **kwargs) return p diff --git a/pyrecest/distributions/circle/circular_dirac_distribution.py b/pyrecest/distributions/circle/circular_dirac_distribution.py index d70d9200..b0736028 100644 --- a/pyrecest/distributions/circle/circular_dirac_distribution.py +++ b/pyrecest/distributions/circle/circular_dirac_distribution.py @@ -1,3 +1,5 @@ +from pyrecest.backend import squeeze +from pyrecest.backend import shape import numpy as np from beartype import beartype @@ -20,8 +22,8 @@ def __init__(self, d: np.ndarray, w: np.ndarray | None = None): super().__init__( d, w, dim=1 ) # Necessary so it is clear that the dimension is 1. - d = np.squeeze(d) - assert w is None or np.shape(d) == np.shape( + d = squeeze(d) + assert w is None or shape(d) == shape( w ), "The shapes of d and w should match." diff --git a/pyrecest/distributions/circle/circular_fourier_distribution.py b/pyrecest/distributions/circle/circular_fourier_distribution.py index e27fa09a..bbbdab68 100644 --- a/pyrecest/distributions/circle/circular_fourier_distribution.py +++ b/pyrecest/distributions/circle/circular_fourier_distribution.py @@ -1,3 +1,16 @@ +from pyrecest.backend import sum +from pyrecest.backend import sqrt +from pyrecest.backend import sin +from pyrecest.backend import real +from pyrecest.backend import linspace +from pyrecest.backend import imag +from pyrecest.backend import hstack +from pyrecest.backend import exp +from pyrecest.backend import cos +from pyrecest.backend import concatenate +from pyrecest.backend import arange +from pyrecest.backend import int64 +from pyrecest.backend import int32 import warnings import matplotlib.pyplot as plt @@ -96,10 +109,10 @@ def pdf(self, xs: np.ndarray) -> np.ndarray: xs = xs.reshape(-1, 1) a, b = self.get_a_b() - k_range = np.arange(1, a.shape[0]).astype(xs.dtype) - p = a[0] / 2 + np.sum( - a[1:].reshape(1, -1) * np.cos(xs * k_range) - + b.reshape(1, -1) * np.sin(xs * k_range), + k_range = arange(1, a.shape[0]).astype(xs.dtype) + p = a[0] / 2 + sum( + a[1:].reshape(1, -1) * cos(xs * k_range) + + b.reshape(1, -1) * sin(xs * k_range), axis=1, ) if self.multiplied_by_n: @@ -119,7 +132,7 @@ def normalize(self) -> "CircularFourierDistribution": if self.transformation == "identity": scale_factor = 1 / integral_value elif self.transformation == "sqrt": - scale_factor = 1 / np.sqrt(integral_value) + scale_factor = 1 / sqrt(integral_value) else: raise NotImplementedError("Transformation not supported.") @@ -137,7 +150,7 @@ def normalize(self) -> "CircularFourierDistribution": if self.transformation == "identity": scale_factor = 1 / integral_value elif self.transformation == "sqrt": - scale_factor = 1 / np.sqrt(integral_value) + scale_factor = 1 / sqrt(integral_value) else: raise NotImplementedError("Transformation not supported.") @@ -170,7 +183,7 @@ def integrate(self, integration_boundaries=None) -> float: a0_non_rooted = a[0] elif self.transformation == "sqrt": from_a0 = a[0] ** 2 * 0.5 - from_a1_to_end_and_b = np.sum(a[1:] ** 2) + np.sum(b**2) + from_a1_to_end_and_b = sum(a[1:] ** 2) + sum(b**2) a0_non_rooted = from_a0 + from_a1_to_end_and_b else: raise NotImplementedError("Transformation not supported.") @@ -178,18 +191,18 @@ def integrate(self, integration_boundaries=None) -> float: elif self.c is not None: if self.transformation == "identity": if self.multiplied_by_n: - c0 = np.real(self.c[0]) * (1 / self.n) + c0 = real(self.c[0]) * (1 / self.n) else: - c0 = np.real(self.c[0]) + c0 = real(self.c[0]) integral = 2 * np.pi * c0 elif self.transformation == "sqrt": if self.multiplied_by_n: c = self.c * (1 / self.n) else: c = self.c - from_c0 = (np.real(c[0])) ** 2 - from_c1_to_end = np.sum((np.real(c[1:])) ** 2) + np.sum( - (np.imag(c[1:])) ** 2 + from_c0 = (real(c[0])) ** 2 + from_c1_to_end = sum((real(c[1:])) ** 2) + sum( + (imag(c[1:])) ** 2 ) a0_non_rooted = 2 * from_c0 + 4 * from_c1_to_end @@ -202,13 +215,13 @@ def integrate(self, integration_boundaries=None) -> float: def plot_grid(self): grid_values = irfft(self.get_c(), self.n) - xs = np.linspace(0, 2 * np.pi, grid_values.shape[0], endpoint=False) + xs = linspace(0, 2 * np.pi, grid_values.shape[0], endpoint=False) vals = grid_values.squeeze() if self.transformation == "sqrt": p = vals**2 elif self.transformation == "log": - p = np.exp(vals) + p = exp(vals) elif self.transformation == "identity": p = vals else: @@ -219,12 +232,12 @@ def plot_grid(self): @beartype def plot(self, resolution=128, **kwargs): - xs = np.linspace(0, 2 * np.pi, resolution) + xs = linspace(0, 2 * np.pi, resolution) if self.a is not None: xs = xs.astype(self.a.dtype) else: - xs = xs.astype(np.real(self.c).dtype) + xs = xs.astype(real(self.c).dtype) pdf_vals = self.pdf(xs) @@ -238,8 +251,8 @@ def get_a_b(self) -> tuple[np.ndarray, np.ndarray]: a = self.a b = self.b elif self.c is not None: - a = 2 * np.real(self.c) - b = -2 * np.imag(self.c[1:]) + a = 2 * real(self.c) + b = -2 * imag(self.c[1:]) assert ( self.n is None or (np.size(a) + np.size(b)) == self.n ) # Other case not implemented yet! @@ -247,7 +260,7 @@ def get_a_b(self) -> tuple[np.ndarray, np.ndarray]: def get_c(self) -> np.ndarray: if self.a is not None: - c = (self.a[0] + 1j * np.hstack((0, self.b))) * 0.5 + c = (self.a[0] + 1j * hstack((0, self.b))) * 0.5 elif self.c is not None: c = self.c return c @@ -271,7 +284,7 @@ def get_full_c(self): neg_c = np.conj( self.c[-1:0:-1] ) # Create array for negative-frequency components - full_c = np.concatenate( + full_c = concatenate( [neg_c, self.c] ) # Concatenate arrays to get full spectrum return full_c @@ -280,7 +293,7 @@ def get_full_c(self): @beartype def from_distribution( distribution: AbstractCircularDistribution, - n: int | np.int32 | np.int64, + n: int | int32 | int64, transformation: str = "sqrt", store_values_multiplied_by_n: bool = True, ) -> "CircularFourierDistribution": @@ -295,12 +308,12 @@ def from_distribution( warnings.warn("Scaling up for WD (this is not recommended).") fd.c = fd.c * fd.n else: - xs = np.linspace(0, 2 * np.pi, n, endpoint=False) + xs = linspace(0, 2 * np.pi, n, endpoint=False) fvals = distribution.pdf(xs) if transformation == "identity": pass elif transformation == "sqrt": - fvals = np.sqrt(fvals) + fvals = sqrt(fvals) else: raise NotImplementedError("Transformation not supported.") fd = CircularFourierDistribution.from_function_values( diff --git a/pyrecest/distributions/circle/circular_mixture.py b/pyrecest/distributions/circle/circular_mixture.py index 8b6db068..449bf7ad 100644 --- a/pyrecest/distributions/circle/circular_mixture.py +++ b/pyrecest/distributions/circle/circular_mixture.py @@ -1,3 +1,5 @@ +from pyrecest.backend import sum +from pyrecest.backend import shape import collections import warnings @@ -32,7 +34,7 @@ def __init__( "All elements of 'dists' must be of type AbstractCircularDistribution." ) - if np.shape(dists) != np.shape(w): + if shape(dists) != shape(w): raise ValueError("'dists' and 'w' must have the same shape.") if all(isinstance(cd, CircularFourierDistribution) for cd in dists): @@ -45,4 +47,4 @@ def __init__( ) self.dists = dists - self.w = w / np.sum(w) + self.w = w / sum(w) diff --git a/pyrecest/distributions/circle/custom_circular_distribution.py b/pyrecest/distributions/circle/custom_circular_distribution.py index de11b0a8..00a4bda4 100644 --- a/pyrecest/distributions/circle/custom_circular_distribution.py +++ b/pyrecest/distributions/circle/custom_circular_distribution.py @@ -1,3 +1,5 @@ +from pyrecest.backend import mod +from pyrecest.backend import array from collections.abc import Callable import numpy as np @@ -40,7 +42,7 @@ def pdf(self, xs: np.ndarray): np.ndarray: The value of the pdf at xs. """ return AbstractCustomDistribution.pdf( - self, np.mod(xs + self.shift_by, 2 * np.pi) + self, mod(xs + self.shift_by, 2 * np.pi) ) @beartype @@ -56,5 +58,5 @@ def integrate(self, integration_boundaries: np.ndarray | None = None) -> float: float: The value of the integral. """ if integration_boundaries is None: - integration_boundaries = np.array([0, 2 * np.pi]) + integration_boundaries = array([0, 2 * np.pi]) return AbstractCircularDistribution.integrate(self, integration_boundaries) diff --git a/pyrecest/distributions/circle/von_mises_distribution.py b/pyrecest/distributions/circle/von_mises_distribution.py index f5afe125..141e6028 100644 --- a/pyrecest/distributions/circle/von_mises_distribution.py +++ b/pyrecest/distributions/circle/von_mises_distribution.py @@ -1,3 +1,15 @@ +from pyrecest.backend import where +from pyrecest.backend import sqrt +from pyrecest.backend import sin +from pyrecest.backend import real +from pyrecest.backend import mod +from pyrecest.backend import log +from pyrecest.backend import imag +from pyrecest.backend import exp +from pyrecest.backend import cos +from pyrecest.backend import arctan2 +from pyrecest.backend import abs +from pyrecest.backend import zeros_like import numbers import numpy as np @@ -34,7 +46,7 @@ def norm_const(self) -> np.number: @beartype def pdf(self, xs: np.ndarray) -> np.ndarray | np.number: - p = np.exp(self.kappa * np.cos(xs - self.mu)) / self.norm_const + p = exp(self.kappa * cos(xs - self.mu)) / self.norm_const return p @staticmethod @@ -60,12 +72,12 @@ def cdf(self, xs, starting_point=0): """ assert xs.ndim <= 1 - r = np.zeros_like(xs) + r = zeros_like(xs) def to_minus_pi_to_pi_range( angle: np.number | numbers.Real | np.ndarray, ) -> np.number | numbers.Real | np.ndarray: - return np.mod(angle + np.pi, 2 * np.pi) - np.pi + return mod(angle + np.pi, 2 * np.pi) - np.pi r = vonmises.cdf( to_minus_pi_to_pi_range(xs), @@ -77,7 +89,7 @@ def to_minus_pi_to_pi_range( loc=to_minus_pi_to_pi_range(self.mu), ) - r = np.where( + r = where( to_minus_pi_to_pi_range(xs) < to_minus_pi_to_pi_range(starting_point), 1 + r, r, @@ -98,15 +110,15 @@ def f(t: float) -> float: @beartype def multiply(self, vm2: "VonMisesDistribution") -> "VonMisesDistribution": - C = self.kappa * np.cos(self.mu) + vm2.kappa * np.cos(vm2.mu) - S = self.kappa * np.sin(self.mu) + vm2.kappa * np.sin(vm2.mu) - mu_ = np.mod(np.arctan2(S, C), 2 * np.pi) - kappa_ = np.sqrt(C**2 + S**2) + C = self.kappa * cos(self.mu) + vm2.kappa * cos(vm2.mu) + S = self.kappa * sin(self.mu) + vm2.kappa * sin(vm2.mu) + mu_ = mod(arctan2(S, C), 2 * np.pi) + kappa_ = sqrt(C**2 + S**2) return VonMisesDistribution(mu_, kappa_) @beartype def convolve(self, vm2: "VonMisesDistribution") -> "VonMisesDistribution": - mu_ = np.mod(self.mu + vm2.mu, 2 * np.pi) + mu_ = mod(self.mu + vm2.mu, 2 * np.pi) t = VonMisesDistribution.besselratio( 0, self.kappa ) * VonMisesDistribution.besselratio(0, vm2.kappa) @@ -114,7 +126,7 @@ def convolve(self, vm2: "VonMisesDistribution") -> "VonMisesDistribution": return VonMisesDistribution(mu_, kappa_) def entropy(self): - result = -self.kappa * VonMisesDistribution.besselratio(0, self.kappa) + np.log( + result = -self.kappa * VonMisesDistribution.besselratio(0, self.kappa) + log( 2 * np.pi * iv(0, self.kappa) ) return result @@ -130,8 +142,8 @@ def from_moment(m): Returns: vm (VMDistribution): VM distribution obtained by moment matching. """ - mu_ = np.mod(np.arctan2(np.imag(m), np.real(m)), 2 * np.pi) - kappa_ = VonMisesDistribution.besselratio_inverse(0, np.abs(m)) + mu_ = mod(arctan2(imag(m), real(m)), 2 * np.pi) + kappa_ = VonMisesDistribution.besselratio_inverse(0, abs(m)) vm = VonMisesDistribution(mu_, kappa_) return vm diff --git a/pyrecest/distributions/circle/wrapped_cauchy_distribution.py b/pyrecest/distributions/circle/wrapped_cauchy_distribution.py index 5ba09058..b88ee4a9 100644 --- a/pyrecest/distributions/circle/wrapped_cauchy_distribution.py +++ b/pyrecest/distributions/circle/wrapped_cauchy_distribution.py @@ -1,3 +1,11 @@ +from pyrecest.backend import tanh +from pyrecest.backend import tan +from pyrecest.backend import sinh +from pyrecest.backend import sin +from pyrecest.backend import mod +from pyrecest.backend import exp +from pyrecest.backend import cosh +from pyrecest.backend import cos import numpy as np from .abstract_circular_distribution import AbstractCircularDistribution @@ -6,27 +14,27 @@ class WrappedCauchyDistribution(AbstractCircularDistribution): def __init__(self, mu, gamma): AbstractCircularDistribution.__init__(self) - self.mu = np.mod(mu, 2 * np.pi) + self.mu = mod(mu, 2 * np.pi) assert gamma > 0 self.gamma = gamma def pdf(self, xs): assert xs.ndim == 1 - xs = np.mod(xs - self.mu, 2 * np.pi) + xs = mod(xs - self.mu, 2 * np.pi) return ( 1 / (2 * np.pi) - * np.sinh(self.gamma) - / (np.cosh(self.gamma) - np.cos(xs - self.mu)) + * sinh(self.gamma) + / (cosh(self.gamma) - cos(xs - self.mu)) ) def cdf(self, xs): def coth(x): - return 1 / np.tanh(x) + return 1 / tanh(x) assert xs.ndim == 1 - return np.arctan(coth(self.gamma / 2) * np.tan((xs - self.mu) / 2)) / np.pi + return np.arctan(coth(self.gamma / 2) * tan((xs - self.mu) / 2)) / np.pi def trigonometric_moment(self, n): - m = np.exp(1j * n * self.mu - abs(n) * self.gamma) + m = exp(1j * n * self.mu - abs(n) * self.gamma) return m diff --git a/pyrecest/distributions/circle/wrapped_laplace_distribution.py b/pyrecest/distributions/circle/wrapped_laplace_distribution.py index b717ef7c..45bede0d 100644 --- a/pyrecest/distributions/circle/wrapped_laplace_distribution.py +++ b/pyrecest/distributions/circle/wrapped_laplace_distribution.py @@ -1,3 +1,6 @@ +from pyrecest.backend import ndim +from pyrecest.backend import mod +from pyrecest.backend import exp import numpy as np from .abstract_circular_distribution import AbstractCircularDistribution @@ -21,17 +24,17 @@ def trigonometric_moment(self, n): ) def pdf(self, xs): - assert np.ndim(xs) <= 1 - xs = np.mod(xs, 2 * np.pi) + assert ndim(xs) <= 1 + xs = mod(xs, 2 * np.pi) p = ( self.lambda_ * self.kappa / (1 + self.kappa**2) * ( - np.exp(-self.lambda_ * self.kappa * xs) - / (1 - np.exp(-2 * np.pi * self.lambda_ * self.kappa)) - + np.exp(self.lambda_ / self.kappa * xs) - / (np.exp(2 * np.pi * self.lambda_ / self.kappa) - 1) + exp(-self.lambda_ * self.kappa * xs) + / (1 - exp(-2 * np.pi * self.lambda_ * self.kappa)) + + exp(self.lambda_ / self.kappa * xs) + / (exp(2 * np.pi * self.lambda_ / self.kappa) - 1) ) ) return p diff --git a/pyrecest/distributions/circle/wrapped_normal_distribution.py b/pyrecest/distributions/circle/wrapped_normal_distribution.py index 8a728e4f..0f1282b5 100644 --- a/pyrecest/distributions/circle/wrapped_normal_distribution.py +++ b/pyrecest/distributions/circle/wrapped_normal_distribution.py @@ -1,3 +1,15 @@ +from pyrecest.backend import where +from pyrecest.backend import squeeze +from pyrecest.backend import sqrt +from pyrecest.backend import ndim +from pyrecest.backend import mod +from pyrecest.backend import log +from pyrecest.backend import exp +from pyrecest.backend import array +from pyrecest.backend import abs +from pyrecest.backend import int64 +from pyrecest.backend import int32 +from pyrecest.backend import zeros import numbers import numpy as np @@ -34,7 +46,7 @@ def __init__( @property def sigma(self): - return np.sqrt(self.C) + return sqrt(self.C) @beartype def pdf(self, xs: np.ndarray | np.number | numbers.Real): @@ -42,28 +54,28 @@ def pdf(self, xs: np.ndarray | np.number | numbers.Real): raise ValueError(f"sigma must be >0, but received {self.sigma}.") xs = np.asarray(xs) - if np.ndim(xs) == 0: - xs = np.array([xs]) + if ndim(xs) == 0: + xs = array([xs]) n_inputs = np.size(xs) - result = np.zeros(n_inputs) + result = zeros(n_inputs) # check if sigma is large and return uniform distribution in this case if self.sigma > self.MAX_SIGMA_BEFORE_UNIFORM: result[:] = 1.0 / (2 * np.pi) return result - x = np.mod(xs, 2 * np.pi) + x = mod(xs, 2 * np.pi) x[x < 0] += 2 * np.pi x -= self.mu max_iterations = 1000 tmp = -1.0 / (2 * self.sigma**2) - nc = 1 / np.sqrt(2 * np.pi) / self.sigma + nc = 1 / sqrt(2 * np.pi) / self.sigma for i in range(n_inputs): old_result = 0 - result[i] = np.exp(x[i] * x[i] * tmp) + result[i] = exp(x[i] * x[i] * tmp) for k in range(1, max_iterations + 1): xp = x[i] + 2 * np.pi * k @@ -71,7 +83,7 @@ def pdf(self, xs: np.ndarray | np.number | numbers.Real): tp = xp * xp * tmp tm = xm * xm * tmp old_result = result[i] - result[i] += np.exp(tp) + np.exp(tm) + result[i] += exp(tp) + exp(tm) if result[i] == old_result: break @@ -85,18 +97,18 @@ def cdf( self, xs: np.ndarray, startingPoint: float = 0, - n_wraps: int | np.int32 | np.int64 = 10, + n_wraps: int | int32 | int64 = 10, ) -> np.ndarray: - startingPoint = np.mod(startingPoint, 2 * np.pi) - xs = np.mod(xs, 2 * np.pi) + startingPoint = mod(startingPoint, 2 * np.pi) + xs = mod(xs, 2 * np.pi) def ncdf(from_, to): return ( 1 / 2 * ( - erf((self.mu - from_) / (np.sqrt(2) * self.sigma)) - - erf((self.mu - to) / (np.sqrt(2) * self.sigma)) + erf((self.mu - from_) / (sqrt(2) * self.sigma)) + - erf((self.mu - to) / (sqrt(2) * self.sigma)) ) ) @@ -108,14 +120,14 @@ def ncdf(from_, to): + ncdf(startingPoint - 2 * np.pi * i, xs - 2 * np.pi * i) ) # Val should be negative when x < startingPoint - val = np.where(xs < startingPoint, 1 + val, val) - return np.squeeze(val) + val = where(xs < startingPoint, 1 + val, val) + return squeeze(val) @beartype def trigonometric_moment( - self, n: int | np.int32 | np.int64 + self, n: int | int32 | int64 ) -> complex | np.ndarray: - return np.exp(1j * n * self.mu - n**2 * self.sigma**2 / 2) + return exp(1j * n * self.mu - n**2 * self.sigma**2 / 2) def multiply( self, other: "WrappedNormalDistribution" @@ -130,8 +142,8 @@ def multiply_vm(self, other): return wn @beartype - def sample(self, n: int | np.int32 | np.int64) -> np.ndarray: - return np.mod(self.mu + self.sigma * np.random.randn(1, n), 2 * np.pi) + def sample(self, n: int | int32 | int64) -> np.ndarray: + return mod(self.mu + self.sigma * np.random.randn(1, n), 2 * np.pi) @beartype def shift(self, shift_by): @@ -145,8 +157,8 @@ def to_vm(self) -> VonMisesDistribution: @staticmethod def from_moment(m: complex) -> "WrappedNormalDistribution": - mu = np.mod(np.angle(m), 2 * np.pi) - sigma = np.sqrt(-2 * np.log(np.abs(m))) + mu = mod(np.angle(m), 2 * np.pi) + sigma = sqrt(-2 * log(abs(m))) return WrappedNormalDistribution(mu, sigma) @staticmethod diff --git a/pyrecest/distributions/disk_uniform_distribution.py b/pyrecest/distributions/disk_uniform_distribution.py index 5642f622..d7d944c3 100644 --- a/pyrecest/distributions/disk_uniform_distribution.py +++ b/pyrecest/distributions/disk_uniform_distribution.py @@ -1,3 +1,5 @@ +from pyrecest.backend import eye +from pyrecest.backend import array import numpy as np from .abstract_disk_distribution import AbstractDiskDistribution @@ -19,4 +21,4 @@ def __init__(self): The center of the disk is at [0, 0] and the shape matrix of the ellipsoid is an identity covariance matrix. """ AbstractDiskDistribution.__init__(self) - EllipsoidalBallUniformDistribution.__init__(self, np.array([0, 0]), np.eye(2)) + EllipsoidalBallUniformDistribution.__init__(self, array([0, 0]), eye(2)) diff --git a/pyrecest/distributions/ellipsoidal_ball_uniform_distribution.py b/pyrecest/distributions/ellipsoidal_ball_uniform_distribution.py index 1bdeb194..eeff5efc 100644 --- a/pyrecest/distributions/ellipsoidal_ball_uniform_distribution.py +++ b/pyrecest/distributions/ellipsoidal_ball_uniform_distribution.py @@ -1,3 +1,9 @@ +from pyrecest.backend import sqrt +from pyrecest.backend import power +from pyrecest.backend import dot +from pyrecest.backend import int64 +from pyrecest.backend import int32 +from pyrecest.backend import zeros import numpy as np from beartype import beartype @@ -38,19 +44,19 @@ def pdf(self, xs: np.ndarray): """ assert xs.shape[-1] == self.dim # Calculate the reciprocal of the volume of the ellipsoid - # reciprocal_volume = 1 / (np.power(np.pi, self.dim / 2) * np.sqrt(np.linalg.det(self.shape_matrix)) / gamma(self.dim / 2 + 1)) + # reciprocal_volume = 1 / (power(np.pi, self.dim / 2) * sqrt(np.linalg.det(self.shape_matrix)) / gamma(self.dim / 2 + 1)) reciprocal_volume = 1 / self.get_manifold_size() if xs.ndim == 1: return reciprocal_volume n = xs.shape[0] - results = np.zeros(n) + results = zeros(n) # Check if points are inside the ellipsoid for i in range(n): point = xs[i, :] diff = point - self.center - result = np.dot(diff.T, np.linalg.solve(self.shape_matrix, diff)) + result = dot(diff.T, np.linalg.solve(self.shape_matrix, diff)) # If the point is inside the ellipsoid, store the reciprocal of the volume as the pdf value if result <= 1: @@ -59,7 +65,7 @@ def pdf(self, xs: np.ndarray): return results @beartype - def sample(self, n: int | np.int32 | np.int64) -> np.ndarray: + def sample(self, n: int | int32 | int64) -> np.ndarray: """ Generate samples from the distribution. diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py index 1608956f..6f4334be 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py @@ -1,3 +1,11 @@ +from pyrecest.backend import vstack +from pyrecest.backend import ones +from pyrecest.backend import meshgrid +from pyrecest.backend import linspace +from pyrecest.backend import concatenate +from pyrecest.backend import int64 +from pyrecest.backend import int32 +from pyrecest.backend import zeros import warnings from collections.abc import Callable @@ -27,9 +35,9 @@ def mean(self) -> np.ndarray: @beartype def sample_metropolis_hastings( self, - n: int | np.int32 | np.int64, - burn_in: int | np.int32 | np.int64 = 10, - skipping: int | np.int32 | np.int64 = 5, + n: int | int32 | int64, + burn_in: int | int32 | int64 = 10, + skipping: int | int32 | int64 = 5, proposal: Callable | None = None, start_point: np.ndarray | None = None, ) -> np.ndarray: @@ -65,8 +73,8 @@ def mean_direction_numerical(self) -> np.ndarray: elif self.dim <= 3: mu = super().mean_direction_numerical( [ - np.zeros(self.dim), - [2 * np.pi, *np.pi * np.ones(self.dim - 2), np.pi / 2], + zeros(self.dim), + [2 * np.pi, *np.pi * ones(self.dim - 2), np.pi / 2], ] ) else: @@ -90,15 +98,15 @@ def mean_direction_numerical(self) -> np.ndarray: @beartype @staticmethod - def get_full_integration_boundaries(dim: int | np.int32 | np.int64) -> np.ndarray: + def get_full_integration_boundaries(dim: int | int32 | int64) -> np.ndarray: if dim == 1: integration_boundaries = [0, np.pi] else: - integration_boundaries = np.vstack( + integration_boundaries = vstack( ( - np.zeros(dim), - np.concatenate( - ([2 * np.pi], np.pi * np.ones(dim - 2), [np.pi / 2]) + zeros(dim), + concatenate( + ([2 * np.pi], np.pi * ones(dim - 2), [np.pi / 2]) ), ) ).T @@ -129,7 +137,7 @@ def integrate_numerically( @beartype @staticmethod def integrate_fun_over_domain( - f_hypersph_coords: Callable, dim: int | np.int32 | np.int64 + f_hypersph_coords: Callable, dim: int | int32 | int64 ) -> float: integration_boundaries = ( AbstractHyperhemisphericalDistribution.get_full_integration_boundaries(dim) @@ -160,11 +168,11 @@ def objective_function_2d(s): @beartype @staticmethod - def plot_hemisphere(resolution: int | np.int32 | np.int64 = 150): - x, y, z = np.meshgrid( - np.linspace(-1, 1, resolution), - np.linspace(-1, 1, resolution), - np.linspace(0, 1, resolution // 2), + def plot_hemisphere(resolution: int | int32 | int64 = 150): + x, y, z = meshgrid( + linspace(-1, 1, resolution), + linspace(-1, 1, resolution), + linspace(0, 1, resolution // 2), ) mask = (x**2 + y**2 + z**2 <= 1) & (z >= 0) x, y, z = x[mask].reshape(-1, 1), y[mask].reshape(-1, 1), z[mask].reshape(-1, 1) diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_dirac_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_dirac_distribution.py index 31b88ef9..878fa9b4 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_dirac_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_dirac_distribution.py @@ -1,3 +1,5 @@ +from pyrecest.backend import sum +from pyrecest.backend import log import numpy as np from ..abstract_dirac_distribution import AbstractDiracDistribution @@ -18,7 +20,7 @@ def moment(self): return m def entropy(self): - result = -np.sum(self.w * np.log(self.w)) + result = -sum(self.w * log(self.w)) return result def integrate(self, integration_boundaries=None): diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py index 676d6d8e..b7ea7a84 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py @@ -1,3 +1,13 @@ +from pyrecest.backend import sort +from pyrecest.backend import squeeze +from pyrecest.backend import sqrt +from pyrecest.backend import sin +from pyrecest.backend import log +from pyrecest.backend import cos +from pyrecest.backend import abs +from pyrecest.backend import int64 +from pyrecest.backend import int32 +from pyrecest.backend import zeros from abc import abstractmethod from collections.abc import Callable @@ -20,7 +30,7 @@ def mean_direction(self): @staticmethod @abstractmethod @beartype - def get_full_integration_boundaries(dim: int | np.int32 | np.int64): + def get_full_integration_boundaries(dim: int | int32 | int64): pass def mean_direction_numerical(self, integration_boundaries=None): @@ -82,22 +92,22 @@ def gen_pdf_hyperspherical_coords(self): @staticmethod @beartype - def gen_fun_hyperspherical_coords(f: Callable, dim: int | np.int32 | np.int64): + def gen_fun_hyperspherical_coords(f: Callable, dim: int | int32 | int64): def generate_input(angles): dim_eucl = dim + 1 angles = np.column_stack(angles) - input_arr = np.zeros((angles.shape[0], dim_eucl)) + input_arr = zeros((angles.shape[0], dim_eucl)) # Start at last, which is just cos - input_arr[:, -1] = np.cos(angles[:, -1]) - sin_product = np.sin(angles[:, -1]) + input_arr[:, -1] = cos(angles[:, -1]) + sin_product = sin(angles[:, -1]) # Now, iterate over all from end to back and accumulate the sines for i in range(2, dim_eucl): # All except the final one have a cos factor as their last one - input_arr[:, -i] = sin_product * np.cos(angles[:, -i]) - sin_product *= np.sin(angles[:, -i]) + input_arr[:, -i] = sin_product * cos(angles[:, -i]) + sin_product *= sin(angles[:, -i]) # The last one is all sines input_arr[:, 0] = sin_product - return np.squeeze(input_arr) + return squeeze(input_arr) def fangles(*angles): input_arr = generate_input(angles) @@ -133,7 +143,7 @@ def g_1d(phi): if dim == 2: def g_2d(phi1, phi2): - return f_hypersph_coords(phi1, phi2) * np.sin(phi2) + return f_hypersph_coords(phi1, phi2) * sin(phi2) return g_2d if dim == 3: @@ -141,8 +151,8 @@ def g_2d(phi1, phi2): def g_3d(phi1, phi2, phi3): return ( f_hypersph_coords(phi1, phi2, phi3) - * np.sin(phi2) - * np.sin(phi3) ** 2 + * sin(phi2) + * sin(phi3) ** 2 ) return g_3d @@ -162,7 +172,7 @@ def g_3d(phi1, phi2, phi3): @beartype def _compute_mean_axis_from_moment(moment_matrix: np.ndarray) -> np.ndarray: D, V = np.linalg.eig(moment_matrix) - Dsorted = np.sort(D) + Dsorted = sort(D) Vsorted = V[:, D.argsort()] if abs(Dsorted[-1] / Dsorted[-2]) < 1.01: print("Eigenvalues are very similar. Axis may be unreliable.") @@ -194,7 +204,7 @@ def integrate(self, integration_boundaries: np.ndarray | None = None): @abstractmethod @beartype def integrate_fun_over_domain( - f_hypersph_coords: Callable, dim: int | np.int32 | np.int64 + f_hypersph_coords: Callable, dim: int | int32 | int64 ): # Overwrite with a function that specifies the integration_boundaries for the type of HypersphereSubsetDistribution pass @@ -203,7 +213,7 @@ def integrate_fun_over_domain( @beartype def integrate_fun_over_domain_part( f_hypersph_coords: Callable, - dim: int | np.int32 | np.int64, + dim: int | int32 | int64, integration_boundaries, ): if dim == 1: @@ -216,7 +226,7 @@ def integrate_fun_over_domain_part( elif dim == 2: def g_2d(phi1, phi2): - return f_hypersph_coords(phi1, phi2) * np.sin(phi2) + return f_hypersph_coords(phi1, phi2) * sin(phi2) i, _ = nquad( g_2d, @@ -228,8 +238,8 @@ def g_2d(phi1, phi2): def g_3d(phi1, phi2, phi3): return ( f_hypersph_coords(phi1, phi2, phi3) - * np.sin(phi2) - * (np.sin(phi3)) ** 2 + * sin(phi2) + * (sin(phi3)) ** 2 ) i, _ = nquad( @@ -262,7 +272,7 @@ def mode_numerical(self): def entropy_numerical(self): def entropy_f_gen(): def f(points): - return self.pdf(points) * np.log(self.pdf(points)) + return self.pdf(points) * log(self.pdf(points)) return f @@ -295,7 +305,7 @@ def hellinger_distance_numerical(self, other, integration_boundaries=None): ), "Cannot compare distributions with different number of dimensions" def hellinger_distance(pdf1, pdf2): - return (np.sqrt(pdf1) - np.sqrt(pdf2)) ** 2 + return (sqrt(pdf1) - sqrt(pdf2)) ** 2 f_hellinger = self._distance_f_gen(other, hellinger_distance) fangles_hellinger = ( @@ -320,7 +330,7 @@ def total_variation_distance_numerical(self, other, integration_boundaries=None) ), "Cannot compare distributions with different number of dimensions" def total_variation_distance(pdf1, pdf2): - return np.abs(pdf1 - pdf2) + return abs(pdf1 - pdf2) f_total_variation = self._distance_f_gen(other, total_variation_distance) fangles_total_variation = ( @@ -340,23 +350,23 @@ def total_variation_distance(pdf1, pdf2): def polar_to_cart(polar_coords: np.ndarray) -> np.ndarray: polar_coords = np.atleast_2d(polar_coords) - coords = np.zeros( + coords = zeros( ( polar_coords.shape[0], polar_coords.shape[1] + 1, ) ) - coords[:, 0] = np.sin(polar_coords[:, 0]) * np.cos(polar_coords[:, 1]) - coords[:, 1] = np.sin(polar_coords[:, 0]) * np.sin(polar_coords[:, 1]) - coords[:, 2] = np.cos(polar_coords[:, 0]) + coords[:, 0] = sin(polar_coords[:, 0]) * cos(polar_coords[:, 1]) + coords[:, 1] = sin(polar_coords[:, 0]) * sin(polar_coords[:, 1]) + coords[:, 2] = cos(polar_coords[:, 0]) for i in range(2, polar_coords.shape[1]): - coords[:, :-i] *= np.sin(polar_coords[:, i]) # noqa: E203 - coords[:, -i] = np.cos(polar_coords[:, i]) - return np.squeeze(coords) + coords[:, :-i] *= sin(polar_coords[:, i]) # noqa: E203 + coords[:, -i] = cos(polar_coords[:, i]) + return squeeze(coords) @staticmethod @beartype - def compute_unit_hypersphere_surface(dim: int | np.int32 | np.int64) -> float: + def compute_unit_hypersphere_surface(dim: int | int32 | int64) -> float: if dim == 1: surface_area = 2 * np.pi elif dim == 2: diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_uniform_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_uniform_distribution.py index 3d21350a..47f53668 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_uniform_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_uniform_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import ones import numpy as np from beartype import beartype @@ -32,5 +33,5 @@ def pdf(self, xs: np.ndarray) -> np.ndarray: raise ValueError("Manifold size cannot be zero.") if not isinstance(manifold_size, (int, float)): raise TypeError("Manifold size must be a numeric value.") - p = (1 / manifold_size) * np.ones(xs.size // (self.dim + 1)) + p = (1 / manifold_size) * ones(xs.size // (self.dim + 1)) return p diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py index f7b9f267..ff8eba8e 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py @@ -1,3 +1,14 @@ +from pyrecest.backend import vstack +from pyrecest.backend import sin +from pyrecest.backend import ones +from pyrecest.backend import meshgrid +from pyrecest.backend import linspace +from pyrecest.backend import cos +from pyrecest.backend import concatenate +from pyrecest.backend import array +from pyrecest.backend import int64 +from pyrecest.backend import int32 +from pyrecest.backend import zeros from collections.abc import Callable import matplotlib.pyplot as plt @@ -29,9 +40,9 @@ def mean(self): @beartype def sample_metropolis_hastings( self, - n: int | np.int32 | np.int64, - burn_in: int | np.int32 | np.int64 = 10, - skipping: int | np.int32 | np.int64 = 5, + n: int | int32 | int64, + burn_in: int | int32 | int64 = 10, + skipping: int | int32 | int64 = 5, proposal: Callable | None = None, start_point: np.ndarray | None = None, ) -> np.ndarray: @@ -73,12 +84,12 @@ def proposal(_): @beartype def plot( self, - faces: int | np.int32 | np.int64 = 100, - grid_faces: int | np.int32 | np.int64 = 20, + faces: int | int32 | int64 = 100, + grid_faces: int | int32 | int64 = 20, ) -> None: if self.dim == 1: - phi = np.linspace(0, 2 * np.pi, 320) - x = np.array([np.sin(phi), np.cos(phi)]) + phi = linspace(0, 2 * np.pi, 320) + x = array([sin(phi), cos(phi)]) p = self.pdf(x) plt.plot(phi, p) plt.show() @@ -90,7 +101,7 @@ def plot( x_sphere_inner, y_sphere_inner, z_sphere_inner = self.create_sphere(faces) c_sphere = self.pdf( - np.array( + array( [ x_sphere_inner.flatten(), y_sphere_inner.flatten(), @@ -149,10 +160,10 @@ def get_full_integration_boundaries(dim): if dim == 1: return [0, 2 * np.pi] - return np.vstack( + return vstack( ( - np.zeros(dim), - np.concatenate(([2 * np.pi], np.pi * np.ones(dim - 1))), + zeros(dim), + concatenate(([2 * np.pi], np.pi * ones(dim - 1))), ) ).T @@ -203,9 +214,9 @@ def create_sphere(faces): 0.0 : np.pi : complex(0, faces), # noqa: E203 0.0 : 2.0 * np.pi : complex(0, faces), # noqa: E203 ] - x = np.sin(phi) * np.cos(theta) - y = np.sin(phi) * np.sin(theta) - z = np.cos(phi) + x = sin(phi) * cos(theta) + y = sin(phi) * sin(theta) + z = cos(phi) return x, y, z @staticmethod @@ -223,16 +234,16 @@ def plot_unit_sphere(): num_points = 1000 # Generate theta and phi angles (in radians) - theta = np.linspace(0, 2 * np.pi, num_points) - phi = np.linspace(0, np.pi, num_points) + theta = linspace(0, 2 * np.pi, num_points) + phi = linspace(0, np.pi, num_points) # Create a meshgrid for theta and phi angles - theta, phi = np.meshgrid(theta, phi) + theta, phi = meshgrid(theta, phi) # Calculate the x, y, and z coordinates - x = np.sin(phi) * np.cos(theta) - y = np.sin(phi) * np.sin(theta) - z = np.cos(phi) + x = sin(phi) * cos(theta) + y = sin(phi) * sin(theta) + z = cos(phi) # Plot the unit circle in 3D space fig = plt.figure() diff --git a/pyrecest/distributions/hypersphere_subset/abstract_sphere_subset_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_sphere_subset_distribution.py index 007f2ba5..87c87186 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_sphere_subset_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_sphere_subset_distribution.py @@ -1,3 +1,9 @@ +from pyrecest.backend import where +from pyrecest.backend import sin +from pyrecest.backend import ndim +from pyrecest.backend import cos +from pyrecest.backend import arctan2 +from pyrecest.backend import arccos import numpy as np from beartype import beartype @@ -31,7 +37,7 @@ def sph_to_cart(phi: np.ndarray, theta: np.ndarray, mode="colatitude") -> tuple: Returns: tuple: Cartesian coordinates. """ - assert np.ndim(phi) == 1 and np.ndim(theta) == 1, "Inputs must be 1-dimensional" + assert ndim(phi) == 1 and ndim(theta) == 1, "Inputs must be 1-dimensional" if mode == "colatitude": x, y, z = AbstractSphereSubsetDistribution._sph_to_cart_colatitude( phi, theta @@ -62,7 +68,7 @@ def cart_to_sph( tuple: Spherical coordinates. """ assert ( - np.ndim(x) == 1 and np.ndim(y) == 1 and np.ndim(z) + ndim(x) == 1 and ndim(y) == 1 and ndim(z) ), "Inputs must be 1-dimensional" if mode == "colatitude": phi, theta = AbstractSphereSubsetDistribution._cart_to_sph_colatitude( @@ -80,12 +86,12 @@ def cart_to_sph( @staticmethod @beartype def _sph_to_cart_colatitude(azimuth: np.ndarray, colatitude: np.ndarray) -> tuple: - assert np.ndim(azimuth) == 1 and np.ndim( + assert ndim(azimuth) == 1 and ndim( colatitude ), "Inputs must be 1-dimensional" - x = np.sin(colatitude) * np.cos(azimuth) - y = np.sin(colatitude) * np.sin(azimuth) - z = np.cos(colatitude) + x = sin(colatitude) * cos(azimuth) + y = sin(colatitude) * sin(azimuth) + z = cos(colatitude) return x, y, z @staticmethod @@ -103,31 +109,31 @@ def _sph_to_cart_elevation(azimuth: np.ndarray, elevation: np.ndarray) -> tuple: tuple: Cartesian coordinates. """ assert ( - np.ndim(azimuth) == 1 and np.ndim(elevation) == 1 + ndim(azimuth) == 1 and ndim(elevation) == 1 ), "Inputs must be 1-dimensional" # elevation is π/2 - colatitude, so we calculate colatitude from elevation colatitude = np.pi / 2 - elevation - x = np.sin(colatitude) * np.cos(azimuth) - y = np.sin(colatitude) * np.sin(azimuth) - z = np.cos(colatitude) + x = sin(colatitude) * cos(azimuth) + y = sin(colatitude) * sin(azimuth) + z = cos(colatitude) return x, y, z @staticmethod @beartype def _cart_to_sph_colatitude(x: np.ndarray, y: np.ndarray, z: np.ndarray) -> tuple: - assert np.ndim(x) == 1 and np.ndim(y) == 1 and np.ndim(z) + assert ndim(x) == 1 and ndim(y) == 1 and ndim(z) radius = 1 - azimuth = np.arctan2(y, x) - azimuth = np.where(azimuth < 0, azimuth + 2 * np.pi, azimuth) - colatitude = np.arccos(z / radius) + azimuth = arctan2(y, x) + azimuth = where(azimuth < 0, azimuth + 2 * np.pi, azimuth) + colatitude = arccos(z / radius) return azimuth, colatitude @staticmethod @beartype def _cart_to_sph_elevation(x: np.ndarray, y: np.ndarray, z: np.ndarray) -> tuple: - assert np.ndim(x) == 1 and np.ndim(y) == 1 and np.ndim(z) == 1 + assert ndim(x) == 1 and ndim(y) == 1 and ndim(z) == 1 radius = 1 - azimuth = np.arctan2(y, x) - azimuth = np.where(azimuth < 0, azimuth + 2 * np.pi, azimuth) - elevation = np.pi / 2 - np.arccos(z / radius) # elevation is π/2 - colatitude + azimuth = arctan2(y, x) + azimuth = where(azimuth < 0, azimuth + 2 * np.pi, azimuth) + elevation = np.pi / 2 - arccos(z / radius) # elevation is π/2 - colatitude return azimuth, elevation diff --git a/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py index 08dfe722..4fb2b11d 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py @@ -1,3 +1,10 @@ +from pyrecest.backend import sqrt +from pyrecest.backend import real +from pyrecest.backend import isnan +from pyrecest.backend import imag +from pyrecest.backend import array +from pyrecest.backend import abs +from pyrecest.backend import zeros import copy import warnings @@ -23,12 +30,12 @@ def __init__(self, coeff_mat, transformation="identity"): coeff_mat = coeff_mat + np.block( [ [ - np.zeros((n - 1, 1)), + zeros((n - 1, 1)), np.kron( - np.triu(np.full((n - 1, n - 1), np.nan)), np.array([[1, 1]]) + np.triu(np.full((n - 1, n - 1), np.nan)), array([[1, 1]]) ), ], - [np.zeros((1, 2 * n - 1))], + [zeros((1, 2 * n - 1))], ] ) AbstractOrthogonalBasisDistribution.__init__(self, coeff_mat, transformation) @@ -44,12 +51,12 @@ def normalize_in_place(self): "This can either be caused by a user error or due to negativity caused by " "non-square rooted version" ) - elif np.abs(int_val) < 1e-12: + elif abs(int_val) < 1e-12: raise ValueError( "Normalization:almostZero - Coefficient for first degree is too close to zero, " "this usually points to a user error" ) - elif np.abs(int_val - 1) > 1e-5: + elif abs(int_val - 1) > 1e-5: warnings.warn( "Warning: Normalization:notNormalized - Coefficients apparently do not belong " "to normalized density. Normalizing..." @@ -60,20 +67,20 @@ def normalize_in_place(self): if self.transformation == "identity": self.coeff_mat = self.coeff_mat / int_val elif self.transformation == "sqrt": - self.coeff_mat = self.coeff_mat / np.sqrt(int_val) + self.coeff_mat = self.coeff_mat / sqrt(int_val) else: warnings.warn("Warning: Currently cannot normalize") def integrate(self): if self.transformation == "identity": - int_val = self.coeff_mat[0, 0] * np.sqrt(4 * np.pi) + int_val = self.coeff_mat[0, 0] * sqrt(4 * np.pi) elif self.transformation == "sqrt": - int_val = norm(self.coeff_mat[~np.isnan(self.coeff_mat)]) ** 2 + int_val = norm(self.coeff_mat[~isnan(self.coeff_mat)]) ** 2 else: raise ValueError("No analytical formula for normalization available") - assert np.abs(np.imag(int_val) < 1e-8) - return np.real(int_val) + assert abs(imag(int_val) < 1e-8) + return real(int_val) def truncate(self, degree): result = copy.deepcopy(self) @@ -83,7 +90,7 @@ def truncate(self, degree): ] # noqa: E203 elif result.coeff_mat.shape[0] - 1 < degree: warnings.warn("Less coefficients than desired, filling up with zeros") - new_coeff_mat = np.zeros( + new_coeff_mat = zeros( (degree + 1, 2 * degree + 1), dtype=self.coeff_mat.dtype ) new_coeff_mat[ diff --git a/pyrecest/distributions/hypersphere_subset/bingham_distribution.py b/pyrecest/distributions/hypersphere_subset/bingham_distribution.py index a848f0ae..bde76db7 100644 --- a/pyrecest/distributions/hypersphere_subset/bingham_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/bingham_distribution.py @@ -1,3 +1,8 @@ +from pyrecest.backend import sum +from pyrecest.backend import eye +from pyrecest.backend import exp +from pyrecest.backend import all +from pyrecest.backend import abs import numpy as np from scipy.integrate import quad from scipy.special import iv @@ -13,12 +18,12 @@ def __init__(self, Z: np.ndarray, M: np.ndarray): assert Z.shape[0] == self.input_dim, "Z has wrong length" assert Z.ndim == 1, "Z needs to be a 1-D vector" assert Z[-1] == 0, "Last entry of Z needs to be zero" - assert np.all(Z[:-1] <= Z[1:]), "Values in Z have to be ascending" + assert all(Z[:-1] <= Z[1:]), "Values in Z have to be ascending" # Verify that M is orthogonal epsilon = 0.001 assert ( - np.max(np.abs(M @ M.T - np.eye(self.dim + 1))) < epsilon + np.max(abs(M @ M.T - eye(self.dim + 1))) < epsilon ), "M is not orthogonal" self.Z = Z @@ -50,7 +55,7 @@ def J(Z, u): ) def ifun(u): - return J(Z, u) * np.exp( + return J(Z, u) * exp( 0.5 * (Z[0] + Z[1]) * u + 0.5 * (Z[2] + Z[3]) * (1 - u) ) @@ -60,7 +65,7 @@ def pdf(self, xs): assert xs.shape[-1] == self.dim + 1 C = self.M @ np.diag(self.Z) @ self.M.T - p = 1 / self.F * np.exp(np.sum(xs.T * (C @ xs.T), axis=0)) + p = 1 / self.F * exp(sum(xs.T * (C @ xs.T), axis=0)) return p def mean_direction(self): @@ -98,11 +103,11 @@ def dF(self): def calculate_dF(self): dim = self.Z.shape[0] # Assuming Z is a property of the object - dF = np.zeros(dim) + dF = zeros(dim) epsilon = 0.001 for i in range(dim): # Using finite differences - dZ = np.zeros(dim) + dZ = zeros(dim) dZ[i] = epsilon F1 = self.calculate_F(self.Z + dZ) F2 = self.calculate_F(self.Z - dZ) @@ -119,7 +124,7 @@ def moment(self): """ D = np.diag(self.dF / self.F) # It should already be normalized, but numerical inaccuracies can lead to values unequal to 1 - D = D / np.sum(np.diag(D)) + D = D / sum(np.diag(D)) S = self.M @ D @ self.M.T S = (S + S.T) / 2 # Enforce symmetry return S diff --git a/pyrecest/distributions/hypersphere_subset/custom_hyperhemispherical_distribution.py b/pyrecest/distributions/hypersphere_subset/custom_hyperhemispherical_distribution.py index ad2c9b61..d097536e 100644 --- a/pyrecest/distributions/hypersphere_subset/custom_hyperhemispherical_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/custom_hyperhemispherical_distribution.py @@ -1,3 +1,5 @@ +from pyrecest.backend import int64 +from pyrecest.backend import int32 from collections.abc import Callable import numpy as np @@ -16,7 +18,7 @@ class CustomHyperhemisphericalDistribution( ): @beartype def __init__( - self, f: Callable, dim: int | np.int32 | np.int64, scale_by: float = 1 + self, f: Callable, dim: int | int32 | int64, scale_by: float = 1 ): """ Initialize a CustomHyperhemisphericalDistribution. diff --git a/pyrecest/distributions/hypersphere_subset/hyperhemispherical_uniform_distribution.py b/pyrecest/distributions/hypersphere_subset/hyperhemispherical_uniform_distribution.py index fa99f6c4..51f6b6c7 100644 --- a/pyrecest/distributions/hypersphere_subset/hyperhemispherical_uniform_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/hyperhemispherical_uniform_distribution.py @@ -1,3 +1,5 @@ +from pyrecest.backend import int64 +from pyrecest.backend import int32 import numpy as np from beartype import beartype @@ -17,7 +19,7 @@ class HyperhemisphericalUniformDistribution( AbstractHyperhemisphericalDistribution, AbstractHypersphereSubsetUniformDistribution ): @beartype - def sample(self, n: int | np.int32 | np.int64) -> np.ndarray: + def sample(self, n: int | int32 | int64) -> np.ndarray: """ Sample n points from the hyperhemispherical distribution. diff --git a/pyrecest/distributions/hypersphere_subset/hyperhemispherical_watson_distribution.py b/pyrecest/distributions/hypersphere_subset/hyperhemispherical_watson_distribution.py index 1255188f..180c0d3b 100644 --- a/pyrecest/distributions/hypersphere_subset/hyperhemispherical_watson_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/hyperhemispherical_watson_distribution.py @@ -1,3 +1,8 @@ +from pyrecest.backend import allclose +from pyrecest.backend import all +from pyrecest.backend import int64 +from pyrecest.backend import int32 +from pyrecest.backend import zeros import numbers import numpy as np @@ -28,7 +33,7 @@ def set_mode(self, mu: np.ndarray) -> "HyperhemisphericalWatsonDistribution": return w @beartype - def sample(self, n: int | np.int32 | np.int64) -> np.ndarray: + def sample(self, n: int | int32 | int64) -> np.ndarray: s_full = self.dist_full_sphere.sample(n) s = s_full * (-1) ** (s_full[-1] < 0) # Mirror to upper hemisphere return s @@ -56,8 +61,8 @@ def mode(self) -> np.ndarray: @beartype def shift(self, shift_by) -> "HyperhemisphericalWatsonDistribution": - assert np.allclose( - self.mu, np.append(np.zeros(self.dim - 1), 1) + assert allclose( + self.mu, np.append(zeros(self.dim - 1), 1) ), "There is no true shifting for the hyperhemisphere. This is a function for compatibility and only works when mu is [0,0,...,1]." dist_shifted = self dist_shifted.mu = shift_by diff --git a/pyrecest/distributions/hypersphere_subset/hyperspherical_dirac_distribution.py b/pyrecest/distributions/hypersphere_subset/hyperspherical_dirac_distribution.py index 0c92632c..eed89550 100644 --- a/pyrecest/distributions/hypersphere_subset/hyperspherical_dirac_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/hyperspherical_dirac_distribution.py @@ -1,3 +1,5 @@ +from pyrecest.backend import sum +from pyrecest.backend import reshape import matplotlib.pyplot as plt import numpy as np @@ -33,6 +35,6 @@ def to_circular_dirac_distribution(self): return CircularDiracDistribution(np.atan2(self.d[1, :], self.d[0, :]), self.w) def mean_direction(self): - vec_sum = np.sum(self.d * np.reshape(self.w, (-1, 1)), axis=0) + vec_sum = sum(self.d * reshape(self.w, (-1, 1)), axis=0) mu = vec_sum / np.linalg.norm(vec_sum) return mu diff --git a/pyrecest/distributions/hypersphere_subset/hyperspherical_uniform_distribution.py b/pyrecest/distributions/hypersphere_subset/hyperspherical_uniform_distribution.py index 5464ac6f..50d1ddf2 100644 --- a/pyrecest/distributions/hypersphere_subset/hyperspherical_uniform_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/hyperspherical_uniform_distribution.py @@ -1,3 +1,9 @@ +from pyrecest.backend import sqrt +from pyrecest.backend import sin +from pyrecest.backend import cos +from pyrecest.backend import int64 +from pyrecest.backend import int32 +from pyrecest.backend import empty import numpy as np from beartype import beartype @@ -11,7 +17,7 @@ class HypersphericalUniformDistribution( AbstractHypersphericalDistribution, AbstractHypersphereSubsetUniformDistribution ): @beartype - def __init__(self, dim: int | np.int32 | np.int64): + def __init__(self, dim: int | int32 | int64): AbstractHypersphereSubsetUniformDistribution.__init__(self, dim) @beartype @@ -19,11 +25,11 @@ def pdf(self, xs: np.ndarray): return AbstractHypersphereSubsetUniformDistribution.pdf(self, xs) @beartype - def sample(self, n: int | np.int32 | np.int64): + def sample(self, n: int | int32 | int64): assert isinstance(n, int) and n > 0, "n must be a positive integer" if self.dim == 2: - s = np.empty( + s = empty( ( n, self.dim + 1, @@ -31,9 +37,9 @@ def sample(self, n: int | np.int32 | np.int64): ) phi = 2 * np.pi * np.random.rand(n) s[:, 2] = np.random.rand(n) * 2 - 1 - r = np.sqrt(1 - s[:, 2] ** 2) - s[:, 0] = r * np.cos(phi) - s[:, 1] = r * np.sin(phi) + r = sqrt(1 - s[:, 2] ** 2) + s[:, 0] = r * cos(phi) + s[:, 1] = r * sin(phi) else: samples_unnorm = np.random.randn(n, self.dim + 1) s = samples_unnorm / np.linalg.norm(samples_unnorm, axis=1, keepdims=True) diff --git a/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py b/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py index c33c9a35..2a17bb3b 100644 --- a/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py +++ b/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py @@ -1,3 +1,16 @@ +from pyrecest.backend import sqrt +from pyrecest.backend import sin +from pyrecest.backend import shape +from pyrecest.backend import reshape +from pyrecest.backend import real +from pyrecest.backend import prod +from pyrecest.backend import isnan +from pyrecest.backend import imag +from pyrecest.backend import array +from pyrecest.backend import all +from pyrecest.backend import abs +from pyrecest.backend import empty +from pyrecest.backend import zeros import numpy as np import scipy @@ -25,7 +38,7 @@ def value(self, xs): return self.value_sph(phi, theta) def value_sph(self, phi, theta): - vals = np.zeros(theta.shape[0], dtype=complex) + vals = zeros(theta.shape[0], dtype=complex) for n_curr in range(self.coeff_mat.shape[0]): for m_curr in range(-n_curr, n_curr + 1): # Evaluate it for all query points at once @@ -35,10 +48,10 @@ def value_sph(self, phi, theta): vals += self.coeff_mat[n_curr, n_curr + m_curr] * y_lm if self.assert_real: - assert np.all( - np.abs(np.imag(vals)) < 1e-10 + assert all( + abs(imag(vals)) < 1e-10 ), "Coefficients apparently do not represent a real function." - return np.real(vals) + return real(vals) return vals @@ -50,9 +63,9 @@ def to_spherical_harmonics_distribution_real(self): if self.transformation != "identity": raise ValueError("Transformation currently not supported") - coeff_mat_real = np.empty(self.coeff_mat.shape, dtype=float) + coeff_mat_real = empty(self.coeff_mat.shape, dtype=float) - coeff_mat_real[0, 0] = np.real(self.coeff_mat[0, 0]) + coeff_mat_real[0, 0] = real(self.coeff_mat[0, 0]) for n in range( 1, self.coeff_mat.shape[0] @@ -61,39 +74,39 @@ def to_spherical_harmonics_distribution_real(self): if m < 0: coeff_mat_real[n, n + m] = ( (-1) ** m - * np.sqrt(2) + * sqrt(2) * (-1 if (-m) % 2 else 1) - * np.imag(self.coeff_mat[n, n + m]) + * imag(self.coeff_mat[n, n + m]) ) elif m > 0: coeff_mat_real[n, n + m] = ( - np.sqrt(2) + sqrt(2) * (-1 if m % 2 else 1) - * np.real(self.coeff_mat[n, n + m]) + * real(self.coeff_mat[n, n + m]) ) else: # m == 0 - coeff_mat_real[n, n] = np.real(self.coeff_mat[n, n]) + coeff_mat_real[n, n] = real(self.coeff_mat[n, n]) shd = SphericalHarmonicsDistributionReal( - np.real(coeff_mat_real), self.transformation + real(coeff_mat_real), self.transformation ) return shd def mean_direction(self): - if np.prod(self.coeff_mat.shape) <= 1: + if prod(self.coeff_mat.shape) <= 1: raise ValueError("Too few coefficients available to calculate the mean") - y = np.imag(self.coeff_mat[1, 0] + self.coeff_mat[1, 2]) / np.sqrt(2) - x = np.real(self.coeff_mat[1, 0] - self.coeff_mat[1, 2]) / np.sqrt(2) - z = np.real(self.coeff_mat[1, 1]) + y = imag(self.coeff_mat[1, 0] + self.coeff_mat[1, 2]) / sqrt(2) + x = real(self.coeff_mat[1, 0] - self.coeff_mat[1, 2]) / sqrt(2) + z = real(self.coeff_mat[1, 1]) - if np.linalg.norm(np.array([x, y, z])) < 1e-9: + if np.linalg.norm(array([x, y, z])) < 1e-9: raise ValueError( "Coefficients of degree 1 are almost zero. Therefore, no meaningful mean is available" ) - mu = np.array([x, y, z]) / np.linalg.norm(np.array([x, y, z])) + mu = array([x, y, z]) / np.linalg.norm(array([x, y, z])) return mu @@ -116,7 +129,7 @@ def fun_sph(phi, theta): np.ravel(phi), np.ravel(theta) ) vals = fun_cart(np.column_stack((x, y, z))) - return np.reshape(vals, np.shape(theta)) + return reshape(vals, shape(theta)) return fun_sph @@ -140,17 +153,17 @@ def from_function_via_integral_sph(fun, degree, transformation="identity"): coeff_mat = np.full((degree + 1, 2 * degree + 1), np.nan, dtype=complex) def real_part(phi, theta, n, m): - return np.real( - fun_with_trans(np.array(phi), np.array(theta)) + return real( + fun_with_trans(array(phi), array(theta)) * np.conj(sph_harm(m, n, phi, theta)) - * np.sin(theta) + * sin(theta) ) def imag_part(phi, theta, n, m): - return np.imag( - fun_with_trans(np.array(phi), np.array(theta)) + return imag( + fun_with_trans(array(phi), array(theta)) * np.conj(sph_harm(m, n, phi, theta)) - * np.sin(theta) + * sin(theta) ) for n in range(degree + 1): # Use n instead of l to comply with PEP 8 @@ -162,7 +175,7 @@ def imag_part(phi, theta, n, m): imag_part, [[0, 2 * np.pi], [0, np.pi]], args=(n, m) ) - if np.isnan(real_integral) or np.isnan(imag_integral): + if isnan(real_integral) or isnan(imag_integral): print(f"Integration failed for l={n}, m={m}") coeff_mat[n, m + n] = real_integral + 1j * imag_integral diff --git a/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_real.py b/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_real.py index ccaa1cb2..f316d4d4 100644 --- a/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_real.py +++ b/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_real.py @@ -1,3 +1,8 @@ +from pyrecest.backend import sqrt +from pyrecest.backend import real +from pyrecest.backend import imag +from pyrecest.backend import all +from pyrecest.backend import zeros import numpy as np # pylint: disable=E0611 @@ -11,7 +16,7 @@ class SphericalHarmonicsDistributionReal(AbstractSphericalHarmonicsDistribution): def __init__(self, coeff_mat, transformation="identity"): - if not np.all(np.isreal(coeff_mat)): + if not all(np.isreal(coeff_mat)): raise ValueError("Coefficients must be real") AbstractSphericalHarmonicsDistribution.__init__(self, coeff_mat, transformation) @@ -20,17 +25,17 @@ def real_spherical_harmonic_basis_function(n, m, theta, phi): y_lm = sph_harm(m, n, phi, theta) if m < 0: - y_nm_real = -np.sqrt(2) * np.imag(y_lm) + y_nm_real = -sqrt(2) * imag(y_lm) elif m == 0: - y_nm_real = np.real(y_lm) + y_nm_real = real(y_lm) else: - y_nm_real = (-1) ** m * np.sqrt(2) * np.real(y_lm) + y_nm_real = (-1) ** m * sqrt(2) * real(y_lm) return y_nm_real def value(self, xs): xs = np.atleast_2d(xs) - vals = np.zeros(xs.shape[0]) + vals = zeros(xs.shape[0]) phi, theta = AbstractSphereSubsetDistribution.cart_to_sph( xs[:, 0], xs[:, 1], xs[:, 2] ) @@ -61,12 +66,12 @@ def to_spherical_harmonics_distribution_complex(self): if m < 0: complex_coeff_mat[n, n + m] = ( 1j * real_coeff_mat[n, n + m] + real_coeff_mat[n, n - m] - ) / np.sqrt(2) + ) / sqrt(2) elif m > 0: complex_coeff_mat[n, n + m] = ( (-1) ** m * (-1j * real_coeff_mat[n, n - m] + real_coeff_mat[n, n + m]) - / np.sqrt(2) + / sqrt(2) ) else: # m == 0 complex_coeff_mat[n, n] = real_coeff_mat[n, n] diff --git a/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py b/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py index 3fe8eac2..8fd3d915 100644 --- a/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py @@ -1,3 +1,14 @@ +from pyrecest.backend import sinh +from pyrecest.backend import sin +from pyrecest.backend import ndim +from pyrecest.backend import isnan +from pyrecest.backend import exp +from pyrecest.backend import cos +from pyrecest.backend import arccos +from pyrecest.backend import all +from pyrecest.backend import abs +from pyrecest.backend import int64 +from pyrecest.backend import int32 import numbers import numpy as np @@ -22,7 +33,7 @@ def __init__(self, mu: np.ndarray, kappa: np.number | numbers.Real): self.kappa = kappa if self.dim == 2: - self.C = kappa / (4 * np.pi * np.sinh(kappa)) + self.C = kappa / (4 * np.pi * sinh(kappa)) else: self.C = kappa ** ((self.dim + 1) / 2 - 1) / ( (2 * np.pi) ** ((self.dim + 1) / 2) * iv((self.dim + 1) / 2 - 1, kappa) @@ -32,7 +43,7 @@ def __init__(self, mu: np.ndarray, kappa: np.number | numbers.Real): def pdf(self, xs: np.ndarray | np.number) -> np.ndarray | np.number: assert xs.shape[-1] == self.input_dim - return self.C * np.exp(self.kappa * self.mu.T @ xs.T) + return self.C * exp(self.kappa * self.mu.T @ xs.T) def mean_direction(self): return self.mu @@ -60,22 +71,22 @@ def sample(self, n): return samples def sample_deterministic(self): - samples = np.zeros((self.dim + 1, self.dim * 2 + 1)) + samples = zeros((self.dim + 1, self.dim * 2 + 1)) samples[0, 0] = 1 m1 = iv(self.dim / 2, self.kappa, 1) / iv(self.dim / 2 + 1, self.kappa, 1) for i in range(self.dim): - alpha = np.arccos(((self.dim * 2 + 1) * m1 - 1) / (self.dim * 2)) - samples[2 * i, 0] = np.cos(alpha) - samples[2 * i + 1, 0] = np.cos(alpha) - samples[2 * i, i + 1] = np.sin(alpha) - samples[2 * i + 1, i + 1] = -np.sin(alpha) + alpha = arccos(((self.dim * 2 + 1) * m1 - 1) / (self.dim * 2)) + samples[2 * i, 0] = cos(alpha) + samples[2 * i + 1, 0] = cos(alpha) + samples[2 * i, i + 1] = sin(alpha) + samples[2 * i + 1, i + 1] = -sin(alpha) Q = self.get_rotation_matrix() samples = Q @ samples return samples def get_rotation_matrix(self): - M = np.zeros((self.dim + 1, self.dim + 1)) + M = zeros((self.dim + 1, self.dim + 1)) M[:, 0] = self.mu Q, R = qr(M) if R[0, 0] < 0: @@ -101,7 +112,7 @@ def from_distribution(d: AbstractHypersphericalDistribution): @staticmethod @beartype def from_moment(m: np.ndarray): - assert np.ndim(m) == 1, "mu must be a vector" + assert ndim(m) == 1, "mu must be a vector" assert len(m) >= 2, "mu must be at least 2 for the circular case" mu_ = m / np.linalg.norm(m) @@ -133,7 +144,7 @@ def multiply(self, other: "VonMisesFisherDistribution"): @beartype def convolve(self, other: "VonMisesFisherDistribution"): assert other.mu[-1] == 1, "Other is not zonal" - assert np.all(self.mu.shape == other.mu.shape) + assert all(self.mu.shape == other.mu.shape) d = self.dim + 1 mu_ = self.mu @@ -146,18 +157,18 @@ def convolve(self, other: "VonMisesFisherDistribution"): @staticmethod @beartype - def a_d(d: int | np.int32 | np.int64, kappa: np.number | numbers.Real): + def a_d(d: int | int32 | int64, kappa: np.number | numbers.Real): bessel1 = iv(d / 2, kappa) bessel2 = iv(d / 2 - 1, kappa) - if np.isnan(bessel1) or np.isnan(bessel2): + if isnan(bessel1) or isnan(bessel2): print(f"Bessel functions returned NaN for d={d}, kappa={kappa}") return bessel1 / bessel2 @staticmethod @beartype - def a_d_inverse(d: int | np.int32 | np.int64, x: float): + def a_d_inverse(d: int | int32 | int64, x: float): kappa_ = x * (d - x**2) / (1 - x**2) - if np.isnan(kappa_): + if isnan(kappa_): print(f"Initial kappa_ is NaN for d={d}, x={x}") max_steps = 20 @@ -166,7 +177,7 @@ def a_d_inverse(d: int | np.int32 | np.int64, x: float): for _ in range(max_steps): kappa_old = kappa_ ad_value = VonMisesFisherDistribution.a_d(d, kappa_old) - if np.isnan(ad_value): + if isnan(ad_value): print( f"a_d returned NaN during iteration for d={d}, kappa_old={kappa_old}" ) @@ -175,12 +186,12 @@ def a_d_inverse(d: int | np.int32 | np.int64, x: float): 1 - ad_value**2 - (d - 1) / kappa_old * ad_value ) - if np.isnan(kappa_): + if isnan(kappa_): print( f"kappa_ became NaN during iteration for d={d}, kappa_old={kappa_old}, x={x}" ) - if np.abs(kappa_ - kappa_old) < epsilon: + if abs(kappa_ - kappa_old) < epsilon: break return kappa_ diff --git a/pyrecest/distributions/hypersphere_subset/watson_distribution.py b/pyrecest/distributions/hypersphere_subset/watson_distribution.py index d3e133d8..96737a95 100644 --- a/pyrecest/distributions/hypersphere_subset/watson_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/watson_distribution.py @@ -1,3 +1,13 @@ +from pyrecest.backend import vstack +from pyrecest.backend import tile +from pyrecest.backend import hstack +from pyrecest.backend import eye +from pyrecest.backend import exp +from pyrecest.backend import dot +from pyrecest.backend import array +from pyrecest.backend import abs +from pyrecest.backend import float64 +from pyrecest.backend import zeros import numbers import mpmath @@ -23,7 +33,7 @@ def __init__(self, mu: np.ndarray, kappa: np.number | numbers.Real): """ AbstractHypersphericalDistribution.__init__(self, dim=mu.shape[0] - 1) assert mu.ndim == 1, "mu must be a 1-D vector" - assert np.abs(np.linalg.norm(mu) - 1) < self.EPSILON, "mu is unnormalized" + assert abs(np.linalg.norm(mu) - 1) < self.EPSILON, "mu is unnormalized" self.mu = mu self.kappa = kappa @@ -33,7 +43,7 @@ def __init__(self, mu: np.ndarray, kappa: np.number | numbers.Real): / (2 * mpmath.pi ** ((self.dim + 1) / 2)) / mpmath.hyper([0.5], [(self.dim + 1) / 2.0], self.kappa) ) - self.C = np.float64(C_mpf) + self.C = float64(C_mpf) def pdf(self, xs): """ @@ -46,7 +56,7 @@ def pdf(self, xs): np.generic: The value of the pdf at xs. """ assert xs.shape[-1] == self.input_dim, "Last dimension of xs must be dim + 1" - p = self.C * np.exp(self.kappa * np.dot(self.mu.T, xs.T) ** 2) + p = self.C * exp(self.kappa * (self.mu.T @ xs.T) ** 2) return p def to_bingham(self) -> BinghamDistribution: @@ -55,13 +65,13 @@ def to_bingham(self) -> BinghamDistribution: "Conversion to Bingham is not implemented for kappa<0" ) - M = np.tile(self.mu.reshape(-1, 1), (1, self.input_dim)) - E = np.eye(self.input_dim) + M = tile(self.mu.reshape(-1, 1), (1, self.input_dim)) + E = eye(self.input_dim) E[0, 0] = 0 M = M + E Q, _ = qr(M) - M = np.hstack([Q[:, 1:], Q[:, 0].reshape(-1, 1)]) - Z = np.hstack([np.full((self.dim), -self.kappa), 0]) + M = hstack([Q[:, 1:], Q[:, 0].reshape(-1, 1)]) + Z = hstack([np.full((self.dim), -self.kappa), 0]) return BinghamDistribution(Z, M) def sample(self, n): @@ -83,7 +93,5 @@ def set_mode(self, new_mode): return dist def shift(self, shift_by): - assert np.array_equal( - self.mu, np.vstack([np.zeros((self.dim, 1)), 1]) - ), "There is no true shifting for the hypersphere. This is a function for compatibility and only works when mu is [0,0,...,1]." + np.testing.assert_almost_equal(self.mu, vstack([zeros((self.dim, 1)), 1]), "There is no true shifting for the hypersphere. This is a function for compatibility and only works when mu is [0,0,...,1].") return self.set_mode(shift_by) diff --git a/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py b/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py index 666e63fa..d8122a9d 100644 --- a/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py +++ b/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py @@ -1,3 +1,20 @@ +from pyrecest.backend import vstack +from pyrecest.backend import sqrt +from pyrecest.backend import sin +from pyrecest.backend import reshape +from pyrecest.backend import ones +from pyrecest.backend import mod +from pyrecest.backend import meshgrid +from pyrecest.backend import log +from pyrecest.backend import linspace +from pyrecest.backend import isnan +from pyrecest.backend import cos +from pyrecest.backend import array +from pyrecest.backend import arange +from pyrecest.backend import abs +from pyrecest.backend import int64 +from pyrecest.backend import int32 +from pyrecest.backend import zeros import numbers from collections.abc import Callable @@ -21,7 +38,7 @@ def input_dim(self) -> int: @staticmethod @beartype - def integrate_fun_over_domain(f: Callable, dim: int | np.int32 | np.int64) -> float: + def integrate_fun_over_domain(f: Callable, dim: int | int32 | int64) -> float: integration_boundaries = [(0, 2 * np.pi)] * dim return AbstractHypertoroidalDistribution.integrate_fun_over_domain_part( f, dim, integration_boundaries @@ -47,7 +64,7 @@ def shift(self, shift_by): # Define the shifted PDF def shifted_pdf(xs): - return self.pdf(np.mod(xs + shift_by, 2 * np.pi)) + return self.pdf(mod(xs + shift_by, 2 * np.pi)) # Create the shifted distribution shifted_distribution = CustomHypertoroidalDistribution(shifted_pdf, self.dim) @@ -57,7 +74,7 @@ def shifted_pdf(xs): @staticmethod @beartype def integrate_fun_over_domain_part( - f: Callable, dim: int | np.int32 | np.int64, integration_boundaries + f: Callable, dim: int | int32 | int64, integration_boundaries ) -> float: if len(integration_boundaries) != dim: raise ValueError( @@ -70,36 +87,36 @@ def integrate_numerically( self, integration_boundaries=None ) -> np.number | numbers.Real: if integration_boundaries is None: - integration_boundaries = np.vstack( - (np.zeros(self.dim), 2 * np.pi * np.ones(self.dim)) + integration_boundaries = vstack( + (zeros(self.dim), 2 * np.pi * ones(self.dim)) ) - integration_boundaries = np.reshape(integration_boundaries, (2, -1)) + integration_boundaries = reshape(integration_boundaries, (2, -1)) left, right = integration_boundaries integration_boundaries = list(zip(left, right)) return self.integrate_fun_over_domain_part( - lambda *args: self.pdf(np.array(args)), self.dim, integration_boundaries + lambda *args: self.pdf(array(args)), self.dim, integration_boundaries ) @beartype def trigonometric_moment_numerical( - self, n: int | np.int32 | np.int64 + self, n: int | int32 | int64 ) -> np.ndarray: """Calculates the complex trignometric moments. Since nquad does not support complex functions, the calculation is split up (as used in the alternative representation of trigonometric polonymials involving the two real numbers alpha and beta""" def moment_fun_real(*args): - x = np.array(args) - return np.array([self.pdf(x) * np.cos(n * xi) for xi in x]) + x = array(args) + return array([self.pdf(x) * cos(n * xi) for xi in x]) def moment_fun_imag(*args): - x = np.array(args) - return np.array([self.pdf(x) * np.sin(n * xi) for xi in x]) + x = array(args) + return array([self.pdf(x) * sin(n * xi) for xi in x]) - alpha = np.zeros(self.dim, dtype=float) - beta = np.zeros(self.dim, dtype=float) + alpha = zeros(self.dim, dtype=float) + beta = zeros(self.dim, dtype=float) for i in range(self.dim): # i=i to avoid pylint warning (though it does not matter here) @@ -114,9 +131,9 @@ def moment_fun_imag(*args): def entropy_numerical(self): def entropy_fun(*args): - x = np.array(args) + x = array(args) pdf_val = self.pdf(x) - return pdf_val * np.log(pdf_val) + return pdf_val * log(pdf_val) return -self.integrate_fun_over_domain(entropy_fun, self.dim) @@ -135,13 +152,13 @@ def angular_error(alpha, beta): Returns: float or numpy array: The angular error(s) in radians. """ - assert not np.isnan(alpha).any() and not np.isnan(beta).any() + assert not isnan(alpha).any() and not isnan(beta).any() # Ensure the angles are between 0 and 2*pi - alpha = np.mod(alpha, 2 * np.pi) - beta = np.mod(beta, 2 * np.pi) + alpha = mod(alpha, 2 * np.pi) + beta = mod(beta, 2 * np.pi) # Calculate the absolute difference - diff = np.abs(alpha - beta) + diff = abs(alpha - beta) # Calculate the angular error e = np.minimum(diff, 2 * np.pi - diff) @@ -155,8 +172,8 @@ def hellinger_distance_numerical(self, other): ), "Cannot compare distributions with different number of dimensions." def hellinger_dist_fun(*args): - x = np.array(args) - return (np.sqrt(self.pdf(x)) - np.sqrt(other.pdf(x))) ** 2 + x = array(args) + return (sqrt(self.pdf(x)) - sqrt(other.pdf(x))) ** 2 dist = 0.5 * self.integrate_fun_over_domain(hellinger_dist_fun, self.dim) return dist @@ -168,7 +185,7 @@ def total_variation_distance_numerical(self, other): ), "Cannot compare distributions with different number of dimensions" def total_variation_dist_fun(*args): - x = np.array(args) + x = array(args) return abs(self.pdf(x) - other.pdf(x)) dist = 0.5 * self.integrate_fun_over_domain(total_variation_dist_fun, self.dim) @@ -176,16 +193,16 @@ def total_variation_dist_fun(*args): def plot(self, resolution=128, **kwargs): if self.dim == 1: - theta = np.linspace(0, 2 * np.pi, resolution) + theta = linspace(0, 2 * np.pi, resolution) f_theta = self.pdf(theta) p = plt.plot(theta, f_theta, **kwargs) AbstractHypertoroidalDistribution.setup_axis_circular("x") elif self.dim == 2: step = 2 * np.pi / resolution - alpha, beta = np.meshgrid( - np.arange(0, 2 * np.pi, step), np.arange(0, 2 * np.pi, step) + alpha, beta = meshgrid( + arange(0, 2 * np.pi, step), arange(0, 2 * np.pi, step) ) - f = self.pdf(np.vstack((alpha.ravel(), beta.ravel()))) + f = self.pdf(vstack((alpha.ravel(), beta.ravel()))) f = f.reshape(alpha.shape) p = plt.contourf(alpha, beta, f, **kwargs) AbstractHypertoroidalDistribution.setup_axis_circular("x") @@ -211,7 +228,7 @@ def mean(self) -> np.ndarray: def mean_direction(self) -> np.ndarray: a = self.trigonometric_moment(1) - m = np.mod(np.angle(a), 2 * np.pi) + m = mod(np.angle(a), 2 * np.pi) return m def mode(self) -> np.ndarray: @@ -222,7 +239,7 @@ def mode_numerical(self) -> np.ndarray: raise NotImplementedError("Mode calculation is not implemented") @beartype - def trigonometric_moment(self, n: int | np.int32 | np.int64) -> np.ndarray: + def trigonometric_moment(self, n: int | int32 | int64) -> np.ndarray: return self.trigonometric_moment_numerical(n) def integrate(self, integration_boundaries=None): @@ -230,15 +247,15 @@ def integrate(self, integration_boundaries=None): def mean_2dimD(self) -> np.ndarray: m = self.trigonometric_moment_numerical(1) - mu = np.vstack((m.real, m.imag)) + mu = vstack((m.real, m.imag)) return mu # jscpd:ignore-start def sample_metropolis_hastings( self, - n: int | np.int32 | np.int64, - burn_in: int | np.int32 | np.int64 = 10, - skipping: int | np.int32 | np.int64 = 5, + n: int | int32 | int64, + burn_in: int | int32 | int64 = 10, + skipping: int | int32 | int64 = 5, proposal: Callable | None = None, start_point: np.number | numbers.Real | np.ndarray | None = None, ) -> np.ndarray: @@ -246,7 +263,7 @@ def sample_metropolis_hastings( if proposal is None: def proposal(x): - return np.mod(x + np.random.randn(self.dim), 2 * np.pi) + return mod(x + np.random.randn(self.dim), 2 * np.pi) if start_point is None: start_point = self.mean_direction() diff --git a/pyrecest/distributions/hypertorus/abstract_toroidal_distribution.py b/pyrecest/distributions/hypertorus/abstract_toroidal_distribution.py index d8a88c54..782a4460 100644 --- a/pyrecest/distributions/hypertorus/abstract_toroidal_distribution.py +++ b/pyrecest/distributions/hypertorus/abstract_toroidal_distribution.py @@ -1,3 +1,10 @@ +from pyrecest.backend import sqrt +from pyrecest.backend import sin +from pyrecest.backend import cos +from pyrecest.backend import array +from pyrecest.backend import int64 +from pyrecest.backend import int32 +from pyrecest.backend import zeros import numpy as np from scipy.integrate import dblquad @@ -14,18 +21,18 @@ def covariance_4D_numerical(self) -> np.ndarray: def f( x: float, y: float, - i: int | np.int32 | np.int64, - j: int | np.int32 | np.int64, + i: int | int32 | int64, + j: int | int32 | int64, ) -> float: funcs = [ - lambda x, _: np.cos(x) - m[0], - lambda x, _: np.sin(x) - m[1], - lambda _, y: np.cos(y) - m[2], - lambda _, y: np.sin(y) - m[3], + lambda x, _: cos(x) - m[0], + lambda x, _: sin(x) - m[1], + lambda _, y: cos(y) - m[2], + lambda _, y: sin(y) - m[3], ] - return self.pdf(np.array([x, y])) * funcs[i](x, y) * funcs[j](x, y) + return self.pdf(array([x, y])) * funcs[i](x, y) * funcs[j](x, y) - C = np.zeros((4, 4)) + C = zeros((4, 4)) for i in range(4): for j in range(i, 4): C[i, j], _ = dblquad(f, 0, 2 * np.pi, 0, 2 * np.pi, args=(i, j)) @@ -42,19 +49,19 @@ def circular_correlation_jammalamadaka_numerical(self) -> float: m = self.mean_direction() def fsinAsinB(x, y): - return self.pdf(np.array([x, y])) * np.sin(x - m[0]) * np.sin(y - m[1]) + return self.pdf(array([x, y])) * sin(x - m[0]) * sin(y - m[1]) def fsinAsquared(x, y): - return self.pdf(np.array([x, y])) * np.sin(x - m[0]) ** 2 + return self.pdf(array([x, y])) * sin(x - m[0]) ** 2 def fsinBsquared(x, y): - return self.pdf(np.array([x, y])) * np.sin(y - m[1]) ** 2 + return self.pdf(array([x, y])) * sin(y - m[1]) ** 2 EsinAsinB, _ = dblquad(fsinAsinB, 0, 2 * np.pi, 0, 2 * np.pi) EsinAsquared, _ = dblquad(fsinAsquared, 0, 2 * np.pi, 0, 2 * np.pi) EsinBsquared, _ = dblquad(fsinBsquared, 0, 2 * np.pi, 0, 2 * np.pi) - rhoc = EsinAsinB / np.sqrt(EsinAsquared * EsinBsquared) + rhoc = EsinAsinB / sqrt(EsinAsquared * EsinBsquared) return rhoc def mean_4D(self) -> np.ndarray: @@ -66,5 +73,5 @@ def mean_4D(self) -> np.ndarray: expectation value of [cos(x1), sin(x1), cos(x2), sin(x2)] """ m = self.trigonometric_moment(1) - mu = np.array([m[0].real, m[0].imag, m[1].real, m[1].imag]).ravel() + mu = array([m[0].real, m[0].imag, m[1].real, m[1].imag]).ravel() return mu diff --git a/pyrecest/distributions/hypertorus/custom_hypertoroidal_distribution.py b/pyrecest/distributions/hypertorus/custom_hypertoroidal_distribution.py index 84dfa23a..f611ed86 100644 --- a/pyrecest/distributions/hypertorus/custom_hypertoroidal_distribution.py +++ b/pyrecest/distributions/hypertorus/custom_hypertoroidal_distribution.py @@ -1,3 +1,5 @@ +from pyrecest.backend import mod +from pyrecest.backend import zeros import numpy as np from ..abstract_custom_distribution import AbstractCustomDistribution @@ -21,13 +23,13 @@ def __init__(self, f, dim, shift_by=None): AbstractCustomDistribution.__init__(self, f) AbstractHypertoroidalDistribution.__init__(self, dim) if shift_by is None: - self.shift_by = np.zeros(dim) + self.shift_by = zeros(dim) else: self.shift_by = shift_by def pdf(self, xs): return AbstractCustomDistribution.pdf( - self, np.mod(xs + self.shift_by, 2 * np.pi) + self, mod(xs + self.shift_by, 2 * np.pi) ) def to_custom_circular(self): diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py b/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py index ee64c6c1..a7d85d3e 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py @@ -1,3 +1,13 @@ +from pyrecest.backend import tile +from pyrecest.backend import sum +from pyrecest.backend import reshape +from pyrecest.backend import real +from pyrecest.backend import mod +from pyrecest.backend import imag +from pyrecest.backend import exp +from pyrecest.backend import arctan2 +from pyrecest.backend import int64 +from pyrecest.backend import int32 import copy from collections.abc import Callable @@ -26,7 +36,7 @@ def __init__( AbstractHypertoroidalDistribution.__init__(self, dim) AbstractDiracDistribution.__init__( - self, np.atleast_1d(np.mod(d, 2 * np.pi)), w=w + self, np.atleast_1d(mod(d, 2 * np.pi)), w=w ) def plot(self, *args, **kwargs): @@ -40,11 +50,11 @@ def mean_direction(self) -> np.ndarray: :return: Mean direction """ a = self.trigonometric_moment(1) - m = np.mod(np.arctan2(np.imag(a), np.real(a)), 2 * np.pi) + m = mod(arctan2(imag(a), real(a)), 2 * np.pi) return m @beartype - def trigonometric_moment(self, n: int | np.int32 | np.int64) -> np.ndarray: + def trigonometric_moment(self, n: int | int32 | int64) -> np.ndarray: """ Calculate the trigonometric moment of the HypertoroidalDiracDistribution. @@ -52,14 +62,14 @@ def trigonometric_moment(self, n: int | np.int32 | np.int64) -> np.ndarray: :param n: Integer moment order :return: Trigonometric moment """ - return np.sum( - np.exp(1j * n * self.d.T) * np.tile(self.w, (self.dim, 1)), axis=1 + return sum( + exp(1j * n * self.d.T) * tile(self.w, (self.dim, 1)), axis=1 ) @beartype def apply_function(self, f: Callable) -> "HypertoroidalDiracDistribution": dist = super().apply_function(f) - dist.d = np.mod(dist.d, 2 * np.pi) + dist.d = mod(dist.d, 2 * np.pi) return dist def to_toroidal_wd(self): @@ -70,7 +80,7 @@ def to_toroidal_wd(self): return twd @beartype - def marginalize_to_1D(self, dimension: int | np.int32 | np.int64): + def marginalize_to_1D(self, dimension: int | int32 | int64): from ..circle.circular_dirac_distribution import CircularDiracDistribution return CircularDiracDistribution(self.d[:, dimension], self.w) @@ -87,7 +97,7 @@ def marginalize_out(self, dimensions: int | list[int]): def shift(self, shift_by) -> "HypertoroidalDiracDistribution": assert shift_by.shape[-1] == self.dim hd = copy.copy(self) - hd.d = np.mod(self.d + np.reshape(shift_by, (1, -1)), 2 * np.pi) + hd.d = mod(self.d + reshape(shift_by, (1, -1)), 2 * np.pi) return hd def entropy(self): diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_mixture.py b/pyrecest/distributions/hypertorus/hypertoroidal_mixture.py index 4ed50092..ec4409d0 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_mixture.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_mixture.py @@ -1,3 +1,6 @@ +from pyrecest.backend import int64 +from pyrecest.backend import int32 +from pyrecest.backend import zeros import collections import copy @@ -28,14 +31,14 @@ def __init__( AbstractHypertoroidalDistribution ] = self.dists - def trigonometric_moment(self, n: int | np.int32 | np.int64) -> np.ndarray: + def trigonometric_moment(self, n: int | int32 | int64) -> np.ndarray: """ Calculate n-th trigonometric moment :param n: number of moment :returns: n-th trigonometric moment (complex number) """ - m = np.zeros(self.dim, dtype=complex) + m = zeros(self.dim, dtype=complex) for i in range(len(self.dists)): # Calculate moments using moments of each component m += self.w[i] * self.dists[i].trigonometric_moment(n) diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_uniform_distribution.py b/pyrecest/distributions/hypertorus/hypertoroidal_uniform_distribution.py index 01e03b86..d8a4f348 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_uniform_distribution.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_uniform_distribution.py @@ -1,3 +1,10 @@ +from pyrecest.backend import prod +from pyrecest.backend import ones +from pyrecest.backend import ndim +from pyrecest.backend import log +from pyrecest.backend import int64 +from pyrecest.backend import int32 +from pyrecest.backend import zeros import numpy as np from ..abstract_uniform_distribution import AbstractUniformDistribution @@ -14,9 +21,9 @@ def pdf(self, xs: np.ndarray) -> np.ndarray: :param xs: Values at which to evaluate the PDF :returns: PDF evaluated at xs """ - return 1 / self.get_manifold_size() * np.ones(xs.size // self.dim) + return 1 / self.get_manifold_size() * ones(xs.size // self.dim) - def trigonometric_moment(self, n: int | np.int32 | np.int64) -> np.ndarray: + def trigonometric_moment(self, n: int | int32 | int64) -> np.ndarray: """ Returns the n-th trigonometric moment @@ -24,9 +31,9 @@ def trigonometric_moment(self, n: int | np.int32 | np.int64) -> np.ndarray: :returns: n-th trigonometric moment """ if n == 0: - return np.ones(self.dim) + return ones(self.dim) - return np.zeros(self.dim) + return zeros(self.dim) def entropy(self) -> float: """ @@ -34,7 +41,7 @@ def entropy(self) -> float: :returns: Entropy """ - return self.dim * np.log(2 * np.pi) + return self.dim * log(2 * np.pi) def mean_direction(self): """ @@ -47,7 +54,7 @@ def mean_direction(self): "Hypertoroidal uniform distributions do not have a unique mean" ) - def sample(self, n: int | np.int32 | np.int64) -> np.ndarray: + def sample(self, n: int | int32 | int64) -> np.ndarray: """ Returns a sample of size n from the distribution @@ -78,12 +85,12 @@ def integrate( :returns: Integral over the specified boundaries """ if integration_boundaries is None: - left = np.zeros((self.dim,)) - right = 2 * np.pi * np.ones((self.dim,)) + left = zeros((self.dim,)) + right = 2 * np.pi * ones((self.dim,)) else: left, right = integration_boundaries - assert np.ndim(left) == 0 and self.dim == 1 or left.shape == (self.dim,) - assert np.ndim(right) == 0 and self.dim == 1 or right.shape == (self.dim,) + assert ndim(left) == 0 and self.dim == 1 or left.shape == (self.dim,) + assert ndim(right) == 0 and self.dim == 1 or right.shape == (self.dim,) - volume = np.prod(right - left) + volume = prod(right - left) return 1 / (2 * np.pi) ** self.dim * volume diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py b/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py index 1341606d..abccb29b 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py @@ -1,3 +1,14 @@ +from pyrecest.backend import reshape +from pyrecest.backend import mod +from pyrecest.backend import meshgrid +from pyrecest.backend import exp +from pyrecest.backend import array +from pyrecest.backend import arange +from pyrecest.backend import allclose +from pyrecest.backend import all +from pyrecest.backend import int64 +from pyrecest.backend import int32 +from pyrecest.backend import zeros import copy import numpy as np @@ -18,18 +29,18 @@ def __init__(self, mu: np.ndarray, C: np.ndarray): AbstractHypertoroidalDistribution.__init__(self, np.size(mu)) # First check is for 1-D case assert np.size(C) == 1 or C.shape[0] == C.shape[1], "C must be dim x dim" - assert np.size(C) == 1 or np.allclose(C, C.T, atol=1e-8), "C must be symmetric" + assert np.size(C) == 1 or allclose(C, C.T, atol=1e-8), "C must be symmetric" assert ( - np.size(C) == 1 and C > 0 or np.all(np.linalg.eigvals(C) > 0) + np.size(C) == 1 and C > 0 or all(np.linalg.eigvals(C) > 0) ), "C must be positive definite" assert ( np.size(C) == np.size(mu) or np.size(mu) == C.shape[1] ), "mu must be dim x 1" - self.mu = np.mod(mu, 2 * np.pi) + self.mu = mod(mu, 2 * np.pi) self.C = C - def pdf(self, xs: np.ndarray, m: int | np.int32 | np.int64 = 3) -> np.ndarray: + def pdf(self, xs: np.ndarray, m: int | int32 | int64 = 3) -> np.ndarray: """ Compute the PDF at given points. @@ -37,14 +48,14 @@ def pdf(self, xs: np.ndarray, m: int | np.int32 | np.int64 = 3) -> np.ndarray: :param m: Controls the number of terms in the Fourier series approximation. :return: PDF values at xs. """ - xs = np.reshape(xs, (-1, self.dim)) + xs = reshape(xs, (-1, self.dim)) # Generate all combinations of offsets for each dimension - offsets = [np.arange(-m, m + 1) * 2 * np.pi for _ in range(self.dim)] - offset_combinations = np.array(np.meshgrid(*offsets)).T.reshape(-1, self.dim) + offsets = [arange(-m, m + 1) * 2 * np.pi for _ in range(self.dim)] + offset_combinations = array(meshgrid(*offsets)).T.reshape(-1, self.dim) # Calculate the PDF values by considering all combinations of offsets - pdf_values = np.zeros(xs.shape[0]) + pdf_values = zeros(xs.shape[0]) for offset in offset_combinations: shifted_xa = xs + offset[np.newaxis, :] pdf_values += multivariate_normal.pdf( @@ -64,7 +75,7 @@ def shift(self, shift_by) -> "HypertoroidalWrappedNormalDistribution": assert shift_by.shape == (self.dim,) hd = self - hd.mu = np.mod(self.mu + shift_by, 2 * np.pi) + hd.mu = mod(self.mu + shift_by, 2 * np.pi) return hd def sample(self, n): @@ -75,7 +86,7 @@ def sample(self, n): raise ValueError("n must be a positive integer") s = np.random.multivariate_normal(self.mu, self.C, n) - s = np.mod(s, 2 * np.pi) # wrap the samples + s = mod(s, 2 * np.pi) # wrap the samples return s def convolve(self, other: "HypertoroidalWrappedNormalDistribution"): @@ -109,7 +120,7 @@ def trigonometric_moment(self, n): """ assert isinstance(n, int), "n must be an integer" - m = np.exp( + m = exp( [1j * n * self.mu[i] - n**2 * self.C[i, i] / 2 for i in range(self.dim)] ) diff --git a/pyrecest/distributions/hypertorus/toroidal_dirac_distribution.py b/pyrecest/distributions/hypertorus/toroidal_dirac_distribution.py index 584e0c74..3de7310c 100644 --- a/pyrecest/distributions/hypertorus/toroidal_dirac_distribution.py +++ b/pyrecest/distributions/hypertorus/toroidal_dirac_distribution.py @@ -1,3 +1,9 @@ +from pyrecest.backend import tile +from pyrecest.backend import sum +from pyrecest.backend import sqrt +from pyrecest.backend import sin +from pyrecest.backend import dot +from pyrecest.backend import cos import numpy as np from .abstract_toroidal_distribution import AbstractToroidalDistribution @@ -25,10 +31,10 @@ def circular_correlation_jammalamadaka(self) -> float: """ m = self.mean_direction() - x = np.sum(self.w * np.sin(self.d[0, :] - m[0]) * np.sin(self.d[1, :] - m[1])) - y = np.sqrt( - np.sum(self.w * np.sin(self.d[0, :] - m[0]) ** 2) - * np.sum(self.w * np.sin(self.d[1, :] - m[1]) ** 2) + x = sum(self.w * sin(self.d[0, :] - m[0]) * sin(self.d[1, :] - m[1])) + y = sqrt( + sum(self.w * sin(self.d[0, :] - m[0]) ** 2) + * sum(self.w * sin(self.d[1, :] - m[1]) ** 2) ) rhoc = x / y return rhoc @@ -41,15 +47,15 @@ def covariance_4D(self) -> np.ndarray: """ dbar = np.column_stack( [ - np.cos(self.d[0, :]), - np.sin(self.d[0, :]), - np.cos(self.d[1, :]), - np.sin(self.d[1, :]), + cos(self.d[0, :]), + sin(self.d[0, :]), + cos(self.d[1, :]), + sin(self.d[1, :]), ] ) - mu = np.dot(self.w, dbar) + mu = dot(self.w, dbar) n = len(self.d) - C = (dbar - np.tile(mu, (n, 1))).T @ ( - np.diag(self.w) @ (dbar - np.tile(mu, (n, 1))) + C = (dbar - tile(mu, (n, 1))).T @ ( + np.diag(self.w) @ (dbar - tile(mu, (n, 1))) ) return C diff --git a/pyrecest/distributions/hypertorus/toroidal_von_mises_sine_distribution.py b/pyrecest/distributions/hypertorus/toroidal_von_mises_sine_distribution.py index 76f98856..14dc065c 100644 --- a/pyrecest/distributions/hypertorus/toroidal_von_mises_sine_distribution.py +++ b/pyrecest/distributions/hypertorus/toroidal_von_mises_sine_distribution.py @@ -1,3 +1,9 @@ +from pyrecest.backend import sum +from pyrecest.backend import sin +from pyrecest.backend import mod +from pyrecest.backend import exp +from pyrecest.backend import cos +from pyrecest.backend import all import numpy as np from scipy.special import comb, iv @@ -10,9 +16,9 @@ def __init__(self, mu, kappa, lambda_): assert np.size(mu) == 2 assert np.size(kappa) == 2 assert np.isscalar(lambda_) - assert np.all(kappa >= 0) + assert all(kappa >= 0) - self.mu = np.mod(mu, 2 * np.pi) + self.mu = mod(mu, 2 * np.pi) self.kappa = kappa self.lambda_ = lambda_ @@ -28,16 +34,16 @@ def s(m): * iv(m, self.kappa[1]) ) - Cinv = 4 * np.pi**2 * np.sum([s(m) for m in range(11)]) + Cinv = 4 * np.pi**2 * sum([s(m) for m in range(11)]) return Cinv def pdf(self, xs): assert xs.shape[-1] == 2 - p = self.C * np.exp( - self.kappa[0] * np.cos(xs[..., 0] - self.mu[0]) - + self.kappa[1] * np.cos(xs[..., 1] - self.mu[1]) + p = self.C * exp( + self.kappa[0] * cos(xs[..., 0] - self.mu[0]) + + self.kappa[1] * cos(xs[..., 1] - self.mu[1]) + self.lambda_ - * np.sin(xs[..., 0] - self.mu[0]) - * np.sin(xs[..., 1] - self.mu[1]) + * sin(xs[..., 0] - self.mu[0]) + * sin(xs[..., 1] - self.mu[1]) ) return p diff --git a/pyrecest/distributions/hypertorus/toroidal_wrapped_normal_distribution.py b/pyrecest/distributions/hypertorus/toroidal_wrapped_normal_distribution.py index cc1eb8d3..3451cbcf 100644 --- a/pyrecest/distributions/hypertorus/toroidal_wrapped_normal_distribution.py +++ b/pyrecest/distributions/hypertorus/toroidal_wrapped_normal_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import array import numpy as np from numpy import cos, exp, sin @@ -19,10 +20,10 @@ def mean_4D(self) -> np.ndarray: Compute the 4D mean of the distribution. Returns: - np.array: The 4D mean. + array: The 4D mean. """ s = self.mu - mu = np.array( + mu = array( [ cos(s[0, :]) * exp(-self.C[0, 0] / 2), sin(s[0, :]) * exp(-self.C[0, 0] / 2), @@ -37,9 +38,9 @@ def covariance_4D(self) -> np.ndarray: Compute the 4D covariance of the distribution. Returns: - np.array: The 4D covariance. + array: The 4D covariance. """ - C = np.zeros((4, 4)) + C = zeros((4, 4)) # jscpd:ignore-start C[0, 0] = ( 1 diff --git a/pyrecest/distributions/nonperiodic/abstract_hyperrectangular_distribution.py b/pyrecest/distributions/nonperiodic/abstract_hyperrectangular_distribution.py index cd013695..ad3b1c05 100644 --- a/pyrecest/distributions/nonperiodic/abstract_hyperrectangular_distribution.py +++ b/pyrecest/distributions/nonperiodic/abstract_hyperrectangular_distribution.py @@ -1,3 +1,6 @@ +from pyrecest.backend import reshape +from pyrecest.backend import prod +from pyrecest.backend import array import numpy as np from scipy.integrate import nquad @@ -12,7 +15,7 @@ def __init__(self, bounds): self.bounds = bounds def get_manifold_size(self): - s = np.prod(np.diff(self.bounds, axis=1)) + s = prod(np.diff(self.bounds, axis=1)) return s @property @@ -35,8 +38,8 @@ def integrate(self, integration_boundaries=None) -> float: if integration_boundaries is None: integration_boundaries = self.bounds - integration_boundaries = np.reshape(integration_boundaries, (2, -1)) + integration_boundaries = reshape(integration_boundaries, (2, -1)) left, right = integration_boundaries integration_boundaries = zip(left, right) - return nquad(lambda *args: self.pdf(np.array(args)), integration_boundaries)[0] + return nquad(lambda *args: self.pdf(array(args)), integration_boundaries)[0] diff --git a/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py b/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py index 9319f48b..475e4734 100644 --- a/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py +++ b/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py @@ -1,3 +1,12 @@ +from pyrecest.backend import squeeze +from pyrecest.backend import sqrt +from pyrecest.backend import reshape +from pyrecest.backend import ndim +from pyrecest.backend import meshgrid +from pyrecest.backend import linspace +from pyrecest.backend import array +from pyrecest.backend import int64 +from pyrecest.backend import int32 import numbers from collections.abc import Callable @@ -34,12 +43,12 @@ def mode(self, starting_point=None): def mode_numerical(self, starting_point=None): if starting_point is None: # Ensure 1-D for minimize - starting_point = np.squeeze(self.sample(1)) + starting_point = squeeze(self.sample(1)) def neg_pdf(x): return -self.pdf(x) - assert np.ndim(starting_point) <= 1, "Starting point must be a 1D array" + assert ndim(starting_point) <= 1, "Starting point must be a 1D array" starting_point = np.atleast_1d( starting_point ) # Avoid numpy warning "DeprecationWarning: Use of `minimize` with `x0.ndim != 1` is deprecated" @@ -49,9 +58,9 @@ def neg_pdf(x): def sample_metropolis_hastings( self, - n: int | np.int32 | np.int64, - burn_in: int | np.int32 | np.int64 = 10, - skipping: int | np.int32 | np.int64 = 5, + n: int | int32 | int64, + burn_in: int | int32 | int64 = 10, + skipping: int | int32 | int64 = 5, proposal: Callable | None = None, start_point: np.number | numbers.Real | np.ndarray | None = None, ) -> np.ndarray: @@ -79,32 +88,32 @@ def mean_numerical(self): if self.dim == 1: mu = quad(lambda x: x * self.pdf(x), -np.inf, np.inf)[0] elif self.dim == 2: - mu = np.array([np.NaN, np.NaN]) + mu = array([np.NaN, np.NaN]) mu[0] = dblquad( - lambda x, y: x * self.pdf(np.array([x, y])), + lambda x, y: x * self.pdf(array([x, y])), -np.inf, np.inf, lambda _: -np.inf, lambda _: np.inf, )[0] mu[1] = dblquad( - lambda x, y: y * self.pdf(np.array([x, y])), + lambda x, y: y * self.pdf(array([x, y])), -np.inf, np.inf, lambda _: -np.inf, lambda _: np.inf, )[0] elif self.dim == 3: - mu = np.array([np.NaN, np.NaN, np.NaN]) + mu = array([np.NaN, np.NaN, np.NaN]) def integrand1(x, y, z): - return x * self.pdf(np.array([x, y, z])) + return x * self.pdf(array([x, y, z])) def integrand2(x, y, z): - return y * self.pdf(np.array([x, y, z])) + return y * self.pdf(array([x, y, z])) def integrand3(x, y, z): - return z * self.pdf(np.array([x, y, z])) + return z * self.pdf(array([x, y, z])) mu[0] = nquad( integrand1, [[-np.inf, np.inf], [-np.inf, np.inf], [-np.inf, np.inf]] @@ -126,16 +135,16 @@ def covariance_numerical(self): if self.dim == 1: C = quad(lambda x: (x - mu) ** 2 * self.pdf(x), -np.inf, np.inf)[0] elif self.dim == 2: - C = np.array([[np.NaN, np.NaN], [np.NaN, np.NaN]]) + C = array([[np.NaN, np.NaN], [np.NaN, np.NaN]]) def integrand1(x, y): - return (x - mu[0]) ** 2 * self.pdf(np.array([x, y])) + return (x - mu[0]) ** 2 * self.pdf(array([x, y])) def integrand2(x, y): - return (x - mu[0]) * (y - mu[1]) * self.pdf(np.array([x, y])) + return (x - mu[0]) * (y - mu[1]) * self.pdf(array([x, y])) def integrand3(x, y): - return (y - mu[1]) ** 2 * self.pdf(np.array([x, y])) + return (y - mu[1]) ** 2 * self.pdf(array([x, y])) C[0, 0] = nquad(integrand1, [[-np.inf, np.inf], [-np.inf, np.inf]])[0] C[0, 1] = nquad(integrand2, [[-np.inf, np.inf], [-np.inf, np.inf]])[0] @@ -171,7 +180,7 @@ def integrate_numerically(self, left=None, right=None): def integrate_fun_over_domain(f, dim, left, right): def f_for_nquad(*args): # Avoid DeprecationWarning: Conversion of an array with ndim > 0 to a scalar is deprecated, and will error in future. - return np.squeeze(f(np.array(args).reshape(-1, dim))) + return squeeze(f(array(args).reshape(-1, dim))) if dim == 1: result, _ = quad(f, left, right) @@ -207,8 +216,8 @@ def get_suggested_integration_limits(self, scaling_factor=10): right = np.full((self.dim,), np.nan) for i in range(self.dim): # Change for linear dimensions - left[i] = m[i] - scaling_factor * np.sqrt(C[i, i]) - right[i] = m[i] + scaling_factor * np.sqrt(C[i, i]) + left[i] = m[i] - scaling_factor * sqrt(C[i, i]) + right[i] = m[i] + scaling_factor * sqrt(C[i, i]) return left, right @@ -217,30 +226,30 @@ def plot(self, *args, plot_range=None, **kwargs): C = self.covariance() if plot_range is None: - scaling = np.sqrt(chi2.ppf(0.99, self.dim)) + scaling = sqrt(chi2.ppf(0.99, self.dim)) plot_range = empty(2 * self.dim) for i in range(0, 2 * self.dim, 2): - plot_range[i] = mu[int(i / 2)] - scaling * np.sqrt( + plot_range[i] = mu[int(i / 2)] - scaling * sqrt( C[int(i / 2), int(i / 2)] ) - plot_range[i + 1] = mu[int(i / 2)] + scaling * np.sqrt( + plot_range[i + 1] = mu[int(i / 2)] + scaling * sqrt( C[int(i / 2), int(i / 2)] ) if self.dim == 1: - x = np.linspace(plot_range[0], plot_range[1], 1000) + x = linspace(plot_range[0], plot_range[1], 1000) y = self.pdf(x) plt.plot(x, y, *args, **kwargs) plt.show() elif self.dim == 2: - x = np.linspace(plot_range[0], plot_range[1], 100) - y = np.linspace(plot_range[2], plot_range[3], 100) - x_grid, y_grid = np.meshgrid(x, y) + x = linspace(plot_range[0], plot_range[1], 100) + y = linspace(plot_range[2], plot_range[3], 100) + x_grid, y_grid = meshgrid(x, y) z_grid = self.pdf(np.column_stack((x_grid.ravel(), y_grid.ravel()))) ax = plt.axes(projection="3d") ax.plot_surface( - x_grid, y_grid, np.reshape(z_grid, x_grid.shape), *args, **kwargs + x_grid, y_grid, reshape(z_grid, x_grid.shape), *args, **kwargs ) plt.show() else: diff --git a/pyrecest/distributions/nonperiodic/custom_linear_distribution.py b/pyrecest/distributions/nonperiodic/custom_linear_distribution.py index 01cfa085..41bf1f03 100644 --- a/pyrecest/distributions/nonperiodic/custom_linear_distribution.py +++ b/pyrecest/distributions/nonperiodic/custom_linear_distribution.py @@ -1,3 +1,5 @@ +from pyrecest.backend import reshape +from pyrecest.backend import ndim import copy import numpy as np @@ -48,9 +50,9 @@ def pdf(self, xs): assert np.size(xs) % self.input_dim == 0 n_inputs = np.size(xs) // self.input_dim p = self.scale_by * self.f( - np.reshape(xs, (-1, self.input_dim)) - np.atleast_2d(self.shift_by) + reshape(xs, (-1, self.input_dim)) - np.atleast_2d(self.shift_by) ) - assert np.ndim(p) <= 1 and np.size(p) == n_inputs + assert ndim(p) <= 1 and np.size(p) == n_inputs return p @staticmethod diff --git a/pyrecest/distributions/nonperiodic/gaussian_distribution.py b/pyrecest/distributions/nonperiodic/gaussian_distribution.py index 25bb49d8..a6d512e6 100644 --- a/pyrecest/distributions/nonperiodic/gaussian_distribution.py +++ b/pyrecest/distributions/nonperiodic/gaussian_distribution.py @@ -1,3 +1,5 @@ +from pyrecest.backend import ndim +from pyrecest.backend import dot import copy import numpy as np @@ -15,7 +17,7 @@ def __init__(self, mu: np.ndarray, C: np.ndarray, check_validity=True): assert ( 1 == np.size(mu) == np.size(C) or np.size(mu) == C.shape[0] == C.shape[1] ), "Size of C invalid" - assert np.ndim(mu) <= 1 + assert ndim(mu) <= 1 self.mu = mu if check_validity: @@ -64,8 +66,8 @@ def covariance(self): def multiply(self, other): assert self.dim == other.dim K = np.linalg.solve(self.C + other.C, self.C) - new_mu = self.mu + np.dot(K, (other.mu - self.mu)) - new_C = self.C - np.dot(K, self.C) + new_mu = self.mu + dot(K, (other.mu - self.mu)) + new_C = self.C - dot(K, self.C) return GaussianDistribution(new_mu, new_C, check_validity=False) def convolve(self, other): diff --git a/pyrecest/distributions/nonperiodic/gaussian_mixture.py b/pyrecest/distributions/nonperiodic/gaussian_mixture.py index 19703a6c..acdb582e 100644 --- a/pyrecest/distributions/nonperiodic/gaussian_mixture.py +++ b/pyrecest/distributions/nonperiodic/gaussian_mixture.py @@ -1,3 +1,8 @@ +from pyrecest.backend import sum +from pyrecest.backend import stack +from pyrecest.backend import ones +from pyrecest.backend import dot +from pyrecest.backend import array import numbers import numpy as np @@ -17,7 +22,7 @@ def __init__(self, dists: list[GaussianDistribution], w: np.ndarray): def mean(self): gauss_array = self.dists - return np.dot(np.array([g.mu for g in gauss_array]), self.w) + return dot(array([g.mu for g in gauss_array]), self.w) @beartype def set_mean(self, new_mean: np.ndarray | numbers.Real): @@ -28,8 +33,8 @@ def set_mean(self, new_mean: np.ndarray | numbers.Real): def to_gaussian(self): gauss_array = self.dists mu, C = self.mixture_parameters_to_gaussian_parameters( - np.array([g.mu for g in gauss_array]), - np.stack([g.C for g in gauss_array], axis=2), + array([g.mu for g in gauss_array]), + stack([g.C for g in gauss_array], axis=2), self.w, ) return GaussianDistribution(mu, C) @@ -37,8 +42,8 @@ def to_gaussian(self): def covariance(self): gauss_array = self.dists _, C = self.mixture_parameters_to_gaussian_parameters( - np.array([g.mu for g in gauss_array]), - np.stack([g.C for g in gauss_array], axis=2), + array([g.mu for g in gauss_array]), + stack([g.C for g in gauss_array], axis=2), self.w, ) return C @@ -48,9 +53,9 @@ def mixture_parameters_to_gaussian_parameters( means, covariance_matrices, weights=None ): if weights is None: - weights = np.ones(means.shape[1]) / means.shape[1] + weights = ones(means.shape[1]) / means.shape[1] - C_from_cov = np.sum(covariance_matrices * weights.reshape(1, 1, -1), axis=2) + C_from_cov = sum(covariance_matrices * weights.reshape(1, 1, -1), axis=2) mu, C_from_means = LinearDiracDistribution.weighted_samples_to_mean_and_cov( means, weights ) diff --git a/pyrecest/distributions/nonperiodic/linear_dirac_distribution.py b/pyrecest/distributions/nonperiodic/linear_dirac_distribution.py index 579436c1..dc941bd4 100644 --- a/pyrecest/distributions/nonperiodic/linear_dirac_distribution.py +++ b/pyrecest/distributions/nonperiodic/linear_dirac_distribution.py @@ -1,3 +1,5 @@ +from pyrecest.backend import reshape +from pyrecest.backend import ones import matplotlib.pyplot as plt import numpy as np @@ -16,7 +18,7 @@ def mean(self): def set_mean(self, new_mean): mean_offset = new_mean - self.mean - self.d += np.reshape(mean_offset, (1, -1)) + self.d += reshape(mean_offset, (1, -1)) def covariance(self): _, C = LinearDiracDistribution.weighted_samples_to_mean_and_cov(self.d, self.w) @@ -41,12 +43,12 @@ def plot(self, *args, **kwargs): @staticmethod def from_distribution(distribution, n_particles): samples = distribution.sample(n_particles) - return LinearDiracDistribution(samples, np.ones(n_particles) / n_particles) + return LinearDiracDistribution(samples, ones(n_particles) / n_particles) @staticmethod def weighted_samples_to_mean_and_cov(samples, weights=None): if weights is None: - weights = np.ones(samples.shape[1]) / samples.shape[1] + weights = ones(samples.shape[1]) / samples.shape[1] mean = np.average(samples, weights=weights, axis=0) deviation = samples - mean diff --git a/pyrecest/distributions/se3_dirac_distribution.py b/pyrecest/distributions/se3_dirac_distribution.py index aad19d0c..1a3f6120 100644 --- a/pyrecest/distributions/se3_dirac_distribution.py +++ b/pyrecest/distributions/se3_dirac_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import ones import numpy as np from .abstract_se3_distribution import AbstractSE3Distribution @@ -42,6 +43,6 @@ def from_distribution(distribution, n_particles): ddist = SE3DiracDistribution( distribution.sample(n_particles), - 1 / n_particles * np.ones((1, n_particles)), + 1 / n_particles * ones((1, n_particles)), ) return ddist diff --git a/pyrecest/evaluation/determine_all_deviations.py b/pyrecest/evaluation/determine_all_deviations.py index f76a4e36..d0d4b048 100644 --- a/pyrecest/evaluation/determine_all_deviations.py +++ b/pyrecest/evaluation/determine_all_deviations.py @@ -1,3 +1,7 @@ +from pyrecest.backend import sum +from pyrecest.backend import ndim +from pyrecest.backend import any +from pyrecest.backend import empty import warnings from typing import Callable @@ -17,16 +21,16 @@ def determine_all_deviations( raise NotImplementedError("Not implemented yet") assert ( - np.ndim(groundtruths) == 2 + ndim(groundtruths) == 2 and isinstance(groundtruths[0, 0], np.ndarray) - and np.ndim(groundtruths[0, 0]) + and ndim(groundtruths[0, 0]) in ( 1, 2, ) ), "Assuming groundtruths to be a 2-D array of shape (n_runs, n_timesteps) composed arrays of shape (n_dim,) or (n_targets,n_dim)." - all_deviations_last_mat = np.empty((len(results), groundtruths.shape[0])) + all_deviations_last_mat = empty((len(results), groundtruths.shape[0])) for config_no, result_curr_config in enumerate(results): for run in range(len(groundtruths)): @@ -47,10 +51,10 @@ def determine_all_deviations( warnings.warn("No estimate for this filter, setting error to inf.") all_deviations_last_mat[config_no][run] = np.inf - if np.any(np.isinf(all_deviations_last_mat[config_no])): + if any(np.isinf(all_deviations_last_mat[config_no])): print( f"Warning: {result_curr_config['filterName']} with {result_curr_config['filterParams']} " - f"parameters apparently failed {np.sum(np.isinf(all_deviations_last_mat[config_no]))} " + f"parameters apparently failed {sum(np.isinf(all_deviations_last_mat[config_no]))} " "times. Check if this is plausible." ) diff --git a/pyrecest/evaluation/eot_shape_database.py b/pyrecest/evaluation/eot_shape_database.py index 92d5adba..41ce34cf 100644 --- a/pyrecest/evaluation/eot_shape_database.py +++ b/pyrecest/evaluation/eot_shape_database.py @@ -1,3 +1,8 @@ +from pyrecest.backend import sin +from pyrecest.backend import linspace +from pyrecest.backend import cos +from pyrecest.backend import array +from pyrecest.backend import empty import numpy as np from shapely.geometry import LineString, MultiLineString, Point, Polygon from shapely.ops import unary_union @@ -12,7 +17,7 @@ def __new__(cls, shell=None, holes=None): # nosec return polygon def sample_on_boundary(self, num_points: int) -> np.ndarray: - points = np.empty((num_points,), dtype=Point) + points = empty((num_points,), dtype=Point) if isinstance(self.boundary, LineString): lines = [self.boundary] @@ -33,11 +38,11 @@ def sample_on_boundary(self, num_points: int) -> np.ndarray: break distance -= line.length - return np.array([(point.x, point.y) for point in points]) + return array([(point.x, point.y) for point in points]) def sample_within(self, num_points: int) -> np.ndarray: min_x, min_y, max_x, max_y = self.bounds - points = np.empty((num_points,), dtype=Point) + points = empty((num_points,), dtype=Point) for i in range(num_points): random_point = Point( @@ -53,7 +58,7 @@ def sample_within(self, num_points: int) -> np.ndarray: points[i] = random_point - return np.array(points) + return array(points) class StarShapedPolygon(PolygonWithSampling): # pylint: disable=abstract-method @@ -103,8 +108,8 @@ def compute_visibility_polygon(self, point): segments.append(line_of_sight) # Check for intersections along the direction to the vertex - direction = np.array(vertex) - np.array(point.coords) - far_away_point = Point(np.array(vertex) + 1000 * direction) + direction = array(vertex) - array(point.coords) + far_away_point = Point(array(vertex) + 1000 * direction) ray = LineString([point, far_away_point]) # Find intersection points with the polygon boundary @@ -135,15 +140,15 @@ def __new__(cls, radius=1, arms=5, arm_width=0.3, center=(0, 0)): # External point points.append( ( - center[0] + radius * np.cos(base_angle), - center[1] + radius * np.sin(base_angle), + center[0] + radius * cos(base_angle), + center[1] + radius * sin(base_angle), ) ) # Internal point points.append( ( - center[0] + arm_width * np.cos(inner_angle), - center[1] + arm_width * np.sin(inner_angle), + center[0] + arm_width * cos(inner_angle), + center[1] + arm_width * sin(inner_angle), ) ) # Close the loop @@ -174,7 +179,7 @@ def __new__(cls, height_1, height_2, width_1, width_2, centroid=None): half_width_2 = width_2 / 2 # Define polygon points - polygon_points = np.array( + polygon_points = array( [ [half_width_1, half_height_1], [half_height_2, half_height_1], @@ -206,11 +211,11 @@ class StarFish(StarShapedPolygon): # pylint: disable=abstract-method # pylint: disable=signature-differs def __new__(cls, scaling_factor=1): - theta = np.linspace(0, 2 * np.pi, 1000) - r = 5 + 1.5 * np.sin(6 * theta) + theta = linspace(0, 2 * np.pi, 1000) + r = 5 + 1.5 * sin(6 * theta) - x = r * np.cos(theta) * scaling_factor - y = r * np.sin(theta) * scaling_factor + x = r * cos(theta) * scaling_factor + y = r * sin(theta) * scaling_factor # Create polygon instance polygon = super().__new__(cls, shell=zip(x, y), holes=None) # nosec diff --git a/pyrecest/evaluation/evaluate_for_file.py b/pyrecest/evaluation/evaluate_for_file.py index 14f4de63..5d91e18c 100644 --- a/pyrecest/evaluation/evaluate_for_file.py +++ b/pyrecest/evaluation/evaluate_for_file.py @@ -1,3 +1,6 @@ +from pyrecest.backend import ones +from pyrecest.backend import concatenate +from pyrecest.backend import zeros import os from typing import Any @@ -39,7 +42,7 @@ def evaluate_for_file( else: scenario_config["n_timesteps"] = data["groundtruths"].shape[1] - n_meas_at_individual_time_step = np.zeros(data["measurements"].shape[1], dtype=int) + n_meas_at_individual_time_step = zeros(data["measurements"].shape[1], dtype=int) for idx, inner_array in enumerate(data["measurements"][0]): if inner_array.ndim == 2: @@ -52,8 +55,8 @@ def evaluate_for_file( ) scenario_config.setdefault( "apply_sys_noise_times", - np.concatenate( - [np.ones(scenario_config["n_timesteps"] - 1, dtype=bool), [False]] + concatenate( + [ones(scenario_config["n_timesteps"] - 1, dtype=bool), [False]] ), ) diff --git a/pyrecest/evaluation/generate_groundtruth.py b/pyrecest/evaluation/generate_groundtruth.py index 940fb30e..8666f4ea 100644 --- a/pyrecest/evaluation/generate_groundtruth.py +++ b/pyrecest/evaluation/generate_groundtruth.py @@ -1,3 +1,7 @@ +from pyrecest.backend import squeeze +from pyrecest.backend import ndim +from pyrecest.backend import empty +from pyrecest.backend import empty_like import numpy as np @@ -19,13 +23,13 @@ def generate_groundtruth(simulation_param, x0=None): x0 = simulation_param["initial_prior"].sample(simulation_param["n_targets"]) assert ( - np.ndim(x0) == 1 + ndim(x0) == 1 and simulation_param["n_targets"] == 1 or x0.shape[0] == simulation_param["n_targets"] ), "Mismatch in number of targets." # Initialize ground truth - groundtruth = np.empty(simulation_param["n_timesteps"], dtype=np.ndarray) + groundtruth = empty(simulation_param["n_timesteps"], dtype=np.ndarray) if "inputs" in simulation_param: assert ( @@ -35,7 +39,7 @@ def generate_groundtruth(simulation_param, x0=None): groundtruth[0] = np.atleast_2d(x0) for t in range(1, simulation_param["n_timesteps"]): - groundtruth[t] = np.empty_like(groundtruth[0]) + groundtruth[t] = empty_like(groundtruth[0]) for target_no in range(simulation_param["n_targets"]): if "gen_next_state_with_noise" in simulation_param: if ( @@ -86,6 +90,6 @@ def generate_groundtruth(simulation_param, x0=None): assert groundtruth[0].shape[0] == simulation_param["n_targets"] assert groundtruth[0].shape[1] == simulation_param["initial_prior"].dim for t in range(simulation_param["n_timesteps"]): - groundtruth[t] = np.squeeze(groundtruth[t]) + groundtruth[t] = squeeze(groundtruth[t]) return groundtruth diff --git a/pyrecest/evaluation/generate_measurements.py b/pyrecest/evaluation/generate_measurements.py index 216a34f6..708da392 100644 --- a/pyrecest/evaluation/generate_measurements.py +++ b/pyrecest/evaluation/generate_measurements.py @@ -1,3 +1,11 @@ +from pyrecest.backend import tile +from pyrecest.backend import sum +from pyrecest.backend import squeeze +from pyrecest.backend import shape +from pyrecest.backend import mod +from pyrecest.backend import dot +from pyrecest.backend import empty +from pyrecest.backend import zeros import numpy as np from beartype import beartype from pyrecest.distributions import ( @@ -27,10 +35,10 @@ def generate_measurements(groundtruth, simulation_config): Comprises timesteps elements, each of which is a numpy array of shape (n_meas_at_individual_time_step[t], n_dim). """ - assert "n_meas_at_individual_time_step" not in simulation_config or np.shape( + assert "n_meas_at_individual_time_step" not in simulation_config or shape( simulation_config["n_meas_at_individual_time_step"] ) == (simulation_config["n_timesteps"],) - measurements = np.empty(simulation_config["n_timesteps"], dtype=np.ndarray) + measurements = empty(simulation_config["n_timesteps"], dtype=np.ndarray) if simulation_config.get("mtt", False) and simulation_config.get("eot", False): raise NotImplementedError( @@ -47,21 +55,21 @@ def generate_measurements(groundtruth, simulation_config): assert ("intensity_lambda" in simulation_config.keys()) != ( "n_meas_at_individual_time_step" in simulation_config.keys() ), "Must either give intensity_lambda or n_meas_at_individual_time_step for EOT" - shape = simulation_config["target_shape"] + target_shape = simulation_config["target_shape"] eot_sampling_style = simulation_config["eot_sampling_style"] assert isinstance( - shape, Polygon + target_shape, Polygon ), "Currently only StarConvexPolygon (based on shapely Polygons) are supported as target shapes." for t in range(simulation_config["n_timesteps"]): if groundtruth[0].shape[-1] == 2: curr_shape = translate( - shape, groundtruth[0][..., 0], yoff=groundtruth[0][..., 1] + target_shape, groundtruth[0][..., 0], yoff=groundtruth[0][..., 1] ) elif groundtruth[0].shape[-1] == 3: curr_shape = rotate( translate( - shape, groundtruth[0][..., 1], yoff=groundtruth[0][..., 2] + target_shape, groundtruth[0][..., 1], yoff=groundtruth[0][..., 2] ), angle=groundtruth[0][..., 0], origin="centroid", @@ -70,7 +78,7 @@ def generate_measurements(groundtruth, simulation_config): raise ValueError( "Currently only R^2 and SE(2) scenarios are supported." ) - if not isinstance(shape, PolygonWithSampling): + if not isinstance(target_shape, PolygonWithSampling): curr_shape.__class__ = ( PolygonWithSampling # Evil class sugery to add sampling methods ) @@ -115,8 +123,8 @@ def generate_measurements(groundtruth, simulation_config): ) for t in range(simulation_config["n_timesteps"]): - n_meas_at_t = np.sum(n_observations[t, :]) - measurements[t] = np.nan * np.zeros( + n_meas_at_t = sum(n_observations[t, :]) + measurements[t] = np.nan * zeros( (simulation_config["meas_matrix_for_each_target"].shape[0], n_meas_at_t) ) @@ -124,7 +132,7 @@ def generate_measurements(groundtruth, simulation_config): for target_no in range(simulation_config["n_targets"]): if n_observations[t, target_no] == 1: meas_no += 1 - measurements[t][meas_no - 1, :] = np.dot( + measurements[t][meas_no - 1, :] = dot( simulation_config["meas_matrix_for_each_target"], groundtruth[t, target_no, :], ) + simulation_config["meas_noise"].sample(1) @@ -146,9 +154,9 @@ def generate_measurements(groundtruth, simulation_config): if isinstance(meas_noise, AbstractHypertoroidalDistribution): noise_samples = meas_noise.sample(n_meas) - measurements[t] = np.mod( - np.squeeze( - np.tile( + measurements[t] = mod( + squeeze( + tile( groundtruth[t - 1], ( n_meas, @@ -169,8 +177,8 @@ def generate_measurements(groundtruth, simulation_config): elif isinstance(meas_noise, GaussianDistribution): noise_samples = meas_noise.sample(n_meas) - measurements[t] = np.squeeze( - np.tile( + measurements[t] = squeeze( + tile( groundtruth[t - 1], ( n_meas, diff --git a/pyrecest/evaluation/generate_simulated_scenarios.py b/pyrecest/evaluation/generate_simulated_scenarios.py index 46a5c7cf..a292e9cb 100644 --- a/pyrecest/evaluation/generate_simulated_scenarios.py +++ b/pyrecest/evaluation/generate_simulated_scenarios.py @@ -1,3 +1,4 @@ +from pyrecest.backend import empty import numpy as np from .check_and_fix_config import check_and_fix_config @@ -21,11 +22,11 @@ def generate_simulated_scenarios( """ simulation_params = check_and_fix_config(simulation_params) - groundtruths = np.empty( + groundtruths = empty( (np.size(simulation_params["all_seeds"]), simulation_params["n_timesteps"]), dtype=np.ndarray, ) - measurements = np.empty( + measurements = empty( (np.size(simulation_params["all_seeds"]), simulation_params["n_timesteps"]), dtype=np.ndarray, ) diff --git a/pyrecest/evaluation/get_distance_function.py b/pyrecest/evaluation/get_distance_function.py index 9cc158c7..c5f5ed18 100644 --- a/pyrecest/evaluation/get_distance_function.py +++ b/pyrecest/evaluation/get_distance_function.py @@ -1,3 +1,5 @@ +from pyrecest.backend import dot +from pyrecest.backend import arccos import numpy as np from numpy.linalg import norm from pyrecest.distributions import AbstractHypertoroidalDistribution @@ -17,12 +19,12 @@ def distance_function(xest, xtrue): elif "hypersphere" in manifold_name: def distance_function(x1, x2): - return np.arccos(np.dot(x1, x2)) + return arccos(dot(x1, x2)) elif "hypersphereSymmetric" in manifold_name: def distance_function(x1, x2): - return min(np.arccos(np.dot(x1, x2)), np.arccos(np.dot(x1, -x2))) + return min(arccos(dot(x1, x2)), arccos(dot(x1, -x2))) elif "se2" in manifold_name or "se2linear" in manifold_name: @@ -45,7 +47,7 @@ def distance_function(x1, x2): def distance_function(x1, x2): return min( - np.arccos(np.dot(x1[:4], x2[:4])), np.arccos(np.dot(x1[:4], -x2[:4])) + arccos(dot(x1[:4], x2[:4])), arccos(dot(x1[:4], -x2[:4])) ) elif ( diff --git a/pyrecest/evaluation/iterate_configs_and_runs.py b/pyrecest/evaluation/iterate_configs_and_runs.py index 794a809e..020aa8ab 100644 --- a/pyrecest/evaluation/iterate_configs_and_runs.py +++ b/pyrecest/evaluation/iterate_configs_and_runs.py @@ -1,3 +1,5 @@ +from pyrecest.backend import empty +from pyrecest.backend import zeros import warnings from typing import Any, Dict @@ -22,13 +24,13 @@ def iterate_configs_and_runs( n_configs = sum(np.size(f["parameter"]) for f in filter_configs) n_runs = groundtruths.shape[0] - run_times = np.empty((n_configs, n_runs)) - run_failed = np.zeros((n_configs, n_runs), dtype=bool) + run_times = empty((n_configs, n_runs)) + run_failed = zeros((n_configs, n_runs), dtype=bool) if evaluation_config["convert_to_point_estimate_during_runtime"]: raise NotImplementedError("This is not implemented yet.") - last_filter_states = np.empty((n_configs, n_runs), dtype=object) + last_filter_states = empty((n_configs, n_runs), dtype=object) for run in range(n_runs): for config_no, filter_config in enumerate(filter_configs): diff --git a/pyrecest/evaluation/perform_predict_update_cycles.py b/pyrecest/evaluation/perform_predict_update_cycles.py index 1b63b37b..24b6b2a8 100644 --- a/pyrecest/evaluation/perform_predict_update_cycles.py +++ b/pyrecest/evaluation/perform_predict_update_cycles.py @@ -1,3 +1,6 @@ +from pyrecest.backend import squeeze +from pyrecest.backend import array +from pyrecest.backend import empty import time import warnings @@ -17,7 +20,7 @@ def perform_predict_update_cycles( cumulated_updates_preferred=None, ): if extract_all_estimates: - all_estimates = np.empty_like(groundtruth) + all_estimates = empty_like(groundtruth) else: all_estimates = None @@ -28,11 +31,11 @@ def perform_predict_update_cycles( # Check conditions for cumulative updates perform_cumulative_updates = cumulated_updates_preferred and any( - np.array(scenario_config["n_meas_at_individual_time_step"]) > 1 + array(scenario_config["n_meas_at_individual_time_step"]) > 1 ) if ( cumulated_updates_preferred - and any(np.array(scenario_config["n_meas_at_individual_time_step"]) > 1) + and any(array(scenario_config["n_meas_at_individual_time_step"]) > 1) and scenario_config.get("plot", False) ): warnings.warn("When plotting, measurements are fused sequentially.") @@ -56,7 +59,7 @@ def perform_predict_update_cycles( if not scenario_config.get("use_likelihood", False): filter_obj.update_identity( - meas_noise=meas_noise_for_filter, measurement=np.squeeze(curr_meas) + meas_noise=meas_noise_for_filter, measurement=squeeze(curr_meas) ) # If plotting is required diff --git a/pyrecest/evaluation/plot_results.py b/pyrecest/evaluation/plot_results.py index 273ac830..8440d630 100644 --- a/pyrecest/evaluation/plot_results.py +++ b/pyrecest/evaluation/plot_results.py @@ -1,3 +1,8 @@ +from pyrecest.backend import shape +from pyrecest.backend import ones +from pyrecest.backend import isnan +from pyrecest.backend import array +from pyrecest.backend import any import warnings import matplotlib.pyplot as plt @@ -18,7 +23,7 @@ def plot_results( Args: filenames (str or list): File names to load results from. - plot_log (np.array of bool): Whether to plot in log scale for each axis. + plot_log (array of bool): Whether to plot in log scale for each axis. plot_stds (bool): Whether to plot standard deviations. omit_slow (bool): Whether to omit slow filters from plotting. @@ -32,9 +37,9 @@ def plot_results( # Expand plot_log to handle all plots (pad it) if np.size(plot_log) == 1: - plot_log = False * np.ones((2, 3), dtype=bool) + plot_log = False * ones((2, 3), dtype=bool) else: - assert np.shape(plot_log) == (2, 3) + assert shape(plot_log) == (2, 3) plot_random_filter = True if filename is None: @@ -76,7 +81,7 @@ def plot_results( plt.figure(0) if ( params[0] is not None - and not np.any(np.isnan(params)) + and not any(isnan(params)) and np.size(params) > 1 ): if plot_stds: @@ -115,7 +120,7 @@ def plot_results( plt.figure(1) if ( params[0] is not None - and not np.any(np.isnan(params)) + and not any(isnan(params)) and np.size(params) > 1 ): plt.plot( @@ -145,7 +150,7 @@ def plot_results( plt.figure(2) if ( params[0] is not None - and not np.any(np.isnan(params)) + and not any(isnan(params)) and np.size(params) > 1 ): plt.plot( diff --git a/pyrecest/evaluation/simulation_database.py b/pyrecest/evaluation/simulation_database.py index c04fdaa7..f9e38af2 100644 --- a/pyrecest/evaluation/simulation_database.py +++ b/pyrecest/evaluation/simulation_database.py @@ -1,3 +1,4 @@ +from pyrecest.backend import eye, zeros import warnings from typing import Optional @@ -28,13 +29,13 @@ def simulation_database( simulation_param["manifold"] = "Euclidean" simulation_param["n_timesteps"] = 10 simulation_param["initial_prior"] = GaussianDistribution( - np.zeros(2), 0.5 * np.eye(2) + zeros(2), 0.5 * eye(2) ) simulation_param["meas_noise"] = GaussianDistribution( - np.zeros(2), 0.5 * np.eye(2) + zeros(2), 0.5 * eye(2) ) simulation_param["sys_noise"] = GaussianDistribution( - np.zeros(2), 0.5 * np.eye(2) + zeros(2), 0.5 * eye(2) ) simulation_param["gen_next_state_without_noise_is_vectorized"] = True else: diff --git a/pyrecest/evaluation/summarize_filter_results.py b/pyrecest/evaluation/summarize_filter_results.py index df7fb0b6..40dcb210 100644 --- a/pyrecest/evaluation/summarize_filter_results.py +++ b/pyrecest/evaluation/summarize_filter_results.py @@ -1,3 +1,6 @@ +from pyrecest.backend import sum +from pyrecest.backend import std +from pyrecest.backend import mean import warnings import numpy as np @@ -40,18 +43,18 @@ def summarize_filter_results( errors_all = determine_all_deviations( filter_results, extract_mean, distance_function, groundtruths ) - errors_mean = np.mean(errors_all, axis=1) - errors_std = np.std(errors_all, axis=1) - times_mean = np.mean(runtimes, axis=1) - failure_rates = np.sum(run_failed, axis=1) / run_failed.shape[1] + errors_mean = mean(errors_all, axis=1) + errors_std = std(errors_all, axis=1) + times_mean = mean(runtimes, axis=1) + failure_rates = sum(run_failed, axis=1) / run_failed.shape[1] results_summarized = filter_configs - for d, err, std, time, fail_rate in zip( + for d, curr_err, curr_std, curr_time, curr_fail_rate in zip( results_summarized, errors_mean, errors_std, times_mean, failure_rates ): - d["error_mean"] = err - d["error_std"] = std - d["time_mean"] = time - d["failure_rate"] = fail_rate + d["error_mean"] = curr_err + d["error_std"] = curr_std + d["time_mean"] = curr_time + d["failure_rate"] = curr_fail_rate return results_summarized diff --git a/pyrecest/filters/abstract_nearest_neighbor_tracker.py b/pyrecest/filters/abstract_nearest_neighbor_tracker.py index 95767d03..a3665c40 100644 --- a/pyrecest/filters/abstract_nearest_neighbor_tracker.py +++ b/pyrecest/filters/abstract_nearest_neighbor_tracker.py @@ -1,3 +1,6 @@ +from pyrecest.backend import ndim +from pyrecest.backend import all +from pyrecest.backend import empty import copy import warnings from abc import abstractmethod @@ -85,7 +88,7 @@ def predict_linear(self, system_matrices, sys_noises, inputs=None): ), "system_matrices may be a single (dimSingleState, dimSingleState) matrix or a (dimSingleState, dimSingleState, noTargets) tensor." if isinstance(sys_noises, GaussianDistribution): - assert np.all(sys_noises.mu == 0) + assert all(sys_noises.mu == 0) sys_noises = np.dstack(sys_noises.C) curr_sys_matrix = system_matrices @@ -94,11 +97,11 @@ def predict_linear(self, system_matrices, sys_noises, inputs=None): for i in range(self.get_number_of_targets()): # Overwrite if different for each track - if np.ndim(system_matrices) == 3: + if ndim(system_matrices) == 3: curr_sys_matrix = system_matrices[:, :, i] - if np.ndim(sys_noises) == 3: + if ndim(sys_noises) == 3: curr_sys_noise = sys_noises[:, :, i] - if np.ndim(inputs) == 2: + if ndim(inputs) == 2: curr_input = inputs[:, i] self.filter_bank[i].predict_linear( @@ -140,7 +143,7 @@ def get_point_estimate(self, flatten_vector=False): warnings.warn("Currently, there are zero targets.") point_ests = None else: - point_ests = np.empty((self.dim, num_targets)) + point_ests = empty((self.dim, num_targets)) point_ests[:] = np.nan for i in range(num_targets): point_ests[:, i] = self.filter_bank[i].get_point_estimate() diff --git a/pyrecest/filters/abstract_particle_filter.py b/pyrecest/filters/abstract_particle_filter.py index f6a714a1..88dce73d 100644 --- a/pyrecest/filters/abstract_particle_filter.py +++ b/pyrecest/filters/abstract_particle_filter.py @@ -1,4 +1,9 @@ +from pyrecest.backend import sum +from pyrecest.backend import ones_like +from pyrecest.backend import ones +from pyrecest.backend import ndim from collections.abc import Callable +from pyrecest.backend import zeros import numpy as np from beartype import beartype @@ -48,10 +53,10 @@ def predict_nonlinear_nonadditive(self, f, samples, weights): samples.shape[0] == weights.size ), "samples and weights must match in size" - weights = weights / np.sum(weights) + weights = weights / sum(weights) n = self.filter_state.w.size noise_ids = np.random.choice(weights.size, n, p=weights) - d = np.zeros((n, self.filter_state.dim)) + d = zeros((n, self.filter_state.dim)) for i in range(n): d[i, :] = f(self.filter_state.d[i, :], samples[noise_ids[i]]) @@ -63,8 +68,8 @@ def update_identity( ): assert measurement is None or np.size(measurement) == meas_noise.dim assert ( - np.ndim(measurement) == 1 - or np.ndim(measurement) == 0 + ndim(measurement) == 1 + or ndim(measurement) == 0 and meas_noise.dim == 1 ) if not shift_instead_of_add: @@ -86,12 +91,12 @@ def update_nonlinear_using_likelihood(self, likelihood, measurement=None): self.filter_state.d = self.filter_state.sample(self.filter_state.w.shape[0]) self.filter_state.w = ( - 1 / self.filter_state.w.shape[0] * np.ones_like(self.filter_state.w) + 1 / self.filter_state.w.shape[0] * ones_like(self.filter_state.w) ) @beartype def association_likelihood(self, likelihood: AbstractManifoldSpecificDistribution): - likelihood_val = np.sum( + likelihood_val = sum( likelihood.pdf(self.filter_state.d) * self.filter_state.w ) return likelihood_val diff --git a/pyrecest/filters/abstract_tracker_with_logging.py b/pyrecest/filters/abstract_tracker_with_logging.py index 622e95cf..87822ad0 100644 --- a/pyrecest/filters/abstract_tracker_with_logging.py +++ b/pyrecest/filters/abstract_tracker_with_logging.py @@ -1,3 +1,5 @@ +from pyrecest.backend import hstack +from pyrecest.backend import array from abc import ABC import numpy as np @@ -10,7 +12,7 @@ def __init__(self, **kwargs): if value: # Remove the 'log_' prefix from the key clean_key = key[4:] if key.startswith("log_") else key - setattr(self, f"{clean_key}_over_time", np.array([[]])) + setattr(self, f"{clean_key}_over_time", array([[]])) def _store_estimates(self, curr_ests, estimates_over_time): # Ensure curr_ests is a 2D array @@ -24,7 +26,7 @@ def _store_estimates(self, curr_ests, estimates_over_time): curr_ests = np.pad( curr_ests, ((0, m - n), (0, 0)), mode="constant", constant_values=np.nan ) - estimates_over_time = np.hstack((estimates_over_time, curr_ests)) + estimates_over_time = hstack((estimates_over_time, curr_ests)) else: estimates_over_time_new = np.full((n, t + 1), np.nan) estimates_over_time_new[:m, :t] = estimates_over_time diff --git a/pyrecest/filters/circular_particle_filter.py b/pyrecest/filters/circular_particle_filter.py index fdc26a2d..d5a731d4 100644 --- a/pyrecest/filters/circular_particle_filter.py +++ b/pyrecest/filters/circular_particle_filter.py @@ -1,10 +1,14 @@ +from pyrecest.backend import sum +from pyrecest.backend import float64 +from pyrecest.backend import int64 +from pyrecest.backend import int32 import numpy as np from .hypertoroidal_particle_filter import HypertoroidalParticleFilter class CircularParticleFilter(HypertoroidalParticleFilter): - def __init__(self, n_particles: int | np.int32 | np.int64) -> None: + def __init__(self, n_particles: int | int32 | int64) -> None: """ Initialize the CircularParticleFilter. @@ -12,7 +16,7 @@ def __init__(self, n_particles: int | np.int32 | np.int64) -> None: """ super().__init__(n_particles, 1) - def compute_association_likelihood(self, likelihood) -> np.float64: + def compute_association_likelihood(self, likelihood) -> float64: """ Compute the likelihood of association based on the PDF of the likelihood and the filter state. @@ -20,7 +24,7 @@ def compute_association_likelihood(self, likelihood) -> np.float64: :param likelihood: likelihood object with a PDF method :return: association likelihood value """ - likelihood_val = np.sum( + likelihood_val = sum( likelihood.pdf(self.filter_state.d) * self.filter_state.w ) return likelihood_val diff --git a/pyrecest/filters/euclidean_particle_filter.py b/pyrecest/filters/euclidean_particle_filter.py index 85ca246d..4003ac73 100644 --- a/pyrecest/filters/euclidean_particle_filter.py +++ b/pyrecest/filters/euclidean_particle_filter.py @@ -1,3 +1,6 @@ +from pyrecest.backend import int64 +from pyrecest.backend import int32 +from pyrecest.backend import zeros import copy from collections.abc import Callable @@ -19,15 +22,15 @@ class EuclideanParticleFilter(AbstractParticleFilter, AbstractEuclideanFilter): def __init__( self, - n_particles: int | np.int32 | np.int64, - dim: int | np.int32 | np.int64, + n_particles: int | int32 | int64, + dim: int | int32 | int64, ): if not (isinstance(n_particles, int) and n_particles > 0): raise ValueError("n_particles must be a positive integer") if not (isinstance(dim, int) and dim > 0): raise ValueError("dim must be a positive integer") - initial_distribution = LinearDiracDistribution(np.zeros((n_particles, dim))) + initial_distribution = LinearDiracDistribution(zeros((n_particles, dim))) AbstractParticleFilter.__init__(self, initial_distribution) AbstractEuclideanFilter.__init__(self, initial_distribution) diff --git a/pyrecest/filters/global_nearest_neighbor.py b/pyrecest/filters/global_nearest_neighbor.py index b1e0c57a..2c2160d3 100644 --- a/pyrecest/filters/global_nearest_neighbor.py +++ b/pyrecest/filters/global_nearest_neighbor.py @@ -1,3 +1,9 @@ +from pyrecest.backend import stack +from pyrecest.backend import squeeze +from pyrecest.backend import repeat +from pyrecest.backend import any +from pyrecest.backend import all +from pyrecest.backend import empty import numpy as np from scipy.optimize import linear_sum_assignment from scipy.spatial.distance import cdist @@ -42,8 +48,8 @@ def find_association( assert cov_mats_meas.ndim == 2 or cov_mats_meas.shape[2] == n_meas all_gaussians = [filter.filter_state for filter in self.filter_bank] - all_means_prior = np.stack([gaussian.mu for gaussian in all_gaussians], axis=1) - all_cov_mats_prior = np.stack( + all_means_prior = stack([gaussian.mu for gaussian in all_gaussians], axis=1) + all_cov_mats_prior = stack( [gaussian.C for gaussian in all_gaussians], axis=2 ) @@ -52,19 +58,19 @@ def find_association( measurements.T, (measurement_matrix @ all_means_prior).T, "euclidean" ).T elif self.association_param["distance_metric_pos"].lower() == "mahalanobis": - dists = np.empty((n_targets, n_meas)) + dists = empty((n_targets, n_meas)) - all_cov_mat_state_equal = np.all( + all_cov_mat_state_equal = all( all_cov_mats_prior - == np.repeat( + == repeat( all_cov_mats_prior[:, :, 0][:, :, np.newaxis], all_cov_mats_prior.shape[2], axis=2, ) ) - all_cov_mat_meas_equal = cov_mats_meas.ndim == 2 or np.all( + all_cov_mat_meas_equal = cov_mats_meas.ndim == 2 or all( cov_mats_meas - == np.repeat( + == repeat( cov_mats_meas[:, :, 0][:, :, np.newaxis], cov_mats_meas.shape[2], axis=2, @@ -85,7 +91,7 @@ def find_association( VI=curr_cov_mahalanobis, ) elif all_cov_mat_meas_equal: - all_mats_mahalanobis = np.empty( + all_mats_mahalanobis = empty( ( measurements.shape[0], measurements.shape[0], @@ -115,7 +121,7 @@ def find_association( @ measurement_matrix.T + cov_mats_meas[:, :, j] ) - dists[i, j] = np.squeeze( + dists[i, j] = squeeze( cdist( (measurement_matrix @ all_means_prior[:, i]).T[ np.newaxis @@ -140,7 +146,7 @@ def find_association( association = col_ind[:n_targets] - if warn_on_no_meas_for_track and np.any(association > n_meas): + if warn_on_no_meas_for_track and any(association > n_meas): print( "GNN: No measurement was within gating threshold for at least one target." ) diff --git a/pyrecest/filters/hypertoroidal_particle_filter.py b/pyrecest/filters/hypertoroidal_particle_filter.py index 2ef10d8f..1e21cd90 100644 --- a/pyrecest/filters/hypertoroidal_particle_filter.py +++ b/pyrecest/filters/hypertoroidal_particle_filter.py @@ -1,3 +1,12 @@ +from pyrecest.backend import tile +from pyrecest.backend import sum +from pyrecest.backend import squeeze +from pyrecest.backend import mod +from pyrecest.backend import linspace +from pyrecest.backend import arange +from pyrecest.backend import int64 +from pyrecest.backend import int32 +from pyrecest.backend import zeros_like import copy from collections.abc import Callable @@ -19,8 +28,8 @@ class HypertoroidalParticleFilter(AbstractParticleFilter, AbstractHypertoroidalF @beartype def __init__( self, - n_particles: int | np.int32 | np.int64, - dim: int | np.int32 | np.int64, + n_particles: int | int32 | int64, + dim: int | int32 | int64, ): assert np.isscalar(n_particles) assert n_particles > 1, "Use CircularParticleFilter for 1-D case" @@ -28,12 +37,12 @@ def __init__( if dim == 1: # Prevents ambiguities if a vector is of size (dim,) or (n,) (for dim=1) filter_state = CircularDiracDistribution( - np.linspace(0, 2 * np.pi, n_particles, endpoint=False) + linspace(0, 2 * np.pi, n_particles, endpoint=False) ) else: filter_state = HypertoroidalDiracDistribution( - np.tile( - np.linspace(0, 2 * np.pi, n_particles, endpoint=False), (dim, 1) + tile( + linspace(0, 2 * np.pi, n_particles, endpoint=False), (dim, 1) ).T.squeeze(), dim=dim, ) @@ -64,8 +73,8 @@ def predict_nonlinear( if noise_distribution is not None: noise = noise_distribution.sample(self.filter_state.w.size) - self.filter_state.d += np.squeeze(noise) - self.filter_state.d = np.mod(self.filter_state.d, 2 * np.pi) + self.filter_state.d += squeeze(noise) + self.filter_state.d = mod(self.filter_state.d, 2 * np.pi) @beartype def predict_nonlinear_nonadditive( @@ -75,10 +84,10 @@ def predict_nonlinear_nonadditive( samples.shape[0] == weights.size ), "samples and weights must match in size" - weights /= np.sum(weights) + weights /= sum(weights) n = self.filter_state.shape[0] - noise_ids = np.random.choice(np.arange(weights.size), size=n, p=weights) - d = np.zeros_like(self.filter_state) + noise_ids = np.random.choice(arange(weights.size), size=n, p=weights) + d = zeros_like(self.filter_state) for i in range(n): d[i, :] = f(self.filter_state[i, :], samples[noise_ids[i, :]]) self.filter_state = d diff --git a/pyrecest/filters/kalman_filter.py b/pyrecest/filters/kalman_filter.py index 338d7888..a871f6f5 100644 --- a/pyrecest/filters/kalman_filter.py +++ b/pyrecest/filters/kalman_filter.py @@ -1,3 +1,4 @@ +from pyrecest.backend import eye import numpy as np from beartype import beartype from filterpy.kalman import KalmanFilter as FilterPyKalmanFilter @@ -63,8 +64,8 @@ def predict_identity(self, sys_noise_cov: np.ndarray, sys_input: np.ndarray = No :param sys_noise_mean: System noise mean. :param sys_input: System noise covariance. """ - system_matrix = np.eye(self._filter_state.x.shape[0]) - B = np.eye(system_matrix.shape[0]) if sys_input is not None else None + system_matrix = eye(self._filter_state.x.shape[0]) + B = eye(system_matrix.shape[0]) if sys_input is not None else None self._filter_state.predict(F=system_matrix, Q=sys_noise_cov, B=B, u=sys_input) @beartype @@ -86,7 +87,7 @@ def predict_linear( "The number of rows in system_matrix should match the number of elements in sys_input" ) - B = np.eye(system_matrix.shape[0]) if sys_input is not None else None + B = eye(system_matrix.shape[0]) if sys_input is not None else None self._filter_state.predict(F=system_matrix, Q=sys_noise_cov, B=B, u=sys_input) @beartype @@ -99,7 +100,7 @@ def update_identity(self, meas_noise: np.ndarray, measurement: np.ndarray): """ self.update_linear( measurement=measurement, - measurement_matrix=np.eye(self.dim), + measurement_matrix=eye(self.dim), meas_noise=meas_noise, ) diff --git a/pyrecest/filters/random_matrix_tracker.py b/pyrecest/filters/random_matrix_tracker.py index 0ef6df69..2ef04c3c 100644 --- a/pyrecest/filters/random_matrix_tracker.py +++ b/pyrecest/filters/random_matrix_tracker.py @@ -1,3 +1,7 @@ +from pyrecest.backend import mean +from pyrecest.backend import eye +from pyrecest.backend import exp +from pyrecest.backend import concatenate import numpy as np from pyrecest.utils.plotting import plot_ellipsoid @@ -22,7 +26,7 @@ def __init__( def get_point_estimate(self): # Combines the kinematic state and flattened extent matrix into one vector - return np.concatenate([self.kinematic_state, self.extent.flatten()]) + return concatenate([self.kinematic_state, self.extent.flatten()]) def get_point_estimate_kinematics(self): # Returns just the kinematic state @@ -40,12 +44,12 @@ def predict(self, dt, Cw, tau, system_matrix): y_rows = x_rows // 2 if np.isscalar(Cw): - Cw = Cw * np.eye(x_rows) + Cw = Cw * eye(x_rows) self.kinematic_state = F @ self.kinematic_state self.covariance = F @ self.covariance @ F.T + Cw - self.alpha = y_rows + np.exp(-dt / tau) * (self.alpha - y_rows) + self.alpha = y_rows + exp(-dt / tau) * (self.alpha - y_rows) # pylint: disable=too-many-locals def update(self, measurements, meas_mat, meas_noise_cov): @@ -61,7 +65,7 @@ def update(self, measurements, meas_mat, meas_noise_cov): if y_cols < y_rows + 1: raise ValueError("Too few measurements.") - y_ = np.mean(ys, axis=1, keepdims=True) + y_ = mean(ys, axis=1, keepdims=True) ys_demean = ys - y_ Y_ = ys_demean @ ys_demean.T diff --git a/pyrecest/filters/toroidal_particle_filter.py b/pyrecest/filters/toroidal_particle_filter.py index b8dc318e..5c830756 100644 --- a/pyrecest/filters/toroidal_particle_filter.py +++ b/pyrecest/filters/toroidal_particle_filter.py @@ -1,3 +1,5 @@ +from pyrecest.backend import int64 +from pyrecest.backend import int32 import numpy as np from beartype import beartype @@ -6,5 +8,5 @@ class ToroidalParticleFilter(HypertoroidalParticleFilter): @beartype - def __init__(self, n_particles: int | np.int32 | np.int64): + def __init__(self, n_particles: int | int32 | int64): HypertoroidalParticleFilter.__init__(self, n_particles, 2) diff --git a/pyrecest/filters/toroidal_wrapped_normal_filter.py b/pyrecest/filters/toroidal_wrapped_normal_filter.py index 3c24371a..24b7f4a4 100644 --- a/pyrecest/filters/toroidal_wrapped_normal_filter.py +++ b/pyrecest/filters/toroidal_wrapped_normal_filter.py @@ -1,3 +1,5 @@ +from pyrecest.backend import eye +from pyrecest.backend import array import numpy as np from pyrecest.distributions.hypertorus.toroidal_wrapped_normal_distribution import ( ToroidalWrappedNormalDistribution, @@ -9,7 +11,7 @@ class ToroidalWrappedNormalFilter(AbstractToroidalFilter): def __init__(self): AbstractToroidalFilter.__init__( - self, ToroidalWrappedNormalDistribution(np.array([0, 0]), np.eye(2)) + self, ToroidalWrappedNormalDistribution(array([0, 0]), eye(2)) ) def predict_identity(self, twn_sys): diff --git a/pyrecest/filters/von_mises_filter.py b/pyrecest/filters/von_mises_filter.py index 0907699a..78d05597 100644 --- a/pyrecest/filters/von_mises_filter.py +++ b/pyrecest/filters/von_mises_filter.py @@ -1,3 +1,4 @@ +from pyrecest.backend import mod import copy import warnings @@ -70,6 +71,6 @@ def update_identity(self, vmMeas: VonMisesDistribution, z=0.0): ) warnings.warn(warning_message) - muWnew = np.mod(z - vmMeas.mu, 2 * np.pi) + muWnew = mod(z - vmMeas.mu, 2 * np.pi) vmMeasShifted = VonMisesDistribution(muWnew, vmMeas.kappa) self.filter_state = self.filter_state.multiply(vmMeasShifted) diff --git a/pyrecest/filters/von_mises_fisher_filter.py b/pyrecest/filters/von_mises_fisher_filter.py index 4f16226a..1c69184d 100644 --- a/pyrecest/filters/von_mises_fisher_filter.py +++ b/pyrecest/filters/von_mises_fisher_filter.py @@ -1,3 +1,5 @@ +from pyrecest.backend import ndim +from pyrecest.backend import array import numpy as np from pyrecest.distributions import VonMisesFisherDistribution @@ -7,7 +9,7 @@ class VonMisesFisherFilter(AbstractHypersphericalFilter): def __init__(self): AbstractHypersphericalFilter.__init__( - self, VonMisesFisherDistribution(np.array([1, 0]), 1) + self, VonMisesFisherDistribution(array([1, 0]), 1) ) @property @@ -45,6 +47,6 @@ def update_identity(self, meas_noise, z): assert ( z.shape[0] == self.filter_state.input_dim ), "Dimension mismatch between measurement and state." - assert np.ndim(z) == 1, "z should be a vector." + assert ndim(z) == 1, "z should be a vector." meas_noise.mu = z self.filter_state = self.filter_state.multiply(meas_noise) diff --git a/pyrecest/filters/wrapped_normal_filter.py b/pyrecest/filters/wrapped_normal_filter.py index 6fef9def..4f2b5669 100644 --- a/pyrecest/filters/wrapped_normal_filter.py +++ b/pyrecest/filters/wrapped_normal_filter.py @@ -1,3 +1,6 @@ +from pyrecest.backend import mod +from pyrecest.backend import log +from pyrecest.backend import array from collections.abc import Callable from functools import partial @@ -18,7 +21,7 @@ def predict_identity(self, wn_sys): self.filter_state = self.filter_state.convolve(wn_sys) def update_identity(self, wn_meas, z): - mu_w_new = np.mod(z - wn_meas.mu, 2 * np.pi) + mu_w_new = mod(z - wn_meas.mu, 2 * np.pi) wn_meas_shifted = WrappedNormalDistribution(mu_w_new, wn_meas.sigma) self.filter_state = self.filter_state.multiply_vm(wn_meas_shifted) @@ -41,7 +44,7 @@ def update_nonlinear_progressive( while lambda_ > 0: wd = self.filter_state.to_dirac5() - likelihood_vals = np.array([likelihood(z, x) for x in wd.d]) + likelihood_vals = array([likelihood(z, x) for x in wd.d]) likelihood_vals_min: np.number = np.min(likelihood_vals) likelihood_vals_max: np.number = np.max(likelihood_vals) @@ -57,8 +60,8 @@ def update_nonlinear_progressive( raise ZeroDivisionError("Cannot perform division by zero") current_lambda = min( - np.log(tau * w_max / w_min) - / np.log(likelihood_vals_min / likelihood_vals_max), + log(tau * w_max / w_min) + / log(likelihood_vals_min / likelihood_vals_max), lambda_, ) diff --git a/pyrecest/sampling/euclidean_sampler.py b/pyrecest/sampling/euclidean_sampler.py index 635def7a..57bd009e 100644 --- a/pyrecest/sampling/euclidean_sampler.py +++ b/pyrecest/sampling/euclidean_sampler.py @@ -1,3 +1,5 @@ +from pyrecest.backend import eye +from pyrecest.backend import zeros import numpy as np from pyrecest.distributions import GaussianDistribution @@ -10,4 +12,4 @@ class AbstractEuclideanSampler(AbstractSampler): class GaussianSampler(AbstractEuclideanSampler): def sample_stochastic(self, n_samples: int, dim: int) -> np.ndarray: - return GaussianDistribution(np.zeros(dim), np.eye(dim)).sample(n_samples) + return GaussianDistribution(zeros(dim), eye(dim)).sample(n_samples) diff --git a/pyrecest/sampling/hyperspherical_sampler.py b/pyrecest/sampling/hyperspherical_sampler.py index 1da37ca8..49df1926 100644 --- a/pyrecest/sampling/hyperspherical_sampler.py +++ b/pyrecest/sampling/hyperspherical_sampler.py @@ -1,3 +1,12 @@ +from pyrecest.backend import vstack +from pyrecest.backend import sqrt +from pyrecest.backend import sin +from pyrecest.backend import cos +from pyrecest.backend import array +from pyrecest.backend import arctan2 +from pyrecest.backend import arccos +from pyrecest.backend import arange +from pyrecest.backend import empty import itertools from abc import abstractmethod @@ -82,7 +91,7 @@ def get_grid(self, grid_density_parameter: int) -> tuple[np.ndarray, dict]: n_side = grid_density_parameter n_areas = hp.nside2npix(n_side) - x, y, z = hp.pix2vec(n_side, np.arange(n_areas)) + x, y, z = hp.pix2vec(n_side, arange(n_areas)) grid = np.column_stack((x, y, z)) grid_specific_description = { @@ -106,7 +115,7 @@ def get_grid_spherical_coordinates( phi_deg_mat = grid.lons() theta_deg_mat = grid.lats() - phi_theta_stacked_deg = np.array( + phi_theta_stacked_deg = array( list(itertools.product(phi_deg_mat, theta_deg_mat)) ) phi_theta_stacked_rad = np.radians(phi_theta_stacked_deg) @@ -129,9 +138,9 @@ class SphericalFibonacciSampler(AbstractSphericalCoordinatesBasedSampler): def get_grid_spherical_coordinates( self, grid_density_parameter: int ) -> tuple[np.ndarray, np.ndarray, dict]: - indices = np.arange(0, grid_density_parameter, dtype=float) + 0.5 + indices = arange(0, grid_density_parameter, dtype=float) + 0.5 phi = np.pi * (1 + 5**0.5) * indices - theta = np.arccos(1 - 2 * indices / grid_density_parameter) + theta = arccos(1 - 2 * indices / grid_density_parameter) grid_specific_description = { "scheme": "spherical_fibonacci", "n_samples": grid_density_parameter, @@ -153,20 +162,20 @@ def hopf_coordinates_to_quaterion_yershova( Anna Yershova, Swati Jain, Steven M. LaValle, Julie C. Mitchell As in appendix (or in Eq 4 if one reorders it). """ - quaterions = np.empty((θ.shape[0], 4)) + quaterions = empty((θ.shape[0], 4)) - quaterions[:, 0] = np.cos(θ / 2) * np.cos(ψ / 2) - quaterions[:, 1] = np.cos(θ / 2) * np.sin(ψ / 2) - quaterions[:, 2] = np.sin(θ / 2) * np.cos(ϕ + ψ / 2) - quaterions[:, 3] = np.sin(θ / 2) * np.sin(ϕ + ψ / 2) + quaterions[:, 0] = cos(θ / 2) * cos(ψ / 2) + quaterions[:, 1] = cos(θ / 2) * sin(ψ / 2) + quaterions[:, 2] = sin(θ / 2) * cos(ϕ + ψ / 2) + quaterions[:, 3] = sin(θ / 2) * sin(ϕ + ψ / 2) return quaterions @staticmethod @beartype def quaternion_to_hopf_yershova(q: np.ndarray): - θ = 2 * np.arccos(np.sqrt(q[:, 0] ** 2 + q[:, 1] ** 2)) - ϕ = np.arctan2(q[:, 3], q[:, 2]) - np.arctan2(q[:, 1], q[:, 0]) - ψ = 2 * np.arctan2(q[:, 1], q[:, 0]) + θ = 2 * arccos(sqrt(q[:, 0] ** 2 + q[:, 1] ** 2)) + ϕ = arctan2(q[:, 3], q[:, 2]) - arctan2(q[:, 1], q[:, 0]) + ψ = 2 * arctan2(q[:, 1], q[:, 0]) return θ, ϕ, ψ @@ -198,19 +207,19 @@ def get_grid(self, grid_density_parameter: int | list[int]): nside = 2**i numpixels = hp.nside2npix(nside) - healpix_points = np.empty((numpixels, 2)) + healpix_points = empty((numpixels, 2)) for j in range(numpixels): theta, phi = hp.pix2ang(nside, j, nest=True) healpix_points[j] = [theta, phi] for j in range(len(healpix_points)): for k in range(len(psi_points)): - temp = np.array( + temp = array( [healpix_points[j, 0], healpix_points[j, 1], psi_points[k]] ) s3_points_list.append(temp) - s3_points = np.vstack(s3_points_list) # Need to stack like this and unpack + s3_points = vstack(s3_points_list) # Need to stack like this and unpack grid = AbstractHopfBasedS3Sampler.hopf_coordinates_to_quaterion_yershova( s3_points[:, 0], s3_points[:, 1], s3_points[:, 2] ) @@ -248,16 +257,16 @@ def get_grid(self, grid_density_parameter: int | list[int]): if len(grid_density_parameter) == 2: n_sample_circle = grid_density_parameter[1] else: - n_sample_circle = np.sqrt(grid_density_parameter[0]) + n_sample_circle = sqrt(grid_density_parameter[0]) psi_points = circular_sampler.get_grid(n_sample_circle) # Step 3: Combine the two grids to generate a grid for S3 for spherical_point in spherical_points: for psi in psi_points: - s3_point = np.array([spherical_point[0], spherical_point[1], psi]) + s3_point = array([spherical_point[0], spherical_point[1], psi]) s3_points_list.append(s3_point) - s3_points = np.vstack(s3_points_list) + s3_points = vstack(s3_points_list) grid = AbstractHopfBasedS3Sampler.hopf_coordinates_to_quaterion_yershova( s3_points[:, 0], s3_points[:, 1], s3_points[:, 2] ) diff --git a/pyrecest/sampling/hypertoroidal_sampler.py b/pyrecest/sampling/hypertoroidal_sampler.py index 36dcd8ed..ed28460b 100644 --- a/pyrecest/sampling/hypertoroidal_sampler.py +++ b/pyrecest/sampling/hypertoroidal_sampler.py @@ -1,3 +1,4 @@ +from pyrecest.backend import linspace import numpy as np from beartype import beartype from pyrecest.distributions import CircularUniformDistribution @@ -23,7 +24,7 @@ def get_grid(self, grid_density_parameter: int) -> np.ndarray: """ Returns an equidistant grid of points on the circle [0,2*pi). """ - points = np.linspace(0, 2 * np.pi, grid_density_parameter, endpoint=False) + points = linspace(0, 2 * np.pi, grid_density_parameter, endpoint=False) # Set it to the middle of the interval instead of the start points += (2 * np.pi / grid_density_parameter) / 2 return points diff --git a/pyrecest/tests/distributions/test_abstract_circular_distribution.py b/pyrecest/tests/distributions/test_abstract_circular_distribution.py index 0e6b132d..d21d678a 100644 --- a/pyrecest/tests/distributions/test_abstract_circular_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_circular_distribution.py @@ -1,3 +1,6 @@ +from pyrecest.backend import arange +from pyrecest.backend import allclose +from pyrecest.backend import all import unittest import numpy as np @@ -13,16 +16,16 @@ def setUp(self): def test_cdf_numerical(self): """Tests if the numerical computation of cdf matches the actual cdf.""" - x = np.arange(0, 7) + x = arange(0, 7) starting_point = 2.1 for dist in self.distributions: with self.subTest(distribution=dist): self.assertTrue( - np.allclose(dist.cdf_numerical(x), dist.cdf(x), rtol=1e-10) + allclose(dist.cdf_numerical(x), dist.cdf(x), rtol=1e-10) ) self.assertTrue( - np.allclose( + allclose( dist.cdf_numerical(x, starting_point), dist.cdf(x, starting_point), rtol=1e-10, @@ -31,13 +34,13 @@ def test_cdf_numerical(self): def test_angular_moment_numerical(self): """Tests if the numerical computation of angular moment matches the actual moment.""" - moments = np.arange(4) + moments = arange(4) for dist in self.distributions: for moment in moments: with self.subTest(distribution=dist, moment=moment): self.assertTrue( - np.allclose( + allclose( dist.trigonometric_moment(moment), dist.trigonometric_moment_numerical(moment), rtol=1e-10, @@ -62,7 +65,7 @@ def test_integral_numerical(self): for interval in intervals: with self.subTest(distribution=dist, interval=interval): self.assertTrue( - np.allclose( + allclose( dist.integrate_numerically(interval), dist.integrate(interval), rtol=1e-10, diff --git a/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py b/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py index 3ba5c188..fb107a25 100644 --- a/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py @@ -1,3 +1,9 @@ +from pyrecest.backend import ones +from pyrecest.backend import array +from pyrecest.backend import arange +from pyrecest.backend import allclose +from pyrecest.backend import all +from pyrecest.backend import zeros import unittest import numpy as np @@ -8,63 +14,63 @@ class AbstractHypercylindricalDistributionTest(unittest.TestCase): def test_mode_numerical_gaussian_2D(self): - mu = np.array([5, 1]) - C = np.array([[2, 1], [1, 1]]) + mu = array([5, 1]) + C = array([[2, 1], [1, 1]]) g = PartiallyWrappedNormalDistribution(mu, C, 1) - self.assertTrue(np.allclose(g.mode_numerical(), mu, atol=1e-5)) + self.assertTrue(allclose(g.mode_numerical(), mu, atol=1e-5)) def test_linear_mean_numerical(self): hwn = PartiallyWrappedNormalDistribution( - np.array([1, 2]), np.array([[2, 0.3], [0.3, 1]]), 1 + array([1, 2]), array([[2, 0.3], [0.3, 1]]), 1 ) np.testing.assert_allclose(hwn.linear_mean_numerical(), hwn.mu[-1]) def test_condition_on_periodic(self): hwn = PartiallyWrappedNormalDistribution( - np.array([1, 2]), np.array([[2, 0.3], [0.3, 1]]), 1 + array([1, 2]), array([[2, 0.3], [0.3, 1]]), 1 ) - dist_cond1 = hwn.condition_on_periodic(np.array(1.5)) + dist_cond1 = hwn.condition_on_periodic(array(1.5)) # There is some normalization constant involved, therefore, test if ratio stays the same np.testing.assert_allclose( np.diff( - hwn.pdf(np.column_stack([1.5 * np.ones(11), np.arange(-5, 6)])) - / dist_cond1.pdf(np.arange(-5, 6)) + hwn.pdf(np.column_stack([1.5 * ones(11), arange(-5, 6)])) + / dist_cond1.pdf(arange(-5, 6)) ), - np.zeros(10), + zeros(10), atol=1e-10, ) - dist_cond2 = hwn.condition_on_periodic(np.array(1.5) + 2 * np.pi) + dist_cond2 = hwn.condition_on_periodic(array(1.5) + 2 * np.pi) np.testing.assert_allclose( np.diff( - hwn.pdf(np.column_stack([1.5 * np.ones(11), np.arange(-5, 6)])) - / dist_cond2.pdf(np.arange(-5, 6)) + hwn.pdf(np.column_stack([1.5 * ones(11), arange(-5, 6)])) + / dist_cond2.pdf(arange(-5, 6)) ), - np.zeros(10), + zeros(10), atol=1e-10, ) def test_condition_on_linear(self): hwn = PartiallyWrappedNormalDistribution( - np.array([1, 2]), np.array([[2, 0.3], [0.3, 1]]), 1 + array([1, 2]), array([[2, 0.3], [0.3, 1]]), 1 ) - dist_cond1 = hwn.condition_on_linear(np.array(1.5)) + dist_cond1 = hwn.condition_on_linear(array(1.5)) np.testing.assert_allclose( np.diff( - hwn.pdf(np.column_stack([np.arange(-5, 6), 1.5 * np.ones(11)])) - / dist_cond1.pdf(np.arange(-5, 6)) + hwn.pdf(np.column_stack([arange(-5, 6), 1.5 * ones(11)])) + / dist_cond1.pdf(arange(-5, 6)) ), - np.zeros(10), + zeros(10), atol=1e-10, ) - dist_cond2 = hwn.condition_on_linear(np.array(1.5 + 2 * np.pi)) + dist_cond2 = hwn.condition_on_linear(array(1.5 + 2 * np.pi)) self.assertFalse( ( - np.allclose( + allclose( np.diff( - hwn.pdf(np.column_stack([np.arange(-5, 6), 1.5 * np.ones(11)])) - / dist_cond2.pdf(np.arange(-5, 6)) + hwn.pdf(np.column_stack([arange(-5, 6), 1.5 * ones(11)])) + / dist_cond2.pdf(arange(-5, 6)) ), - np.zeros(10), + zeros(10), ) ) ) diff --git a/pyrecest/tests/distributions/test_abstract_hyperhemispherical_distribution.py b/pyrecest/tests/distributions/test_abstract_hyperhemispherical_distribution.py index a05c15cd..9a4e565f 100644 --- a/pyrecest/tests/distributions/test_abstract_hyperhemispherical_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hyperhemispherical_distribution.py @@ -1,3 +1,6 @@ +from pyrecest.backend import sum +from pyrecest.backend import ones +from pyrecest.backend import array import unittest import numpy as np @@ -15,7 +18,7 @@ class TestAbstractHyperhemisphericalDistribution(unittest.TestCase): def setUp(self): - self.mu_ = np.array([0.5, 1.0, 1.0]) / np.linalg.norm([0.5, 1.0, 1.0]) + self.mu_ = array([0.5, 1.0, 1.0]) / np.linalg.norm([0.5, 1.0, 1.0]) self.kappa_ = 2.0 def test_get_manifold_size(self): @@ -34,7 +37,7 @@ def test_mode_numerical(self): def test_sample_metropolis_hastings_basics_only(self): """Tests the sample_metropolis_hastings sampling""" - vmf = VonMisesFisherDistribution(np.array([1, 0, 0]), 2.0) + vmf = VonMisesFisherDistribution(array([1, 0, 0]), 2.0) chd = CustomHyperhemisphericalDistribution( lambda x: vmf.pdf(x) + vmf.pdf(-x), vmf.dim ) @@ -44,7 +47,7 @@ def test_sample_metropolis_hastings_basics_only(self): with self.subTest(sample=s): self.assertEqual(s.shape, (n, chd.input_dim)) np.testing.assert_allclose( - np.sum(s**2, axis=1), np.ones(n), rtol=1e-10 + sum(s**2, axis=1), ones(n), rtol=1e-10 ) diff --git a/pyrecest/tests/distributions/test_abstract_hypersphere_subset_distribution.py b/pyrecest/tests/distributions/test_abstract_hypersphere_subset_distribution.py index 45a17307..cf7a3a5f 100644 --- a/pyrecest/tests/distributions/test_abstract_hypersphere_subset_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hypersphere_subset_distribution.py @@ -1,3 +1,6 @@ +from pyrecest.backend import sin +from pyrecest.backend import cos +from pyrecest.backend import array import unittest import numpy as np @@ -6,23 +9,23 @@ class TestAbstractHypersphereSubsetDistribution(unittest.TestCase): def test_pdf_hyperspherical_coords_1d(self): - mu_ = np.array([0.5, 1.0]) / np.linalg.norm([0.5, 1.0]) + mu_ = array([0.5, 1.0]) / np.linalg.norm([0.5, 1.0]) kappa_ = 2.0 vmf = VonMisesFisherDistribution(mu_, kappa_) pdf_hyperspherical = vmf.gen_pdf_hyperspherical_coords() def fangles_1d(phi): - return vmf.pdf(np.array([np.sin(phi), np.cos(phi)]).T) + return vmf.pdf(array([sin(phi), cos(phi)]).T) - phi_test = np.array([1.0, 2.0, 0.0, 0.3, 1.1]) + phi_test = array([1.0, 2.0, 0.0, 0.3, 1.1]) np.testing.assert_array_almost_equal( pdf_hyperspherical(phi_test), fangles_1d(phi_test) ) def test_pdf_hyperspherical_coords_2d(self): - mu_ = np.array([0.5, 1.0, 1.0]) / np.linalg.norm([0.5, 1.0, 1.0]) + mu_ = array([0.5, 1.0, 1.0]) / np.linalg.norm([0.5, 1.0, 1.0]) kappa_ = 2.0 vmf = VonMisesFisherDistribution(mu_, kappa_) @@ -31,11 +34,11 @@ def test_pdf_hyperspherical_coords_2d(self): def fangles_2d(phi1, phi2): r = 1 return vmf.pdf( - np.array( + array( [ - r * np.sin(phi1) * np.sin(phi2), - r * np.cos(phi1) * np.sin(phi2), - r * np.cos(phi2), + r * sin(phi1) * sin(phi2), + r * cos(phi1) * sin(phi2), + r * cos(phi2), ] ).T ) @@ -48,7 +51,7 @@ def fangles_2d(phi1, phi2): ) def test_pdf_hyperspherical_coords_3d(self): - mu_ = np.array([0.5, 1.0, 1.0, -0.5]) / np.linalg.norm([0.5, 1.0, 1.0, -0.5]) + mu_ = array([0.5, 1.0, 1.0, -0.5]) / np.linalg.norm([0.5, 1.0, 1.0, -0.5]) kappa_ = 2.0 vmf = VonMisesFisherDistribution(mu_, kappa_) @@ -57,18 +60,18 @@ def test_pdf_hyperspherical_coords_3d(self): def fangles_3d(phi1, phi2, phi3): r = 1 return vmf.pdf( - np.array( + array( [ - r * np.sin(phi1) * np.sin(phi2) * np.sin(phi3), - r * np.cos(phi1) * np.sin(phi2) * np.sin(phi3), - r * np.cos(phi2) * np.sin(phi3), - r * np.cos(phi3), + r * sin(phi1) * sin(phi2) * sin(phi3), + r * cos(phi1) * sin(phi2) * sin(phi3), + r * cos(phi2) * sin(phi3), + r * cos(phi3), ] ).T ) - phi1_test = np.array([1.0, 2.0, 0.0, 0.3, 1.1]) - phi2_test = np.array([2.0, 3.0, 0.1, 3.0, 1.1]) + phi1_test = array([1.0, 2.0, 0.0, 0.3, 1.1]) + phi2_test = array([2.0, 3.0, 0.1, 3.0, 1.1]) phi3_test = phi2_test + 0.2 np.testing.assert_array_almost_equal( diff --git a/pyrecest/tests/distributions/test_abstract_hyperspherical_distribution.py b/pyrecest/tests/distributions/test_abstract_hyperspherical_distribution.py index f80c9b03..04910e25 100644 --- a/pyrecest/tests/distributions/test_abstract_hyperspherical_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hyperspherical_distribution.py @@ -1,3 +1,5 @@ +from pyrecest.backend import sqrt +from pyrecest.backend import array import unittest import matplotlib @@ -13,7 +15,7 @@ class AbstractHypersphericalDistributionTest(unittest.TestCase): def testIntegral2D(self): """Tests the integral calculation in 2D.""" - mu = np.array([1, 1, 2]) + mu = array([1, 1, 2]) mu = mu / np.linalg.norm(mu) kappa = 10 vmf = VonMisesFisherDistribution(mu, kappa) @@ -21,7 +23,7 @@ def testIntegral2D(self): def testIntegral3D(self): """Tests the integral calculation in 3D.""" - mu = np.array([1, 1, 2, 2]) + mu = array([1, 1, 2, 2]) mu = mu / np.linalg.norm(mu) kappa = 10 vmf = VonMisesFisherDistribution(mu, kappa) @@ -47,7 +49,7 @@ def testUnitSphereSurface(self): def test_mean_direction_numerical(self): """Tests the numerical mean direction calculation.""" - mu = 1 / np.sqrt(2) * np.array([1, 1, 0]) + mu = 1 / sqrt(2) * array([1, 1, 0]) kappa = 10 vmf = VonMisesFisherDistribution(mu, kappa) self.assertLess(np.linalg.norm(vmf.mean_direction_numerical() - mu), 1e-6) @@ -55,7 +57,7 @@ def test_mean_direction_numerical(self): def test_plotting_error_free_2d(self): """Tests the plotting function""" - mu = np.array([1, 1, 2]) + mu = array([1, 1, 2]) mu = mu / np.linalg.norm(mu) kappa = 10 vmf = VonMisesFisherDistribution(mu, kappa) diff --git a/pyrecest/tests/distributions/test_abstract_linear_distribution.py b/pyrecest/tests/distributions/test_abstract_linear_distribution.py index 32802de3..62fb8e1f 100644 --- a/pyrecest/tests/distributions/test_abstract_linear_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_linear_distribution.py @@ -1,3 +1,6 @@ +from pyrecest.backend import squeeze +from pyrecest.backend import isclose +from pyrecest.backend import array import unittest import matplotlib @@ -13,23 +16,23 @@ class TestAbstractLinearDistribution(unittest.TestCase): def setUp(self): - self.mu_2D = np.array([5, 1]) - self.C_2D = np.array([[2, 1], [1, 1]]) - self.mu_3D = np.array([1, 2, 3]) - self.C_3D = np.array([[1.1, 0.4, 0], [0.4, 0.9, 0], [0, 0, 1]]) + self.mu_2D = array([5, 1]) + self.C_2D = array([[2, 1], [1, 1]]) + self.mu_3D = array([1, 2, 3]) + self.C_3D = array([[1.1, 0.4, 0], [0.4, 0.9, 0], [0, 0, 1]]) self.g_2D = GaussianDistribution(self.mu_2D, self.C_2D) self.g_3D = GaussianDistribution(self.mu_3D, self.C_3D) def test_integrate_numerically(self): """Test that the numerical integration of a Gaussian distribution equals 1.""" - dist = GaussianDistribution(np.array([1, 2]), np.diag([1, 2])) + dist = GaussianDistribution(array([1, 2]), np.diag([1, 2])) integration_result = dist.integrate_numerically() - assert np.isclose( + assert isclose( integration_result, 1, rtol=1e-5 ), f"Expected 1, but got {integration_result}" def test_integrate_fun_over_domain(self): - dist = GaussianDistribution(np.array([1, 2]), np.diag([1, 2])) + dist = GaussianDistribution(array([1, 2]), np.diag([1, 2])) def f(x): return 0.3 * dist.pdf(x) @@ -41,26 +44,26 @@ def f(x): integration_result = AbstractLinearDistribution.integrate_fun_over_domain( f, dim, left, right ) - assert np.isclose( + assert isclose( integration_result, 0.3, rtol=1e-5 ), f"Expected 0.3, but got {integration_result}" def test_mode_numerical_custom_1D(self): cd = CustomLinearDistribution( - lambda x: np.squeeze( + lambda x: squeeze( ((x > -1) & (x <= 0)) * (1 + x) + ((x > 0) & (x <= 1)) * (1 - x) ), 1, ) - cd = cd.shift(np.array(0.5)) + cd = cd.shift(array(0.5)) self.assertAlmostEqual(cd.mode_numerical(), 0.5, delta=1e-4) def test_mean_numerical_gaussian_2D(self): np.testing.assert_allclose(self.g_2D.mean_numerical(), self.mu_2D, atol=1e-6) def test_mode_numerical_gaussian_2D_mean_far_away(self): - mu = np.array([5, 10]) - C = np.array([[2, 1], [1, 1]]) + mu = array([5, 10]) + C = array([[2, 1], [1, 1]]) g = GaussianDistribution(mu, C) np.testing.assert_allclose(g.mode_numerical(), mu, atol=2e-4) @@ -73,7 +76,7 @@ def test_covariance_numerical_gaussian_2D(self): ) def test_plot_state_r2(self): - gd = GaussianDistribution(np.array([1, 2]), np.array([[1, 0.5], [0.5, 1]])) + gd = GaussianDistribution(array([1, 2]), array([[1, 0.5], [0.5, 1]])) gd.plot() diff --git a/pyrecest/tests/distributions/test_abstract_mixture.py b/pyrecest/tests/distributions/test_abstract_mixture.py index 84e7df76..3f9427fc 100644 --- a/pyrecest/tests/distributions/test_abstract_mixture.py +++ b/pyrecest/tests/distributions/test_abstract_mixture.py @@ -1,3 +1,8 @@ +from pyrecest.backend import ones +from pyrecest.backend import eye +from pyrecest.backend import array +from pyrecest.backend import allclose +from pyrecest.backend import all import unittest import numpy as np @@ -22,26 +27,26 @@ def _test_sample(self, mix, n): return s def test_sample_metropolis_hastings_basics_only_t2(self): - vmf = ToroidalWrappedNormalDistribution(np.array([1, 0]), np.eye(2)) + vmf = ToroidalWrappedNormalDistribution(array([1, 0]), eye(2)) mix = HypertoroidalMixture( - [vmf, vmf.shift(np.array([1, 1]))], np.array([0.5, 0.5]) + [vmf, vmf.shift(array([1, 1]))], array([0.5, 0.5]) ) self._test_sample(mix, 10) def test_sample_metropolis_hastings_basics_only_s2(self): - vmf1 = VonMisesFisherDistribution(np.array([1, 0, 0]), 2) - vmf2 = VonMisesFisherDistribution(np.array([0, 1, 0]), 2) + vmf1 = VonMisesFisherDistribution(array([1, 0, 0]), 2) + vmf2 = VonMisesFisherDistribution(array([0, 1, 0]), 2) mix = HypersphericalMixture([vmf1, vmf2], [0.5, 0.5]) s = self._test_sample(mix, 10) - self.assertTrue(np.allclose(np.linalg.norm(s, axis=1), np.ones(10), rtol=1e-10)) + self.assertTrue(allclose(np.linalg.norm(s, axis=1), ones(10), rtol=1e-10)) def test_sample_metropolis_hastings_basics_only_h2(self): - vmf = VonMisesFisherDistribution(np.array([1, 0, 0]), 2) + vmf = VonMisesFisherDistribution(array([1, 0, 0]), 2) mix = CustomHyperhemisphericalDistribution( lambda x: vmf.pdf(x) + vmf.pdf(-x), 2 ) s = self._test_sample(mix, 10) - self.assertTrue(np.allclose(np.linalg.norm(s, axis=1), np.ones(10), rtol=1e-10)) + self.assertTrue(allclose(np.linalg.norm(s, axis=1), ones(10), rtol=1e-10)) if __name__ == "__main__": diff --git a/pyrecest/tests/distributions/test_bingham_distribution.py b/pyrecest/tests/distributions/test_bingham_distribution.py index 93c03a52..fcc778f2 100644 --- a/pyrecest/tests/distributions/test_bingham_distribution.py +++ b/pyrecest/tests/distributions/test_bingham_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import array import unittest import numpy as np @@ -9,15 +10,15 @@ class TestBinghamDistribution(unittest.TestCase): def setUp(self): """Setup BinghamDistribution instance for testing.""" - M = np.array( + M = array( [[1 / 3, 2 / 3, -2 / 3], [-2 / 3, 2 / 3, 1 / 3], [2 / 3, 1 / 3, 2 / 3]] ) - Z = np.array([-5, -3, 0]) + Z = array([-5, -3, 0]) self.bd = BinghamDistribution(Z, M) def test_pdf(self): """Test pdf method with a fixed set of values.""" - expected_values = np.array( + expected_values = array( [ 0.0767812166360095, 0.0145020985787277, diff --git a/pyrecest/tests/distributions/test_circular_fourier_distribution.py b/pyrecest/tests/distributions/test_circular_fourier_distribution.py index b192afa0..369c8ac2 100644 --- a/pyrecest/tests/distributions/test_circular_fourier_distribution.py +++ b/pyrecest/tests/distributions/test_circular_fourier_distribution.py @@ -1,3 +1,10 @@ +from pyrecest.backend import sqrt +from pyrecest.backend import linspace +from pyrecest.backend import ceil +from pyrecest.backend import array +from pyrecest.backend import arange +from pyrecest.backend import allclose +from pyrecest.backend import all import copy import unittest @@ -18,16 +25,16 @@ class TestCircularFourierDistribution(unittest.TestCase): "identity", VonMisesDistribution, 0.4, - np.arange(0.1, 2.1, 0.1), + arange(0.1, 2.1, 0.1), 101, 1e-8, ), - ("sqrt", VonMisesDistribution, 0.5, np.arange(0.1, 2.1, 0.1), 101, 1e-8), + ("sqrt", VonMisesDistribution, 0.5, arange(0.1, 2.1, 0.1), 101, 1e-8), ( "identity", WrappedNormalDistribution, 0.8, - np.arange(0.2, 2.1, 0.1), + arange(0.2, 2.1, 0.1), 101, 1e-8, ), @@ -35,7 +42,7 @@ class TestCircularFourierDistribution(unittest.TestCase): "sqrt", WrappedNormalDistribution, 0.8, - np.arange(0.2, 2.1, 0.1), + arange(0.2, 2.1, 0.1), 101, 1e-8, ), @@ -50,17 +57,17 @@ def test_fourier_conversion( """ for param in param_range: dist = dist_class(mu, param) - xvals = np.arange(-2 * np.pi, 3 * np.pi, 0.01) + xvals = arange(-2 * np.pi, 3 * np.pi, 0.01) fd = CircularFourierDistribution.from_distribution( dist, coeffs, transformation ) self.assertEqual( np.size(fd.c), - np.ceil(coeffs / 2), + ceil(coeffs / 2), "Length of Fourier Coefficients mismatch.", ) self.assertTrue( - np.allclose(fd.pdf(xvals), dist.pdf(xvals), atol=tolerance), + allclose(fd.pdf(xvals), dist.pdf(xvals), atol=tolerance), "PDF values do not match.", ) @@ -73,7 +80,7 @@ def test_fourier_conversion( ] ) def test_vm_to_fourier(self, mult_by_n, transformation): - xs = np.linspace(0, 2 * np.pi, 100) + xs = linspace(0, 2 * np.pi, 100) dist = VonMisesDistribution(2.5, 1.5) fd = CircularFourierDistribution.from_distribution( dist, @@ -184,7 +191,7 @@ def test_distance(self, mult_by_n): ) hel_like_distance, _ = integrate.quad( lambda x: ( - np.sqrt(dist1.pdf(np.array(x))) - np.sqrt(dist2.pdf(np.array(x))) + sqrt(dist1.pdf(array(x))) - sqrt(dist2.pdf(array(x))) ) ** 2, 0, diff --git a/pyrecest/tests/distributions/test_circular_uniform_distribution.py b/pyrecest/tests/distributions/test_circular_uniform_distribution.py index a121b94a..f7fdb9b2 100644 --- a/pyrecest/tests/distributions/test_circular_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_circular_uniform_distribution.py @@ -1,3 +1,5 @@ +from pyrecest.backend import ones +from pyrecest.backend import array import unittest import numpy as np @@ -9,25 +11,25 @@ class CircularUniformDistributionTest(unittest.TestCase): def test_pdf(self): cu = CircularUniformDistribution() - x = np.array([1, 2, 3, 4, 5, 6]) + x = array([1, 2, 3, 4, 5, 6]) # Test pdf - np.testing.assert_allclose(cu.pdf(x), 1 / (2 * np.pi) * np.ones(x.shape)) + np.testing.assert_allclose(cu.pdf(x), 1 / (2 * np.pi) * ones(x.shape)) def test_shift(self): cu = CircularUniformDistribution() cu2 = cu.shift(3) - x = np.array([1, 2, 3, 4, 5, 6]) - np.testing.assert_allclose(cu2.pdf(x), 1 / (2 * np.pi) * np.ones(x.shape)) + x = array([1, 2, 3, 4, 5, 6]) + np.testing.assert_allclose(cu2.pdf(x), 1 / (2 * np.pi) * ones(x.shape)) def test_cdf(self): cu = CircularUniformDistribution() - x = np.array([1, 2, 3, 4, 5, 6]) + x = array([1, 2, 3, 4, 5, 6]) np.testing.assert_allclose(cu.cdf(x), cu.cdf_numerical(x)) def test_cdf_with_shift(self): cu = CircularUniformDistribution() - x = np.array([1, 2, 3, 4, 5, 6]) + x = array([1, 2, 3, 4, 5, 6]) cu2 = cu.shift(3) np.testing.assert_allclose(cu2.cdf(x), cu2.cdf_numerical(x)) diff --git a/pyrecest/tests/distributions/test_custom_hemispherical_distribution.py b/pyrecest/tests/distributions/test_custom_hemispherical_distribution.py index 1f7ecf84..49c84ae6 100644 --- a/pyrecest/tests/distributions/test_custom_hemispherical_distribution.py +++ b/pyrecest/tests/distributions/test_custom_hemispherical_distribution.py @@ -1,3 +1,7 @@ +from pyrecest.backend import eye +from pyrecest.backend import array +from pyrecest.backend import allclose +from pyrecest.backend import all import unittest import warnings @@ -11,8 +15,8 @@ class CustomHemisphericalDistributionTest(unittest.TestCase): def setUp(self): - self.M = np.eye(3) - self.Z = np.array([-2, -0.5, 0]) + self.M = eye(3) + self.Z = array([-2, -0.5, 0]) self.bingham_distribution = BinghamDistribution(self.Z, self.M) self.custom_hemispherical_distribution = ( CustomHemisphericalDistribution.from_distribution(self.bingham_distribution) @@ -29,7 +33,7 @@ def test_simple_distribution_2D(self): points /= np.linalg.norm(points, axis=1, keepdims=True) self.assertTrue( - np.allclose( + allclose( self.custom_hemispherical_distribution.pdf(points), 2 * self.bingham_distribution.pdf(points), atol=1e-5, @@ -49,7 +53,7 @@ def test_integrate_bingham_s2(self): def test_warning_asymmetric(self): """Test that creating a custom distribution based on a full hypersphere distribution raises a warning.""" - vmf = VonMisesFisherDistribution(np.array([0, 0, 1]), 10) + vmf = VonMisesFisherDistribution(array([0, 0, 1]), 10) expected_warning_message = ( "You are creating a CustomHyperhemispherical distribution based on a distribution on the full hypersphere. " + "Using numerical integration to calculate the normalization constant." diff --git a/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py b/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py index 83b988e8..04f4fc3f 100644 --- a/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py +++ b/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py @@ -1,3 +1,6 @@ +from pyrecest.backend import linspace +from pyrecest.backend import eye +from pyrecest.backend import array import unittest import numpy as np @@ -16,13 +19,13 @@ def setUp(self) -> None: mat = np.random.rand(6, 6) mat = mat @ mat.T self.pwn = PartiallyWrappedNormalDistribution( - np.array([2, 3, 4, 5, 6, 7]), mat, 3 + array([2, 3, 4, 5, 6, 7]), mat, 3 ) grid = np.mgrid[-3:4, -3:4, -2:3, -2:3, -2:3, -2:3] self.grid_flat = grid.reshape(6, -1).T self.vm = VonMisesDistribution(0, 1) - self.gauss = GaussianDistribution(np.array([1, 2]), np.eye(2)) + self.gauss = GaussianDistribution(array([1, 2]), eye(2)) def fun(x): return self.vm.pdf(x[:, 0]) * self.gauss.pdf(x[:, 1:]) @@ -44,7 +47,7 @@ def test_from_distribution(self): def test_condition_on_linear(self): dist = self.chcd_vm_gauss_stacked.condition_on_linear([2, 1]) - x = np.linspace(0, 2 * np.pi, 100) + x = linspace(0, 2 * np.pi, 100) np.testing.assert_allclose(dist.pdf(x), self.vm.pdf(x)) def test_condition_on_periodic(self): diff --git a/pyrecest/tests/distributions/test_custom_hyperrectangular_distribution.py b/pyrecest/tests/distributions/test_custom_hyperrectangular_distribution.py index 20db8df8..198170ee 100644 --- a/pyrecest/tests/distributions/test_custom_hyperrectangular_distribution.py +++ b/pyrecest/tests/distributions/test_custom_hyperrectangular_distribution.py @@ -1,3 +1,9 @@ +from pyrecest.backend import ones +from pyrecest.backend import meshgrid +from pyrecest.backend import linspace +from pyrecest.backend import array +from pyrecest.backend import allclose +from pyrecest.backend import all import unittest import numpy as np @@ -11,7 +17,7 @@ class TestCustomHyperrectangularDistribution(unittest.TestCase): def setUp(self): - self.bounds = np.array([[1, 3], [2, 5]]) + self.bounds = array([[1, 3], [2, 5]]) self.hud = HyperrectangularUniformDistribution(self.bounds) self.cd = CustomHyperrectangularDistribution(self.hud.pdf, self.hud.bounds) @@ -25,11 +31,11 @@ def test_object_creation(self): def test_pdf_method(self): """Test that the pdf method returns correct values.""" - x_mesh, y_mesh = np.meshgrid(np.linspace(1, 3, 50), np.linspace(2, 5, 50)) - expected_pdf = 1 / 6 * np.ones(50**2) + x_mesh, y_mesh = meshgrid(linspace(1, 3, 50), linspace(2, 5, 50)) + expected_pdf = 1 / 6 * ones(50**2) calculated_pdf = self.cd.pdf(np.column_stack((x_mesh.ravel(), y_mesh.ravel()))) self.assertTrue( - np.allclose(calculated_pdf, expected_pdf), + allclose(calculated_pdf, expected_pdf), "PDF calculated values do not match the expected values.", ) diff --git a/pyrecest/tests/distributions/test_custom_hyperspherical_distribution.py b/pyrecest/tests/distributions/test_custom_hyperspherical_distribution.py index 86884fe3..414fa07e 100644 --- a/pyrecest/tests/distributions/test_custom_hyperspherical_distribution.py +++ b/pyrecest/tests/distributions/test_custom_hyperspherical_distribution.py @@ -1,3 +1,6 @@ +from pyrecest.backend import array +from pyrecest.backend import allclose +from pyrecest.backend import all import unittest import numpy as np @@ -9,7 +12,7 @@ class CustomHypersphericalDistributionTest(unittest.TestCase): def setUp(self): - self.vmf = VonMisesFisherDistribution(np.array([0, 0, 1]), 10) + self.vmf = VonMisesFisherDistribution(array([0, 0, 1]), 10) self.custom_hyperspherical_distribution = ( CustomHypersphericalDistribution.from_distribution(self.vmf) ) @@ -24,7 +27,7 @@ def test_simple_distribution(self): points /= np.linalg.norm(points, axis=1, keepdims=True) self.assertTrue( - np.allclose( + allclose( self.custom_hyperspherical_distribution.pdf(points), self.vmf.pdf(points), atol=1e-5, diff --git a/pyrecest/tests/distributions/test_custom_linear_distribution.py b/pyrecest/tests/distributions/test_custom_linear_distribution.py index 8cbb1ee2..7ab41c62 100644 --- a/pyrecest/tests/distributions/test_custom_linear_distribution.py +++ b/pyrecest/tests/distributions/test_custom_linear_distribution.py @@ -1,3 +1,7 @@ +from pyrecest.backend import meshgrid +from pyrecest.backend import linspace +from pyrecest.backend import eye +from pyrecest.backend import array import unittest import numpy as np @@ -7,9 +11,9 @@ class CustomLinearDistributionTest(unittest.TestCase): def setUp(self): - g1 = GaussianDistribution(np.array([1, 1]), np.eye(2)) - g2 = GaussianDistribution(np.array([-3, -3]), np.eye(2)) - self.gm = GaussianMixture([g1, g2], np.array([0.7, 0.3])) + g1 = GaussianDistribution(array([1, 1]), eye(2)) + g2 = GaussianDistribution(array([-3, -3]), eye(2)) + self.gm = GaussianMixture([g1, g2], array([0.7, 0.3])) def test_init_and_mean(self): cld = CustomLinearDistribution.from_distribution(self.gm) @@ -26,7 +30,7 @@ def test_normalize(self): @staticmethod def verify_pdf_equal(dist1, dist2, tol): - x, y = np.meshgrid(np.linspace(0, 2 * np.pi, 10), np.linspace(0, 2 * np.pi, 10)) + x, y = meshgrid(linspace(0, 2 * np.pi, 10), linspace(0, 2 * np.pi, 10)) np.testing.assert_allclose( dist1.pdf(np.column_stack((x.ravel(), y.ravel()))), dist2.pdf(np.column_stack((x.ravel(), y.ravel()))), diff --git a/pyrecest/tests/distributions/test_disk_uniform_distribution.py b/pyrecest/tests/distributions/test_disk_uniform_distribution.py index a2111d65..fd2af46f 100644 --- a/pyrecest/tests/distributions/test_disk_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_disk_uniform_distribution.py @@ -1,3 +1,8 @@ +from pyrecest.backend import sqrt +from pyrecest.backend import ones +from pyrecest.backend import concatenate +from pyrecest.backend import array +from pyrecest.backend import zeros """ Test cases for DiskUniformDistribution""" import unittest @@ -11,10 +16,10 @@ class TestDiskUniformDistribution(unittest.TestCase): def test_pdf(self): dist = DiskUniformDistribution() - xs = np.array( + xs = array( [ - [0.5, 0, 1, 1 / np.sqrt(2), 0, 3, 1.5], - [0.5, 1, 0, 1 / np.sqrt(2), 3, 0, 1.5], + [0.5, 0, 1, 1 / sqrt(2), 0, 3, 1.5], + [0.5, 1, 0, 1 / sqrt(2), 3, 0, 1.5], ] ).T pdf_values = dist.pdf(xs) @@ -23,10 +28,10 @@ def test_pdf(self): pdf_values, 1 / np.pi - * np.concatenate( + * concatenate( ( - np.ones(4), - np.zeros(3), + ones(4), + zeros(3), ) ), rtol=1e-12, diff --git a/pyrecest/tests/distributions/test_ellipsoidal_ball_uniform_distribution.py b/pyrecest/tests/distributions/test_ellipsoidal_ball_uniform_distribution.py index a00c45cc..c15ad3c3 100644 --- a/pyrecest/tests/distributions/test_ellipsoidal_ball_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_ellipsoidal_ball_uniform_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import array import unittest import numpy as np @@ -7,13 +8,13 @@ class TestEllipsoidalBallUniformDistribution(unittest.TestCase): def test_pdf(self): dist = EllipsoidalBallUniformDistribution( - np.array([0, 0, 0]), np.diag([4, 9, 16]) + array([0, 0, 0]), np.diag([4, 9, 16]) ) - self.assertAlmostEqual(dist.pdf(np.array([0, 0, 0])), 1 / 100.53096491) + self.assertAlmostEqual(dist.pdf(array([0, 0, 0])), 1 / 100.53096491) def test_sampling(self): dist = EllipsoidalBallUniformDistribution( - np.array([2, 3]), np.array([[4, 3], [3, 9]]) + array([2, 3]), array([[4, 3], [3, 9]]) ) samples = dist.sample(10) self.assertEqual(samples.shape[-1], dist.dim) diff --git a/pyrecest/tests/distributions/test_gaussian_distribution.py b/pyrecest/tests/distributions/test_gaussian_distribution.py index 69ccd054..ea9ff5d9 100644 --- a/pyrecest/tests/distributions/test_gaussian_distribution.py +++ b/pyrecest/tests/distributions/test_gaussian_distribution.py @@ -1,3 +1,7 @@ +from pyrecest.backend import linspace +from pyrecest.backend import array +from pyrecest.backend import allclose +from pyrecest.backend import all import unittest import numpy as np @@ -8,11 +12,11 @@ class GaussianDistributionTest(unittest.TestCase): def test_gaussian_distribution_3d(self): - mu = np.array([2, 3, 4]) - C = np.array([[1.1, 0.4, 0], [0.4, 0.9, 0], [0, 0, 0.1]]) + mu = array([2, 3, 4]) + C = array([[1.1, 0.4, 0], [0.4, 0.9, 0], [0, 0, 0.1]]) g = GaussianDistribution(mu, C) - xs = np.array( + xs = array( [ [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5], [-3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7], @@ -20,7 +24,7 @@ def test_gaussian_distribution_3d(self): ] ).T self.assertTrue( - np.allclose(g.pdf(xs), multivariate_normal.pdf(xs, mu, C), rtol=1e-10) + allclose(g.pdf(xs), multivariate_normal.pdf(xs, mu, C), rtol=1e-10) ) n = 10 @@ -34,33 +38,33 @@ def test_gaussian_distribution_3d(self): ) def test_mode(self): - mu = np.array([1, 2, 3]) - C = np.array([[1.1, 0.4, 0], [0.4, 0.9, 0], [0, 0, 1]]) + mu = array([1, 2, 3]) + C = array([[1.1, 0.4, 0], [0.4, 0.9, 0], [0, 0, 1]]) g = GaussianDistribution(mu, C) - self.assertTrue(np.allclose(g.mode(), mu, atol=1e-6)) + self.assertTrue(allclose(g.mode(), mu, atol=1e-6)) def test_shift(self): - mu = np.array([3, 2, 1]) - C = np.array([[1.1, -0.4, 0], [-0.4, 0.9, 0], [0, 0, 1]]) + mu = array([3, 2, 1]) + C = array([[1.1, -0.4, 0], [-0.4, 0.9, 0], [0, 0, 1]]) g = GaussianDistribution(mu, C) - shift_by = np.array([2, -2, 3]) + shift_by = array([2, -2, 3]) g_shifted = g.shift(shift_by) - self.assertTrue(np.allclose(g_shifted.mode(), mu + shift_by, atol=1e-6)) + self.assertTrue(allclose(g_shifted.mode(), mu + shift_by, atol=1e-6)) def test_marginalization(self): - mu = np.array([1, 2]) - C = np.array([[1.1, 0.4], [0.4, 0.9]]) + mu = array([1, 2]) + C = array([[1.1, 0.4], [0.4, 0.9]]) g = GaussianDistribution(mu, C) - grid = np.linspace(-10, 10, 30) + grid = linspace(-10, 10, 30) dist_marginalized = g.marginalize_out(1) def marginlized_1D_via_integrate(xs): def integrand(y, x): - return g.pdf(np.array([x, y])) + return g.pdf(array([x, y])) result = [] for x_curr in xs: @@ -68,10 +72,10 @@ def integrand(y, x): integrand, -np.inf, np.inf, args=x_curr ) result.append(integral_value) - return np.array(result) + return array(result) self.assertTrue( - np.allclose( + allclose( dist_marginalized.pdf(grid), marginlized_1D_via_integrate(grid), atol=1e-9, diff --git a/pyrecest/tests/distributions/test_hemispherical_uniform_distribution.py b/pyrecest/tests/distributions/test_hemispherical_uniform_distribution.py index 30cf88f3..70663f8d 100644 --- a/pyrecest/tests/distributions/test_hemispherical_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_hemispherical_uniform_distribution.py @@ -1,3 +1,6 @@ +from pyrecest.backend import ones +from pyrecest.backend import allclose +from pyrecest.backend import all import unittest import numpy as np @@ -19,8 +22,8 @@ def test_pdf_2d(self): # jscpd:ignore-start self.assertTrue( - np.allclose( - hhud.pdf(points), np.ones(points.shape[0]) / (2 * np.pi), atol=1e-6 + allclose( + hhud.pdf(points), ones(points.shape[0]) / (2 * np.pi), atol=1e-6 ) ) # jscpd:ignore-end diff --git a/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py b/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py index 212be897..d3b49f8d 100644 --- a/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py @@ -1,3 +1,12 @@ +from pyrecest.backend import sum +from pyrecest.backend import ones_like +from pyrecest.backend import ones +from pyrecest.backend import isclose +from pyrecest.backend import eye +from pyrecest.backend import exp +from pyrecest.backend import array +from pyrecest.backend import zeros_like +from pyrecest.backend import zeros import unittest import numpy as np @@ -12,20 +21,20 @@ class TestHypercylindricalDiracDistribution(unittest.TestCase): def setUp(self): - self.d = np.array( + self.d = array( [[1, 2, 3, 4, 5, 6], [2, 4, 0, 0.5, 1, 1], [0, 10, 20, 30, 40, 50]] ).T - self.w = np.array([1, 2, 3, 1, 2, 3]) + self.w = array([1, 2, 3, 1, 2, 3]) self.w = self.w / sum(self.w) self.pwd = HypercylindricalDiracDistribution(1, self.d, self.w) def test_mean_and_marginalization(self): mean = self.pwd.hybrid_moment() wd = self.pwd.marginalize_linear() - assert np.isclose(mean[0], wd.trigonometric_moment(1).real, rtol=1e-10) - assert np.isclose(mean[1], wd.trigonometric_moment(1).imag, rtol=1e-10) - assert np.isclose(mean[2], sum(self.w * self.d[:, 1]), rtol=1e-10) - assert np.isclose(mean[3], sum(self.w * self.d[:, 2]), rtol=1e-10) + assert isclose(mean[0], wd.trigonometric_moment(1).real, rtol=1e-10) + assert isclose(mean[1], wd.trigonometric_moment(1).imag, rtol=1e-10) + assert isclose(mean[2], sum(self.w * self.d[:, 1]), rtol=1e-10) + assert isclose(mean[3], sum(self.w * self.d[:, 2]), rtol=1e-10) def test_covariance(self): clin = self.pwd.linear_covariance() @@ -33,32 +42,32 @@ def test_covariance(self): def test_apply_function_identity(self): same = self.pwd.apply_function(lambda x: x) - assert np.array_equal(self.pwd.d, same.d) - assert np.array_equal(self.pwd.w, same.w) + np.testing.assert_array_equal(self.pwd.d, same.d) + np.testing.assert_array_equal(self.pwd.w, same.w) assert self.pwd.lin_dim == same.lin_dim assert self.pwd.bound_dim == same.bound_dim def test_apply_function_shift(self): - shift_offset = np.array([1.4, -0.3, 1]) + shift_offset = array([1.4, -0.3, 1]) def shift(x, shift_by=shift_offset): return x + shift_by shifted = self.pwd.apply_function(shift) - assert np.isclose( + assert isclose( shifted.marginalize_linear().trigonometric_moment(1), self.pwd.marginalize_linear().trigonometric_moment(1) - * np.exp(1j * shift_offset[0]), + * exp(1j * shift_offset[0]), rtol=1e-10, ) def test_reweigh(self): # Define functions for testing def f1(x): - return np.sum(x, axis=-1) == 3 + return sum(x, axis=-1) == 3 def f2(x): - return 2 * np.ones(x.shape[0]) + return 2 * ones(x.shape[0]) def f3(x): return x[:, 0] @@ -68,17 +77,17 @@ def f3(x): pwd_rew3 = self.pwd.reweigh(f3) assert isinstance(pwd_rew1, HypercylindricalDiracDistribution) - assert np.array_equal(pwd_rew1.d, self.pwd.d) - assert np.array_equal(pwd_rew1.w, f1(self.pwd.d)) + np.testing.assert_array_equal(pwd_rew1.d, self.pwd.d) + np.testing.assert_array_equal(pwd_rew1.w, f1(self.pwd.d)) assert isinstance(pwd_rew2, HypercylindricalDiracDistribution) - assert np.array_equal(pwd_rew2.d, self.pwd.d) - assert np.array_equal(pwd_rew2.w, self.pwd.w) + np.testing.assert_array_equal(pwd_rew2.d, self.pwd.d) + np.testing.assert_array_equal(pwd_rew2.w, self.pwd.w) assert isinstance(pwd_rew3, HypercylindricalDiracDistribution) - assert np.array_equal(pwd_rew3.d, self.pwd.d) + np.testing.assert_array_equal(pwd_rew3.d, self.pwd.d) w_new = self.pwd.d[:, 0] * self.pwd.w - assert np.array_equal(pwd_rew3.w, w_new / np.sum(w_new)) + np.testing.assert_array_equal(pwd_rew3.w, w_new / sum(w_new)) def test_sampling(self): np.random.seed(0) @@ -86,14 +95,14 @@ def test_sampling(self): s = self.pwd.sample(n) assert s.shape == (n, 3) s = s[:, 0] - self.assertTrue(all(s >= np.zeros_like(s))) - self.assertTrue(all(s < 2 * np.pi * np.ones_like(s))) + self.assertTrue(all(s >= zeros_like(s))) + self.assertTrue(all(s < 2 * np.pi * ones_like(s))) def test_from_distribution(self): random_gen = np.random.default_rng(0) # Could fail randomly otherwise df = 4 - scale = np.eye(4) + scale = eye(4) C = wishart.rvs(df, scale, random_state=random_gen) - hwn = PartiallyWrappedNormalDistribution(np.array([1, 2, 3, 4]), C, 2) + hwn = PartiallyWrappedNormalDistribution(array([1, 2, 3, 4]), C, 2) hddist = HypercylindricalDiracDistribution.from_distribution(hwn, 100000) np.testing.assert_allclose(hddist.hybrid_mean(), hwn.hybrid_mean(), atol=0.15) diff --git a/pyrecest/tests/distributions/test_hyperhemispherical_uniform_distribution.py b/pyrecest/tests/distributions/test_hyperhemispherical_uniform_distribution.py index bd8abd57..cbbd6d26 100644 --- a/pyrecest/tests/distributions/test_hyperhemispherical_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_hyperhemispherical_uniform_distribution.py @@ -1,3 +1,7 @@ +from pyrecest.backend import reshape +from pyrecest.backend import ones +from pyrecest.backend import allclose +from pyrecest.backend import all """ Test for uniform distribution for hyperhemispheres """ import unittest @@ -9,7 +13,7 @@ def get_random_points(n, d): np.random.seed(10) points = np.random.randn(n, d + 1) points = points[points[:, -1] >= 0, :] - points /= np.reshape(np.linalg.norm(points, axis=1), (-1, 1)) + points /= reshape(np.linalg.norm(points, axis=1), (-1, 1)) return points @@ -22,8 +26,8 @@ def test_pdf_2d(self): points = get_random_points(100, 2) self.assertTrue( - np.allclose( - hhud.pdf(points), np.ones(points.shape[0]) / (2 * np.pi), atol=1e-6 + allclose( + hhud.pdf(points), ones(points.shape[0]) / (2 * np.pi), atol=1e-6 ) ) @@ -33,8 +37,8 @@ def test_pdf_3d(self): points = get_random_points(100, 3) # jscpd:ignore-start self.assertTrue( - np.allclose( - hhud.pdf(points), np.ones(points.shape[0]) / (np.pi**2), atol=1e-6 + allclose( + hhud.pdf(points), ones(points.shape[0]) / (np.pi**2), atol=1e-6 ) ) # jscpd:ignore-end diff --git a/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py b/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py index ef19ad7d..1f359c2a 100644 --- a/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py @@ -1,3 +1,8 @@ +from pyrecest.backend import sum +from pyrecest.backend import sqrt +from pyrecest.backend import ones +from pyrecest.backend import mod +from pyrecest.backend import array import unittest import numpy as np @@ -9,11 +14,11 @@ class HypersphericalDiracDistributionTest(unittest.TestCase): def setUp(self): - self.d = np.array( + self.d = array( [[0.5, 3, 4, 6, 6], [2, 2, 5, 3, 0], [0.5, 0.2, 5.8, 4.3, 1.2]] ).T self.d = self.d / np.linalg.norm(self.d, axis=1)[:, None] - self.w = np.array([0.1, 0.1, 0.1, 0.1, 0.6]) + self.w = array([0.1, 0.1, 0.1, 0.1, 0.6]) self.hdd = HypersphericalDiracDistribution(self.d, self.w) def test_instance_creation(self): @@ -23,9 +28,9 @@ def test_sampling(self): nSamples = 5 s = self.hdd.sample(nSamples) self.assertEqual(s.shape, (nSamples, self.d.shape[-1])) - np.testing.assert_array_almost_equal(s, np.mod(s, 2 * np.pi)) + np.testing.assert_array_almost_equal(s, mod(s, 2 * np.pi)) np.testing.assert_array_almost_equal( - np.linalg.norm(s, axis=-1), np.ones(nSamples) + np.linalg.norm(s, axis=-1), ones(nSamples) ) def test_apply_function(self): @@ -39,7 +44,7 @@ def test_apply_function(self): def test_reweigh_identity(self): def f(x): - return 2 * np.ones(x.shape[0]) + return 2 * ones(x.shape[0]) twdNew = self.hdd.reweigh(f) self.assertIsInstance(twdNew, HypersphericalDiracDistribution) @@ -53,13 +58,13 @@ def f(x): twdNew = self.hdd.reweigh(f) self.assertIsInstance(twdNew, HypersphericalDiracDistribution) np.testing.assert_array_almost_equal(twdNew.d, self.hdd.d) - self.assertAlmostEqual(np.sum(twdNew.w), 1, places=10) + self.assertAlmostEqual(sum(twdNew.w), 1, places=10) wNew = self.hdd.d[:, 1] * self.hdd.w - np.testing.assert_array_almost_equal(twdNew.w, wNew / np.sum(wNew)) + np.testing.assert_array_almost_equal(twdNew.w, wNew / sum(wNew)) def test_from_distribution(self): np.random.seed(0) - vmf = VonMisesFisherDistribution(np.array([1, 1, 1]) / np.sqrt(3), 1) + vmf = VonMisesFisherDistribution(array([1, 1, 1]) / sqrt(3), 1) dirac_dist = HypersphericalDiracDistribution.from_distribution(vmf, 100000) np.testing.assert_almost_equal( dirac_dist.mean_direction(), vmf.mean_direction(), decimal=2 diff --git a/pyrecest/tests/distributions/test_hyperspherical_mixture.py b/pyrecest/tests/distributions/test_hyperspherical_mixture.py index d569f80b..8da16d3e 100644 --- a/pyrecest/tests/distributions/test_hyperspherical_mixture.py +++ b/pyrecest/tests/distributions/test_hyperspherical_mixture.py @@ -1,3 +1,9 @@ +from pyrecest.backend import sum +from pyrecest.backend import stack +from pyrecest.backend import sqrt +from pyrecest.backend import meshgrid +from pyrecest.backend import linspace +from pyrecest.backend import array import unittest import numpy as np @@ -12,16 +18,16 @@ class HypersphericalMixtureTest(unittest.TestCase): def test_pdf_3d(self): - wad = WatsonDistribution(np.array([0, 0, 1]), -10) - vmf = VonMisesFisherDistribution(np.array([0, 0, 1]), 1) + wad = WatsonDistribution(array([0, 0, 1]), -10) + vmf = VonMisesFisherDistribution(array([0, 0, 1]), 1) w = [0.3, 0.7] smix = HypersphericalMixture([wad, vmf], w) - phi, theta = np.meshgrid( - np.linspace(0, 2 * np.pi, 10), np.linspace(-np.pi / 2, np.pi / 2, 10) + phi, theta = meshgrid( + linspace(0, 2 * np.pi, 10), linspace(-np.pi / 2, np.pi / 2, 10) ) points = AbstractHypersphereSubsetDistribution.polar_to_cart( - np.stack([phi.ravel(), theta.ravel()], axis=-1) + stack([phi.ravel(), theta.ravel()], axis=-1) ) assert_allclose( @@ -31,14 +37,14 @@ def test_pdf_3d(self): ) def test_pdf_4d(self): - wad = WatsonDistribution(np.array([0, 0, 0, 1]), -10) - vmf = VonMisesFisherDistribution(np.array([0, 1, 0, 0]), 1) + wad = WatsonDistribution(array([0, 0, 0, 1]), -10) + vmf = VonMisesFisherDistribution(array([0, 1, 0, 0]), 1) w = [0.3, 0.7] smix = HypersphericalMixture([wad, vmf], w) a, b, c, d = np.mgrid[-1:1:4j, -1:1:4j, -1:1:4j, -1:1:4j] - points = np.array([a.ravel(), b.ravel(), c.ravel(), d.ravel()]).T - points = points / np.sqrt(np.sum(points**2, axis=1, keepdims=True)) + points = array([a.ravel(), b.ravel(), c.ravel(), d.ravel()]).T + points = points / sqrt(sum(points**2, axis=1, keepdims=True)) assert_allclose( smix.pdf(points), diff --git a/pyrecest/tests/distributions/test_hyperspherical_uniform_distribution.py b/pyrecest/tests/distributions/test_hyperspherical_uniform_distribution.py index f0662452..c637f2b8 100644 --- a/pyrecest/tests/distributions/test_hyperspherical_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_hyperspherical_uniform_distribution.py @@ -1,3 +1,6 @@ +from pyrecest.backend import ones +from pyrecest.backend import allclose +from pyrecest.backend import all """ Test for uniform distribution on the hypersphere """ import unittest @@ -39,7 +42,7 @@ def test_sample(self): samples = hud.sample(n) self.assertEqual(samples.shape, (n, hud.dim + 1)) self.assertTrue( - np.allclose(np.linalg.norm(samples, axis=1), np.ones(n), rtol=1e-10) + allclose(np.linalg.norm(samples, axis=1), ones(n), rtol=1e-10) ) diff --git a/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py b/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py index 81adf082..5f28e6c3 100644 --- a/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py @@ -1,3 +1,11 @@ +from pyrecest.backend import sum +from pyrecest.backend import squeeze +from pyrecest.backend import outer +from pyrecest.backend import ones_like +from pyrecest.backend import ones +from pyrecest.backend import mod +from pyrecest.backend import exp +from pyrecest.backend import array import copy import unittest @@ -10,10 +18,10 @@ class TestHypertoroidalDiracDistribution(unittest.TestCase): def setUp(self): - self.d = np.array( + self.d = array( [[0.5, 2, 0.5], [3, 2, 0.2], [4, 5, 5.8], [6, 3, 4.3], [6, 0, 1.2]] ) - self.w = np.array([0.1, 0.1, 0.1, 0.1, 0.6]) + self.w = array([0.1, 0.1, 0.1, 0.1, 0.6]) self.twd = HypertoroidalDiracDistribution(self.d, self.w) def test_init(self): @@ -28,44 +36,44 @@ def test_trigonometric_moment(self): np.testing.assert_almost_equal(m[0], m1, decimal=10) np.testing.assert_almost_equal(m[1], m2, decimal=10) np.testing.assert_almost_equal( - m[0], np.sum(self.w * np.exp(1j * self.d[:, 0])), decimal=10 + m[0], sum(self.w * exp(1j * self.d[:, 0])), decimal=10 ) np.testing.assert_almost_equal( - m[1], np.sum(self.w * np.exp(1j * self.d[:, 1])), decimal=10 + m[1], sum(self.w * exp(1j * self.d[:, 1])), decimal=10 ) def test_sample(self): n_samples = 5 s = self.twd.sample(n_samples) self.assertEqual(s.shape, (n_samples, self.d.shape[-1])) - np.testing.assert_array_almost_equal(s, np.mod(s, 2 * np.pi)) + np.testing.assert_array_almost_equal(s, mod(s, 2 * np.pi)) def test_marginalize_to_1D(self): for i in range(self.d.shape[-1]): wd = self.twd.marginalize_to_1D(i) np.testing.assert_array_almost_equal(self.twd.w, wd.w) - np.testing.assert_array_almost_equal(np.squeeze(wd.d), self.twd.d[:, i]) + np.testing.assert_array_almost_equal(squeeze(wd.d), self.twd.d[:, i]) def test_apply_function(self): same = self.twd.apply_function(lambda x: x) np.testing.assert_array_almost_equal( same.trigonometric_moment(1), self.twd.trigonometric_moment(1) ) - shift_offset = np.array([1.4, -0.3, np.pi]) + shift_offset = array([1.4, -0.3, np.pi]) shifted = self.twd.apply_function(lambda x: x + shift_offset) np.testing.assert_almost_equal( shifted.trigonometric_moment(1)[0], - np.sum(self.w * np.exp(1j * (self.d[:, 0] + shift_offset[0]))), + sum(self.w * exp(1j * (self.d[:, 0] + shift_offset[0]))), decimal=10, ) np.testing.assert_almost_equal( shifted.trigonometric_moment(1)[1], - np.sum(self.w * np.exp(1j * (self.d[:, 1] + shift_offset[1]))), + sum(self.w * exp(1j * (self.d[:, 1] + shift_offset[1]))), decimal=10, ) def test_shift(self): - d = np.array( + d = array( [ [4, -2, 0.01], [3, 2, 0], @@ -75,15 +83,15 @@ def test_shift(self): ] ) - w = np.array([0.3, 0.3, 0.3, 0.05, 0.05]) + w = array([0.3, 0.3, 0.3, 0.05, 0.05]) twd = HypertoroidalDiracDistribution(d, w) - s = np.array([1, -3, 6]) + s = array([1, -3, 6]) twd_shifted = twd.shift(s) self.assertIsInstance(twd_shifted, HypertoroidalDiracDistribution) np.testing.assert_array_almost_equal(twd.w, twd_shifted.w) np.testing.assert_array_almost_equal( twd.d, - np.mod(twd_shifted.d - np.outer(np.ones_like(w), s), 2 * np.pi), + mod(twd_shifted.d - outer(ones_like(w), s), 2 * np.pi), decimal=10, ) @@ -93,7 +101,7 @@ def get_pseudorandom_hypertoroidal_wd(dim=2): n = 20 d = 2 * np.pi * np.random.rand(n, dim) w = np.random.rand(n) - w = w / np.sum(w) + w = w / sum(w) hwd = HypertoroidalDiracDistribution(d, w) return hwd @@ -109,7 +117,7 @@ def test_marginalization(self): hwd = TestHypertoroidalDiracDistribution.get_pseudorandom_hypertoroidal_wd(2) wd1 = hwd.marginalize_to_1D(0) wd2 = hwd.marginalize_out(1) - np.testing.assert_array_almost_equal(wd1.d, np.squeeze(wd2.d)) + np.testing.assert_array_almost_equal(wd1.d, squeeze(wd2.d)) np.testing.assert_array_almost_equal(wd1.w, wd2.w) diff --git a/pyrecest/tests/distributions/test_hypertoroidal_wrapped_normal_distribution.py b/pyrecest/tests/distributions/test_hypertoroidal_wrapped_normal_distribution.py index 2a50cd87..9eee518a 100644 --- a/pyrecest/tests/distributions/test_hypertoroidal_wrapped_normal_distribution.py +++ b/pyrecest/tests/distributions/test_hypertoroidal_wrapped_normal_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import array import unittest import numpy as np @@ -6,15 +7,15 @@ class TestHypertoroidalWNDistribution(unittest.TestCase): def test_pdf(self): - mu = np.array([[1], [2]]) - C = np.array([[0.5, 0.1], [0.1, 0.3]]) + mu = array([[1], [2]]) + C = array([[0.5, 0.1], [0.1, 0.3]]) hwn = HypertoroidalWNDistribution(mu, C) - xa = np.array([[0, 1, 2], [1, 2, 3]]).T + xa = array([[0, 1, 2], [1, 2, 3]]).T pdf_values = hwn.pdf(xa) - expected_values = np.array( + expected_values = array( [0.0499028191873498, 0.425359477472412, 0.0499028191873498] ) np.testing.assert_allclose(pdf_values, expected_values, rtol=1e-12) diff --git a/pyrecest/tests/distributions/test_linear_dirac_distribution.py b/pyrecest/tests/distributions/test_linear_dirac_distribution.py index 637113a1..48a45b52 100644 --- a/pyrecest/tests/distributions/test_linear_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_linear_dirac_distribution.py @@ -1,3 +1,7 @@ +from pyrecest.backend import eye +from pyrecest.backend import array +from pyrecest.backend import allclose +from pyrecest.backend import all import unittest import numpy as np @@ -11,18 +15,18 @@ class LinearDiracDistributionTest(unittest.TestCase): def test_from_distribution(self): np.random.seed(0) - C = wishart.rvs(3, np.eye(3)) - hwn = GaussianDistribution(np.array([1, 2, 3]), C) + C = wishart.rvs(3, eye(3)) + hwn = GaussianDistribution(array([1, 2, 3]), C) hwd = LinearDiracDistribution.from_distribution(hwn, 100000) - self.assertTrue(np.allclose(hwd.mean(), hwn.mean(), atol=0.005)) - self.assertTrue(np.allclose(hwd.covariance(), hwn.covariance(), rtol=0.01)) + self.assertTrue(allclose(hwd.mean(), hwn.mean(), atol=0.005)) + self.assertTrue(allclose(hwd.covariance(), hwn.covariance(), rtol=0.01)) def test_mean_and_cov(self): np.random.seed(0) - gd = GaussianDistribution(np.array([1, 2]), np.array([[2, -0.3], [-0.3, 1]])) + gd = GaussianDistribution(array([1, 2]), array([[2, -0.3], [-0.3, 1]])) ddist = LinearDiracDistribution(gd.sample(10000)) - self.assertTrue(np.allclose(ddist.mean(), gd.mean(), atol=0.05)) - self.assertTrue(np.allclose(ddist.covariance(), gd.covariance(), atol=0.05)) + self.assertTrue(allclose(ddist.mean(), gd.mean(), atol=0.05)) + self.assertTrue(allclose(ddist.covariance(), gd.covariance(), atol=0.05)) if __name__ == "__main__": diff --git a/pyrecest/tests/distributions/test_linear_mixture.py b/pyrecest/tests/distributions/test_linear_mixture.py index 80d83b80..428b18b8 100644 --- a/pyrecest/tests/distributions/test_linear_mixture.py +++ b/pyrecest/tests/distributions/test_linear_mixture.py @@ -1,3 +1,6 @@ +from pyrecest.backend import meshgrid +from pyrecest.backend import linspace +from pyrecest.backend import array import unittest from warnings import catch_warnings, simplefilter @@ -12,10 +15,10 @@ def test_constructor_warning(self): simplefilter("always") LinearMixture( [ - GaussianDistribution(np.array(1), np.array(1)), - GaussianDistribution(np.array(50), np.array(1)), + GaussianDistribution(array(1), array(1)), + GaussianDistribution(array(50), array(1)), ], - np.array([0.3, 0.7]), + array([0.3, 0.7]), ) self.assertEqual(len(w), 1) self.assertTrue(issubclass(w[-1].category, UserWarning)) @@ -25,14 +28,14 @@ def test_constructor_warning(self): ) def test_pdf(self): - gm1 = GaussianDistribution(np.array([1, 1]), np.diag([2, 3])) - gm2 = GaussianDistribution(-np.array([3, 1]), np.diag([2, 3])) + gm1 = GaussianDistribution(array([1, 1]), np.diag([2, 3])) + gm2 = GaussianDistribution(-array([3, 1]), np.diag([2, 3])) with catch_warnings(): simplefilter("ignore", category=UserWarning) - lm = LinearMixture([gm1, gm2], np.array([0.3, 0.7])) + lm = LinearMixture([gm1, gm2], array([0.3, 0.7])) - x, y = np.meshgrid(np.linspace(-2, 2, 100), np.linspace(-2, 2, 100)) + x, y = meshgrid(linspace(-2, 2, 100), linspace(-2, 2, 100)) points = np.column_stack((x.ravel(), y.ravel())) np.testing.assert_allclose( diff --git a/pyrecest/tests/distributions/test_partially_wrapped_normal_distribution.py b/pyrecest/tests/distributions/test_partially_wrapped_normal_distribution.py index eb278eb8..a73b9255 100644 --- a/pyrecest/tests/distributions/test_partially_wrapped_normal_distribution.py +++ b/pyrecest/tests/distributions/test_partially_wrapped_normal_distribution.py @@ -1,3 +1,5 @@ +from pyrecest.backend import ones +from pyrecest.backend import array import unittest import numpy as np @@ -9,19 +11,19 @@ class TestPartiallyWrappedNormalDistribution(unittest.TestCase): def setUp(self) -> None: - self.mu = np.array([5, 1]) - self.C = np.array([[2, 1], [1, 1]]) + self.mu = array([5, 1]) + self.C = array([[2, 1], [1, 1]]) self.dist_2d = PartiallyWrappedNormalDistribution(self.mu, self.C, 1) def test_pdf(self): - self.assertEqual(self.dist_2d.pdf(np.ones((10, 2))).shape, (10,)) + self.assertEqual(self.dist_2d.pdf(ones((10, 2))).shape, (10,)) def test_hybrid_mean_2d(self): np.testing.assert_allclose(self.dist_2d.hybrid_mean(), self.mu) def test_hybrid_mean_4d(self): - mu = np.array([5, 1, 3, 4]) - C = np.array(scipy.linalg.block_diag([[2, 1], [1, 1]], [[2, 1], [1, 1]])) + mu = array([5, 1, 3, 4]) + C = array(scipy.linalg.block_diag([[2, 1], [1, 1]], [[2, 1], [1, 1]])) dist = PartiallyWrappedNormalDistribution(mu, C, 2) np.testing.assert_allclose(dist.hybrid_mean(), mu) diff --git a/pyrecest/tests/distributions/test_se3_dirac_distribution.py b/pyrecest/tests/distributions/test_se3_dirac_distribution.py index effa565e..1c750c4c 100644 --- a/pyrecest/tests/distributions/test_se3_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_se3_dirac_distribution.py @@ -1,3 +1,7 @@ +from pyrecest.backend import tile +from pyrecest.backend import sum +from pyrecest.backend import concatenate +from pyrecest.backend import array import unittest import numpy as np @@ -13,7 +17,7 @@ class SE3DiracDistributionTest(unittest.TestCase): def test_constructor(self): - dSph = np.array( + dSph = array( [ [1, 2, 3, 4, 5, 6], [2, 4, 0, 0.5, 1, 1], @@ -22,16 +26,16 @@ def test_constructor(self): ] ).T dSph = dSph / np.linalg.norm(dSph, axis=-1, keepdims=True) - dLin = np.tile(np.array([-5, 0, 5, 10, 15, 20]), (3, 1)).T - w = np.array([1, 2, 3, 1, 2, 3]) - w = w / np.sum(w) - SE3DiracDistribution(np.concatenate((dSph, dLin), axis=-1), w) + dLin = tile(array([-5, 0, 5, 10, 15, 20]), (3, 1)).T + w = array([1, 2, 3, 1, 2, 3]) + w = w / sum(w) + SE3DiracDistribution(concatenate((dSph, dLin), axis=-1), w) def test_from_distribution(self): cpsd = SE3CartProdStackedDistribution( [ HyperhemisphericalUniformDistribution(3), - GaussianDistribution(np.array([1, 2, 3]).T, np.diag([3, 2, 1])), + GaussianDistribution(array([1, 2, 3]).T, np.diag([3, 2, 1])), ] ) SE3DiracDistribution.from_distribution(cpsd, 100) diff --git a/pyrecest/tests/distributions/test_sphere_subset_distribution.py b/pyrecest/tests/distributions/test_sphere_subset_distribution.py index c6d709cc..4da5380a 100644 --- a/pyrecest/tests/distributions/test_sphere_subset_distribution.py +++ b/pyrecest/tests/distributions/test_sphere_subset_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import array import unittest import numpy as np @@ -16,9 +17,9 @@ class TestAbstractSphereSubsetDistribution(unittest.TestCase): ) def test_cart_to_sph_to_cart(self, mode): # Create some Cartesian coordinates - x = np.array([1.0, 0.0, 0.0]) - y = np.array([0.0, 1.0, 0.0]) - z = np.array([0.0, 0.0, 1.0]) + x = array([1.0, 0.0, 0.0]) + y = array([0.0, 1.0, 0.0]) + z = array([0.0, 0.0, 1.0]) # Convert to spherical coordinates and back azimuth, theta = AbstractSphereSubsetDistribution.cart_to_sph( @@ -43,8 +44,8 @@ def test_sph_to_cart_to_sph(self, mode): # Create some spherical coordinates. Do *not* use 0 as theta because # the transformation from spherical to Cartesian coordinates is not # uniquely invertible in this case. - azimuth = np.array([0.0, np.pi / 4, np.pi / 2]) - theta = np.array([np.pi / 2, np.pi / 4, 0.1]) + azimuth = array([0.0, np.pi / 4, np.pi / 2]) + theta = array([np.pi / 2, np.pi / 4, 0.1]) # Convert to Cartesian coordinates and back x, y, z = AbstractSphereSubsetDistribution.sph_to_cart( diff --git a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py index f2959c15..4aaa74db 100644 --- a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py +++ b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py @@ -1,3 +1,16 @@ +from pyrecest.backend import sqrt +from pyrecest.backend import sin +from pyrecest.backend import ones_like +from pyrecest.backend import ones +from pyrecest.backend import meshgrid +from pyrecest.backend import linspace +from pyrecest.backend import isnan +from pyrecest.backend import exp +from pyrecest.backend import cos +from pyrecest.backend import array +from pyrecest.backend import allclose +from pyrecest.backend import all +from pyrecest.backend import zeros import unittest import numpy as np @@ -18,7 +31,7 @@ class SphericalHarmonicsDistributionComplexTest(unittest.TestCase): def setUp(self): np.random.seed(1) coeff_rand = np.random.rand(9) - self.unnormalized_coeffs = np.array( + self.unnormalized_coeffs = array( [ [coeff_rand[0], np.nan, np.nan, np.nan, np.nan], [ @@ -52,16 +65,16 @@ def test_normalization(self): np.random.rand(1, 10) * 2 * np.pi, np.random.rand(1, 10) * np.pi - np.pi / 2, ) - x, y, z = np.array( - [np.cos(theta) * np.cos(phi), np.cos(theta) * np.sin(phi), np.sin(theta)] + x, y, z = array( + [cos(theta) * cos(phi), cos(theta) * sin(phi), sin(theta)] ) vals_normalized = shd.pdf(np.column_stack([x, y, z])) shd.coeff_mat = self.unnormalized_coeffs vals_unnormalized = shd.pdf(np.column_stack([x, y, z])) self.assertTrue( - np.allclose( + allclose( np.diff(vals_normalized / vals_unnormalized), - np.zeros(vals_normalized.shape[0] - 1), + zeros(vals_normalized.shape[0] - 1), atol=1e-6, ) ) @@ -71,7 +84,7 @@ def test_integral_analytical(self, transformation): """Test if the analytical integral is equal to the numerical integral""" np.random.seed(10) coeff_rand = np.random.rand(1, 9) - unnormalized_coeffs = np.array( + unnormalized_coeffs = array( [ [coeff_rand[0, 0], np.nan, np.nan, np.nan, np.nan], [ @@ -92,7 +105,7 @@ def test_integral_analytical(self, transformation): ) # First initialize and overwrite afterward to prevent normalization shd = SphericalHarmonicsDistributionComplex( - np.array([[1, np.nan, np.nan], [0, 0, 0]]) + array([[1, np.nan, np.nan], [0, 0, 0]]) ) shd.coeff_mat = unnormalized_coeffs shd.transformation = transformation @@ -107,13 +120,13 @@ def test_truncation(self): shd2 = shd.truncate(4) self.assertEqual(shd2.coeff_mat.shape, (5, 9)) self.assertTrue( - np.all(np.isnan(shd2.coeff_mat[4, :]) | (shd2.coeff_mat[4, :] == 0)) + all(isnan(shd2.coeff_mat[4, :]) | (shd2.coeff_mat[4, :] == 0)) ) shd3 = shd.truncate(5) self.assertEqual(shd3.coeff_mat.shape, (6, 11)) self.assertTrue( - np.all( - np.isnan(shd3.coeff_mat[5:6, :]) | (shd3.coeff_mat[5:6, :] == 0), + all( + isnan(shd3.coeff_mat[5:6, :]) | (shd3.coeff_mat[5:6, :] == 0), axis=(0, 1), ) ) @@ -125,28 +138,28 @@ def test_truncation(self): phi, theta = np.random.rand(10) * 2 * np.pi, np.random.rand(10) * np.pi x, y, z = AbstractSphericalDistribution.sph_to_cart(phi, theta) self.assertTrue( - np.allclose( + allclose( shd2.pdf(np.column_stack((x, y, z))), shd.pdf(np.column_stack((x, y, z))), atol=1e-6, ) ) self.assertTrue( - np.allclose( + allclose( shd3.pdf(np.column_stack((x, y, z))), shd.pdf(np.column_stack((x, y, z))), atol=1e-6, ) ) self.assertTrue( - np.allclose( + allclose( shd4.pdf(np.column_stack((x, y, z))), shd.pdf(np.column_stack((x, y, z))), atol=1e-6, ) ) self.assertTrue( - np.allclose( + allclose( shd5.pdf(np.column_stack((x, y, z))), shd.pdf(np.column_stack((x, y, z))), atol=1e-6, @@ -158,29 +171,29 @@ def test_truncation(self): # First, the basis functions that only yield real values are tested ( "testl0m0", - np.array( + array( [ [1, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan], [0, 0, 0, 0, 0], ] ), - lambda _, _1, z: np.ones_like(z) * np.sqrt(1 / (4 * np.pi)), + lambda _, _1, z: ones_like(z) * sqrt(1 / (4 * np.pi)), ), ( "testl1m0", - np.array( + array( [ [0, np.nan, np.nan, np.nan, np.nan], [0, 1, 0, np.nan, np.nan], [0, 0, 0, 0, 0], ] ), - lambda _, _1, z: np.sqrt(3 / (4 * np.pi)) * z, + lambda _, _1, z: sqrt(3 / (4 * np.pi)) * z, ), ( "testl2m0", - np.array( + array( [ [0, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan], @@ -189,12 +202,12 @@ def test_truncation(self): ), lambda x, y, z: 1 / 4 - * np.sqrt(5 / np.pi) + * sqrt(5 / np.pi) * (2 * z**2 - x**2 - y**2), ), ( "testl3m0", - np.array( + array( [ [0, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan, np.nan, np.nan], @@ -204,7 +217,7 @@ def test_truncation(self): ), lambda x, y, z: 1 / 4 - * np.sqrt(7 / np.pi) + * sqrt(7 / np.pi) * (z * (2 * z**2 - 3 * x**2 - 3 * y**2)), ), # For the other basis functions, complex values would be obtained. @@ -212,165 +225,165 @@ def test_truncation(self): # to complex basis functions ( "test_l1mneg1real", - np.array( + array( [ [0, np.nan, np.nan, np.nan, np.nan], - [1j * np.sqrt(1 / 2), 0, 1j * np.sqrt(1 / 2), np.nan, np.nan], + [1j * sqrt(1 / 2), 0, 1j * sqrt(1 / 2), np.nan, np.nan], [0, 0, 0, 0, 0], ] ), - lambda _, y, _1: np.sqrt(3 / (4 * np.pi)) * y, + lambda _, y, _1: sqrt(3 / (4 * np.pi)) * y, ), ( "test_l1m1real", - np.array( + array( [ [0, np.nan, np.nan, np.nan, np.nan], - [np.sqrt(1 / 2), 0, -np.sqrt(1 / 2), np.nan, np.nan], + [sqrt(1 / 2), 0, -sqrt(1 / 2), np.nan, np.nan], [0, 0, 0, 0, 0], ] ), - lambda x, _, _1: np.sqrt(3 / (4 * np.pi)) * x, + lambda x, _, _1: sqrt(3 / (4 * np.pi)) * x, ), ( "test_l2mneg2real", - np.array( + array( [ [0, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan], - [1j * np.sqrt(1 / 2), 0, 0, 0, -1j * np.sqrt(1 / 2)], + [1j * sqrt(1 / 2), 0, 0, 0, -1j * sqrt(1 / 2)], ] ), - lambda x, y, _: 1 / 2 * np.sqrt(15 / np.pi) * x * y, + lambda x, y, _: 1 / 2 * sqrt(15 / np.pi) * x * y, ), ( "test_l2mneg1real", - np.array( + array( [ [0, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan], - [0, 1j * np.sqrt(1 / 2), 0, 1j * np.sqrt(1 / 2), 0], + [0, 1j * sqrt(1 / 2), 0, 1j * sqrt(1 / 2), 0], ] ), - lambda _, y, z: 1 / 2 * np.sqrt(15 / np.pi) * y * z, + lambda _, y, z: 1 / 2 * sqrt(15 / np.pi) * y * z, ), ( "test_l2m1real", - np.array( + array( [ [0, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan], - [0, np.sqrt(1 / 2), 0, -np.sqrt(1 / 2), 0], + [0, sqrt(1 / 2), 0, -sqrt(1 / 2), 0], ] ), - lambda x, _, z: 1 / 2 * np.sqrt(15 / np.pi) * x * z, + lambda x, _, z: 1 / 2 * sqrt(15 / np.pi) * x * z, ), ( "test_l2m2real", - np.array( + array( [ [0, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan], - [np.sqrt(1 / 2), 0, 0, 0, np.sqrt(1 / 2)], + [sqrt(1 / 2), 0, 0, 0, sqrt(1 / 2)], ] ), - lambda x, y, _: 1 / 4 * np.sqrt(15 / np.pi) * (x**2 - y**2), + lambda x, y, _: 1 / 4 * sqrt(15 / np.pi) * (x**2 - y**2), ), ( "test_l3mneg3real", - np.array( + array( [ [0, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, 0, 0, np.nan, np.nan], - [1j / np.sqrt(2), 0, 0, 0, 0, 0, 1j / np.sqrt(2)], + [1j / sqrt(2), 0, 0, 0, 0, 0, 1j / sqrt(2)], ] ), lambda x, y, z: 1 / 4 - * np.sqrt(35 / (2 * np.pi)) + * sqrt(35 / (2 * np.pi)) * y * (3 * x**2 - y**2), ), ( "test_l3mneg2real", - np.array( + array( [ [0, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, 0, 0, np.nan, np.nan], - [0, 1j / np.sqrt(2), 0, 0, 0, -1j / np.sqrt(2), 0], + [0, 1j / sqrt(2), 0, 0, 0, -1j / sqrt(2), 0], ] ), - lambda x, y, z: 1 / 2 * np.sqrt(105 / np.pi) * x * y * z, + lambda x, y, z: 1 / 2 * sqrt(105 / np.pi) * x * y * z, ), ( "test_l3mneg1real", - np.array( + array( [ [0, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, 0, 0, np.nan, np.nan], - [0, 0, 1j / np.sqrt(2), 0, 1j / np.sqrt(2), 0, 0], + [0, 0, 1j / sqrt(2), 0, 1j / sqrt(2), 0, 0], ] ), lambda x, y, z: 1 / 4 - * np.sqrt(21 / (2 * np.pi)) + * sqrt(21 / (2 * np.pi)) * y * (4 * z**2 - x**2 - y**2), ), ( "test_l3m1real", - np.array( + array( [ [0, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, 0, 0, np.nan, np.nan], - [0, 0, 1 / np.sqrt(2), 0, -1 / np.sqrt(2), 0, 0], + [0, 0, 1 / sqrt(2), 0, -1 / sqrt(2), 0, 0], ] ), lambda x, y, z: 1 / 4 - * np.sqrt(21 / (2 * np.pi)) + * sqrt(21 / (2 * np.pi)) * x * (4 * z**2 - x**2 - y**2), ), ( "test_l3m2real", - np.array( + array( [ [0, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, 0, 0, np.nan, np.nan], - [0, 1 / np.sqrt(2), 0, 0, 0, 1 / np.sqrt(2), 0], + [0, 1 / sqrt(2), 0, 0, 0, 1 / sqrt(2), 0], ] ), - lambda x, y, z: 1 / 4 * np.sqrt(105 / np.pi) * z * (x**2 - y**2), + lambda x, y, z: 1 / 4 * sqrt(105 / np.pi) * z * (x**2 - y**2), ), ( "test_l3m3real", - np.array( + array( [ [0, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, 0, 0, np.nan, np.nan], - [1 / np.sqrt(2), 0, 0, 0, 0, 0, -1 / np.sqrt(2)], + [1 / sqrt(2), 0, 0, 0, 0, 0, -1 / sqrt(2)], ] ), lambda x, y, z: 1 / 4 - * np.sqrt(35 / (2 * np.pi)) + * sqrt(35 / (2 * np.pi)) * x * (x**2 - 3 * y**2), ), ] ) def test_basis_function(self, _, coeff_mat, expected_func): - shd = SphericalHarmonicsDistributionComplex(1 / np.sqrt(4 * np.pi)) + shd = SphericalHarmonicsDistributionComplex(1 / sqrt(4 * np.pi)) shd.coeff_mat = coeff_mat - phi, theta = np.meshgrid( - np.linspace(0, 2 * np.pi, 10), np.linspace(0, np.pi, 10) + phi, theta = meshgrid( + linspace(0, 2 * np.pi, 10), linspace(0, np.pi, 10) ) x, y, z = AbstractSphericalDistribution.sph_to_cart(phi.ravel(), theta.ravel()) np.testing.assert_allclose( @@ -382,74 +395,74 @@ def test_basis_function(self, _, coeff_mat, expected_func): # Test complex basis functions ( "testl1mneg1_cart", - np.array( + array( [ [0, np.nan, np.nan, np.nan, np.nan], [1, 0, 0, np.nan, np.nan], [0, 0, 0, 0, 0], ] ), - lambda x, y, _: 0.5 * np.sqrt(3 / (2 * np.pi)) * (x - 1j * y), + lambda x, y, _: 0.5 * sqrt(3 / (2 * np.pi)) * (x - 1j * y), ), ( "testl1m1_cart", - np.array( + array( [ [0, np.nan, np.nan, np.nan, np.nan], [0, 0, 1, np.nan, np.nan], [0, 0, 0, 0, 0], ] ), - lambda x, y, _: -0.5 * np.sqrt(3 / (2 * np.pi)) * (x + 1j * y), + lambda x, y, _: -0.5 * sqrt(3 / (2 * np.pi)) * (x + 1j * y), ), ( "testl2mneg2_cart", - np.array( + array( [ [0, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan], [1, 0, 0, 0, 0], ] ), - lambda x, y, _: 0.25 * np.sqrt(15 / (2 * np.pi)) * (x - 1j * y) ** 2, + lambda x, y, _: 0.25 * sqrt(15 / (2 * np.pi)) * (x - 1j * y) ** 2, ), ( "testl2mneg1_cart", - np.array( + array( [ [0, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan], [0, 1, 0, 0, 0], ] ), - lambda x, y, z: 0.5 * np.sqrt(15 / (2 * np.pi)) * (x - 1j * y) * z, + lambda x, y, z: 0.5 * sqrt(15 / (2 * np.pi)) * (x - 1j * y) * z, ), ( "testl2m1_cart", - np.array( + array( [ [0, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan], [0, 0, 0, 1, 0], ] ), - lambda x, y, z: -0.5 * np.sqrt(15 / (2 * np.pi)) * (x + 1j * y) * z, + lambda x, y, z: -0.5 * sqrt(15 / (2 * np.pi)) * (x + 1j * y) * z, ), ( "testl2m2_cart", - np.array( + array( [ [0, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan], [0, 0, 0, 0, 1], ] ), - lambda x, y, _: 0.25 * np.sqrt(15 / (2 * np.pi)) * (x + 1j * y) ** 2, + lambda x, y, _: 0.25 * sqrt(15 / (2 * np.pi)) * (x + 1j * y) ** 2, ), # For spherical coordinates ( "testl1mneg1_sph", - np.array( + array( [ [0, np.nan, np.nan, np.nan, np.nan], [1, 0, 0, np.nan, np.nan], @@ -457,13 +470,13 @@ def test_basis_function(self, _, coeff_mat, expected_func): ] ), lambda phi, theta: 0.5 - * np.sqrt(3 / (2 * np.pi)) - * np.sin(theta) - * np.exp(-1j * phi), + * sqrt(3 / (2 * np.pi)) + * sin(theta) + * exp(-1j * phi), ), ( "testl1m1_sph", - np.array( + array( [ [0, np.nan, np.nan, np.nan, np.nan], [0, 0, 1, np.nan, np.nan], @@ -471,13 +484,13 @@ def test_basis_function(self, _, coeff_mat, expected_func): ] ), lambda phi, theta: -0.5 - * np.sqrt(3 / (2 * np.pi)) - * np.sin(theta) - * np.exp(1j * phi), + * sqrt(3 / (2 * np.pi)) + * sin(theta) + * exp(1j * phi), ), ( "testl2mneg2_sph", - np.array( + array( [ [0, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan], @@ -485,13 +498,13 @@ def test_basis_function(self, _, coeff_mat, expected_func): ] ), lambda phi, theta: 0.25 - * np.sqrt(15 / (2 * np.pi)) - * np.sin(theta) ** 2 - * np.exp(-2j * phi), + * sqrt(15 / (2 * np.pi)) + * sin(theta) ** 2 + * exp(-2j * phi), ), ( "testl2mneg1_sph", - np.array( + array( [ [0, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan], @@ -499,14 +512,14 @@ def test_basis_function(self, _, coeff_mat, expected_func): ] ), lambda phi, theta: 0.5 - * np.sqrt(15 / (2 * np.pi)) - * np.sin(theta) - * np.cos(theta) - * np.exp(-1j * phi), + * sqrt(15 / (2 * np.pi)) + * sin(theta) + * cos(theta) + * exp(-1j * phi), ), ( "testl2m1_sph", - np.array( + array( [ [0, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan], @@ -514,14 +527,14 @@ def test_basis_function(self, _, coeff_mat, expected_func): ] ), lambda phi, theta: -0.5 - * np.sqrt(15 / (2 * np.pi)) - * np.sin(theta) - * np.cos(theta) - * np.exp(1j * phi), + * sqrt(15 / (2 * np.pi)) + * sin(theta) + * cos(theta) + * exp(1j * phi), ), ( "testl2m2_sph", - np.array( + array( [ [0, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan], @@ -529,13 +542,13 @@ def test_basis_function(self, _, coeff_mat, expected_func): ] ), lambda phi, theta: 0.25 - * np.sqrt(15 / (2 * np.pi)) - * np.sin(theta) ** 2 - * np.exp(2j * phi), + * sqrt(15 / (2 * np.pi)) + * sin(theta) ** 2 + * exp(2j * phi), ), ( "testl1mneg1_sphconv_colatitude", - np.array( + array( [ [0, np.nan, np.nan, np.nan, np.nan], [1, 0, 0, np.nan, np.nan], @@ -543,13 +556,13 @@ def test_basis_function(self, _, coeff_mat, expected_func): ] ), lambda phi, theta: 0.5 - * np.sqrt(3 / (2 * np.pi)) - * np.sin(theta) - * np.exp(-1j * phi), + * sqrt(3 / (2 * np.pi)) + * sin(theta) + * exp(-1j * phi), ), ( "testl1m1_sphconv_colatitude", - np.array( + array( [ [0, np.nan, np.nan, np.nan, np.nan], [0, 0, 1, np.nan, np.nan], @@ -557,13 +570,13 @@ def test_basis_function(self, _, coeff_mat, expected_func): ] ), lambda phi, theta: -0.5 - * np.sqrt(3 / (2 * np.pi)) - * np.sin(theta) - * np.exp(1j * phi), + * sqrt(3 / (2 * np.pi)) + * sin(theta) + * exp(1j * phi), ), ( "testl2mneg2_sphconv_colatitude", - np.array( + array( [ [0, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan], @@ -571,13 +584,13 @@ def test_basis_function(self, _, coeff_mat, expected_func): ] ), lambda phi, theta: 0.25 - * np.sqrt(15 / (2 * np.pi)) - * np.sin(theta) ** 2 - * np.exp(-2j * phi), + * sqrt(15 / (2 * np.pi)) + * sin(theta) ** 2 + * exp(-2j * phi), ), ( "testl2mneg1_sphconv_colatitude", - np.array( + array( [ [0, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan], @@ -585,14 +598,14 @@ def test_basis_function(self, _, coeff_mat, expected_func): ] ), lambda phi, theta: 0.5 - * np.sqrt(15 / (2 * np.pi)) - * np.sin(theta) - * np.cos(theta) - * np.exp(-1j * phi), + * sqrt(15 / (2 * np.pi)) + * sin(theta) + * cos(theta) + * exp(-1j * phi), ), ( "testl2m1_sphconv_colatitude", - np.array( + array( [ [0, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan], @@ -600,14 +613,14 @@ def test_basis_function(self, _, coeff_mat, expected_func): ] ), lambda phi, theta: -0.5 - * np.sqrt(15 / (2 * np.pi)) - * np.sin(theta) - * np.cos(theta) - * np.exp(1j * phi), + * sqrt(15 / (2 * np.pi)) + * sin(theta) + * cos(theta) + * exp(1j * phi), ), ( "testl2m2_sphconv_colatitude", - np.array( + array( [ [0, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan], @@ -615,19 +628,19 @@ def test_basis_function(self, _, coeff_mat, expected_func): ] ), lambda phi, theta: 0.25 - * np.sqrt(15 / (2 * np.pi)) - * np.sin(theta) ** 2 - * np.exp(2j * phi), + * sqrt(15 / (2 * np.pi)) + * sin(theta) ** 2 + * exp(2j * phi), ), ] ) def test_basis_function_complex(self, name, coeff_mat, expected_func): shd = SphericalHarmonicsDistributionComplex( - 1 / np.sqrt(4 * np.pi), assert_real=False + 1 / sqrt(4 * np.pi), assert_real=False ) shd.coeff_mat = coeff_mat - phi, theta = np.meshgrid( - np.linspace(0, 2 * np.pi, 10), np.linspace(-np.pi / 2, np.pi / 2, 10) + phi, theta = meshgrid( + linspace(0, 2 * np.pi, 10), linspace(-np.pi / 2, np.pi / 2, 10) ) x, y, z = AbstractSphericalDistribution.sph_to_cart(phi.ravel(), theta.ravel()) @@ -648,7 +661,7 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): [ ( "l0m0", - np.array( + array( [ [1, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan], @@ -658,17 +671,17 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): ), ( "l1mneg1", - np.array( + array( [ [1, np.nan, np.nan, np.nan, np.nan], - [1j * np.sqrt(1 / 2), 0, 1j * np.sqrt(1 / 2), np.nan, np.nan], + [1j * sqrt(1 / 2), 0, 1j * sqrt(1 / 2), np.nan, np.nan], [0, 0, 0, 0, 0], ] ), ), ( "l1m0", - np.array( + array( [ [1, np.nan, np.nan, np.nan, np.nan], [0, 1, 0, np.nan, np.nan], @@ -678,37 +691,37 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): ), ( "l1m1", - np.array( + array( [ [1, np.nan, np.nan, np.nan, np.nan], - [np.sqrt(1 / 2), 0, -np.sqrt(1 / 2), np.nan, np.nan], + [sqrt(1 / 2), 0, -sqrt(1 / 2), np.nan, np.nan], [0, 0, 0, 0, 0], ] ), ), ( "l2mneg2", - np.array( + array( [ [1, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan], - [1j * np.sqrt(1 / 2), 0, 0, 0, -1j * np.sqrt(1 / 2)], + [1j * sqrt(1 / 2), 0, 0, 0, -1j * sqrt(1 / 2)], ] ), ), ( "l2mneg1", - np.array( + array( [ [1, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan], - [0, 1j * np.sqrt(1 / 2), 0, 1j * np.sqrt(1 / 2), 0], + [0, 1j * sqrt(1 / 2), 0, 1j * sqrt(1 / 2), 0], ] ), ), ( "l2m0", - np.array( + array( [ [1, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan], @@ -718,60 +731,60 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): ), ( "l2m1", - np.array( + array( [ [1, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan], - [0, np.sqrt(1 / 2), 0, -np.sqrt(1 / 2), 0], + [0, sqrt(1 / 2), 0, -sqrt(1 / 2), 0], ] ), ), ( "l2m2", - np.array( + array( [ [1, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan], - [np.sqrt(1 / 2), 0, 0, 0, np.sqrt(1 / 2)], + [sqrt(1 / 2), 0, 0, 0, sqrt(1 / 2)], ] ), ), ( "l3mneg3", - np.array( + array( [ [1, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, 0, 0, np.nan, np.nan], - [1j / np.sqrt(2), 0, 0, 0, 0, 0, 1j / np.sqrt(2)], + [1j / sqrt(2), 0, 0, 0, 0, 0, 1j / sqrt(2)], ] ), ), ( "l3mneg2", - np.array( + array( [ [1, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, 0, 0, np.nan, np.nan], - [0, 1j / np.sqrt(2), 0, 0, 0, -1j / np.sqrt(2), 0], + [0, 1j / sqrt(2), 0, 0, 0, -1j / sqrt(2), 0], ] ), ), ( "l3mneg1", - np.array( + array( [ [1, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, 0, 0, np.nan, np.nan], - [0, 0, 1j / np.sqrt(2), 0, 1j / np.sqrt(2), 0, 0], + [0, 0, 1j / sqrt(2), 0, 1j / sqrt(2), 0, 0], ] ), ), ( "l3m0", - np.array( + array( [ [1, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan, np.nan, np.nan], @@ -782,34 +795,34 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): ), ( "l3m1", - np.array( + array( [ [1, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, 0, 0, np.nan, np.nan], - [0, 0, 1 / np.sqrt(2), 0, -1 / np.sqrt(2), 0, 0], + [0, 0, 1 / sqrt(2), 0, -1 / sqrt(2), 0, 0], ] ), ), ( "l3m2", - np.array( + array( [ [1, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, 0, 0, np.nan, np.nan], - [0, 1 / np.sqrt(2), 0, 0, 0, 1 / np.sqrt(2), 0], + [0, 1 / sqrt(2), 0, 0, 0, 1 / sqrt(2), 0], ] ), ), ( "l3m3", - np.array( + array( [ [1, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, 0, 0, np.nan, np.nan], - [1 / np.sqrt(2), 0, 0, 0, 0, 0, -1 / np.sqrt(2)], + [1 / sqrt(2), 0, 0, 0, 0, 0, -1 / sqrt(2)], ] ), ), @@ -818,8 +831,8 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): def test_conversion(self, _, coeff_mat): shd = SphericalHarmonicsDistributionComplex(coeff_mat) rshd = shd.to_spherical_harmonics_distribution_real() - phi, theta = np.meshgrid( - np.linspace(0, 2 * np.pi, 10), np.linspace(-np.pi / 2, np.pi / 2, 10) + phi, theta = meshgrid( + linspace(0, 2 * np.pi, 10), linspace(-np.pi / 2, np.pi / 2, 10) ) x, y, z = AbstractSphericalDistribution.sph_to_cart(phi.ravel(), theta.ravel()) np.testing.assert_allclose( @@ -832,71 +845,71 @@ def test_conversion(self, _, coeff_mat): [ ( "shd_x", - np.array([[1, np.nan, np.nan], [np.sqrt(1 / 2), 0, -np.sqrt(1 / 2)]]), - np.array([1, 0, 0]), + array([[1, np.nan, np.nan], [sqrt(1 / 2), 0, -sqrt(1 / 2)]]), + array([1, 0, 0]), SphericalHarmonicsDistributionComplex.mean_direction, ), ( "shd_y", - np.array( - [[1, np.nan, np.nan], [1j * np.sqrt(1 / 2), 0, 1j * np.sqrt(1 / 2)]] + array( + [[1, np.nan, np.nan], [1j * sqrt(1 / 2), 0, 1j * sqrt(1 / 2)]] ), - np.array([0, 1, 0]), + array([0, 1, 0]), SphericalHarmonicsDistributionComplex.mean_direction, ), ( "shd_z", - np.array([[1, np.nan, np.nan], [0, 1, 0]]), - np.array([0, 0, 1]), + array([[1, np.nan, np.nan], [0, 1, 0]]), + array([0, 0, 1]), SphericalHarmonicsDistributionComplex.mean_direction, ), ( "shd_xy", - np.array( + array( [ [1, np.nan, np.nan], [ - np.sqrt(1 / 2) + 1j * np.sqrt(1 / 2), + sqrt(1 / 2) + 1j * sqrt(1 / 2), 0, - -np.sqrt(1 / 2) + 1j * np.sqrt(1 / 2), + -sqrt(1 / 2) + 1j * sqrt(1 / 2), ], ] ), - np.array([1, 1, 0] / np.sqrt(2)), + array([1, 1, 0] / sqrt(2)), SphericalHarmonicsDistributionComplex.mean_direction, ), ( "shd_xz", - np.array([[1, np.nan, np.nan], [np.sqrt(1 / 2), 1, -np.sqrt(1 / 2)]]), - np.array([1, 0, 1] / np.sqrt(2)), + array([[1, np.nan, np.nan], [sqrt(1 / 2), 1, -sqrt(1 / 2)]]), + array([1, 0, 1] / sqrt(2)), SphericalHarmonicsDistributionComplex.mean_direction, ), ( "shd_yz", - np.array( - [[1, np.nan, np.nan], [1j * np.sqrt(1 / 2), 1, 1j * np.sqrt(1 / 2)]] + array( + [[1, np.nan, np.nan], [1j * sqrt(1 / 2), 1, 1j * sqrt(1 / 2)]] ), - np.array([0, 1, 1] / np.sqrt(2)), + array([0, 1, 1] / sqrt(2)), SphericalHarmonicsDistributionComplex.mean_direction, ), ( "numerical_shd_x", - np.array([[1, np.nan, np.nan], [np.sqrt(1 / 2), 0, -np.sqrt(1 / 2)]]), - np.array([1, 0, 0]), + array([[1, np.nan, np.nan], [sqrt(1 / 2), 0, -sqrt(1 / 2)]]), + array([1, 0, 0]), SphericalHarmonicsDistributionComplex.mean_direction_numerical, ), ( "numerical_shd_y", - np.array( - [[1, np.nan, np.nan], [1j * np.sqrt(1 / 2), 0, 1j * np.sqrt(1 / 2)]] + array( + [[1, np.nan, np.nan], [1j * sqrt(1 / 2), 0, 1j * sqrt(1 / 2)]] ), - np.array([0, 1, 0]), + array([0, 1, 0]), SphericalHarmonicsDistributionComplex.mean_direction_numerical, ), ( "numerical_shd_z", - np.array([[1, np.nan, np.nan], [0, 1, 0]]), - np.array([0, 0, 1]), + array([[1, np.nan, np.nan], [0, 1, 0]]), + array([0, 0, 1]), SphericalHarmonicsDistributionComplex.mean_direction_numerical, ), ] @@ -907,12 +920,12 @@ def test_mean_direction(self, _, input_array, expected_output, fun_to_test): def test_from_distribution_via_integral_vmf(self): # Test approximating a VMF - dist = VonMisesFisherDistribution(np.array([-1, -1, 0] / np.sqrt(2)), 1) + dist = VonMisesFisherDistribution(array([-1, -1, 0] / sqrt(2)), 1) shd = SphericalHarmonicsDistributionComplex.from_distribution_via_integral( dist, 3 ) - phi, theta = np.meshgrid( - np.linspace(0, 2 * np.pi, 10), np.linspace(-np.pi / 2, np.pi / 2, 10) + phi, theta = meshgrid( + linspace(0, 2 * np.pi, 10), linspace(-np.pi / 2, np.pi / 2, 10) ) x, y, z = AbstractSphericalDistribution.sph_to_cart(phi.ravel(), theta.ravel()) np.testing.assert_allclose( @@ -934,12 +947,12 @@ def test_from_distribution_via_integral_uniform(self): shd = SphericalHarmonicsDistributionComplex.from_distribution_via_integral( HypersphericalUniformDistribution(2), degree=0 ) - np.testing.assert_allclose(shd.coeff_mat, np.array([[1 / np.sqrt(4 * np.pi)]])) + np.testing.assert_allclose(shd.coeff_mat, array([[1 / sqrt(4 * np.pi)]])) def test_transformation_via_integral_shd(self): # Test approximating a spherical harmonic distribution dist = SphericalHarmonicsDistributionComplex( - np.array([[1, np.nan, np.nan], [0, 1, 0]]) + array([[1, np.nan, np.nan], [0, 1, 0]]) ) shd = SphericalHarmonicsDistributionComplex.from_function_via_integral_cart( @@ -949,8 +962,8 @@ def test_transformation_via_integral_shd(self): def test_convergence(self): no_diffs = 3 - dist = VonMisesFisherDistribution(np.array([0, -1, 0]), 1) - diffs = np.zeros(no_diffs) + dist = VonMisesFisherDistribution(array([0, -1, 0]), 1) + diffs = zeros(no_diffs) for i in range(0, no_diffs): shd = SphericalHarmonicsDistributionComplex.from_function_via_integral_cart( @@ -959,71 +972,71 @@ def test_convergence(self): diffs[i] = shd.total_variation_distance_numerical(dist) # Check if the deviation from true density is decreasing - self.assertTrue(np.all(np.diff(diffs) < 0)) + self.assertTrue(all(np.diff(diffs) < 0)) @parameterized.expand( [ - ("zplus", [[1 / np.sqrt(4 * np.pi), np.nan, np.nan], [0, 1, 0]], [0, 0, 1]), + ("zplus", [[1 / sqrt(4 * np.pi), np.nan, np.nan], [0, 1, 0]], [0, 0, 1]), ( "zminus", - [[1 / np.sqrt(4 * np.pi), np.nan, np.nan], [0, -1, 0]], + [[1 / sqrt(4 * np.pi), np.nan, np.nan], [0, -1, 0]], [0, 0, -1], ), ( "yplus", [ - [1 / np.sqrt(4 * np.pi), np.nan, np.nan], - [1j * np.sqrt(1 / 2), 0, 1j * np.sqrt(1 / 2)], + [1 / sqrt(4 * np.pi), np.nan, np.nan], + [1j * sqrt(1 / 2), 0, 1j * sqrt(1 / 2)], ], [0, 1, 0], ), ( "yminus", [ - [1 / np.sqrt(4 * np.pi), np.nan, np.nan], - [-1j * np.sqrt(1 / 2), 0, -1j * np.sqrt(1 / 2)], + [1 / sqrt(4 * np.pi), np.nan, np.nan], + [-1j * sqrt(1 / 2), 0, -1j * sqrt(1 / 2)], ], [0, -1, 0], ), ( "xplus", [ - [1 / np.sqrt(4 * np.pi), np.nan, np.nan], - [np.sqrt(1 / 2), 0, -np.sqrt(1 / 2)], + [1 / sqrt(4 * np.pi), np.nan, np.nan], + [sqrt(1 / 2), 0, -sqrt(1 / 2)], ], [1, 0, 0], ), ( "xminus", [ - [1 / np.sqrt(4 * np.pi), np.nan, np.nan], - [-np.sqrt(1 / 2), 0, np.sqrt(1 / 2)], + [1 / sqrt(4 * np.pi), np.nan, np.nan], + [-sqrt(1 / 2), 0, sqrt(1 / 2)], ], [-1, 0, 0], ), ( "xyplus", [ - [1 / np.sqrt(4 * np.pi), np.nan, np.nan], + [1 / sqrt(4 * np.pi), np.nan, np.nan], [ - 1j * np.sqrt(1 / 2) + np.sqrt(1 / 2), + 1j * sqrt(1 / 2) + sqrt(1 / 2), 1, - 1j * np.sqrt(1 / 2) - np.sqrt(1 / 2), + 1j * sqrt(1 / 2) - sqrt(1 / 2), ], ], - 1 / np.sqrt(3) * np.array([1, 1, 1]), + 1 / sqrt(3) * array([1, 1, 1]), ), ( "xyminus", [ - [1 / np.sqrt(4 * np.pi), np.nan, np.nan], + [1 / sqrt(4 * np.pi), np.nan, np.nan], [ - -1j * np.sqrt(1 / 2) - np.sqrt(1 / 2), + -1j * sqrt(1 / 2) - sqrt(1 / 2), 0, - -1j * np.sqrt(1 / 2) + np.sqrt(1 / 2), + -1j * sqrt(1 / 2) + sqrt(1 / 2), ], ], - 1 / np.sqrt(2) * np.array([-1, -1, 0]), + 1 / sqrt(2) * array([-1, -1, 0]), ), ] ) diff --git a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py index d436672a..65e7fcbe 100644 --- a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py +++ b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py @@ -1,3 +1,10 @@ +from pyrecest.backend import sqrt +from pyrecest.backend import ones_like +from pyrecest.backend import ones +from pyrecest.backend import array +from pyrecest.backend import allclose +from pyrecest.backend import all +from pyrecest.backend import zeros import unittest import warnings @@ -31,9 +38,9 @@ def testNormalization(self): shd.coeff_mat = unnormalized_coeffs vals_unnormalized = shd.pdf(np.column_stack((x, y, z))) self.assertTrue( - np.allclose( + allclose( np.diff(vals_normalized / vals_unnormalized), - np.zeros((1, x.size - 1)), + zeros((1, x.size - 1)), atol=1e-6, ) ) @@ -47,7 +54,7 @@ def testNormalization(self): [0, 0, 0, np.nan, np.nan], [0, 0, 0, 0, 0], ], - lambda x, _, __: np.ones_like(x) * np.sqrt(1 / (4 * np.pi)), + lambda x, _, __: ones_like(x) * sqrt(1 / (4 * np.pi)), ), ( "l1mneg1", @@ -56,7 +63,7 @@ def testNormalization(self): [1, 0, 0, np.nan, np.nan], [0, 0, 0, 0, 0], ], - lambda _, y, __: np.sqrt(3 / (4 * np.pi)) * y, + lambda _, y, __: sqrt(3 / (4 * np.pi)) * y, ), ( "l1_m0", @@ -65,7 +72,7 @@ def testNormalization(self): [0, 1, 0, np.nan, np.nan], [0, 0, 0, 0, 0], ], - lambda _, __, z: np.sqrt(3 / (4 * np.pi)) * z, + lambda _, __, z: sqrt(3 / (4 * np.pi)) * z, ), ( "l1_m1", @@ -74,7 +81,7 @@ def testNormalization(self): [0, 0, 1, np.nan, np.nan], [0, 0, 0, 0, 0], ], - lambda x, _, __: np.sqrt(3 / (4 * np.pi)) * x, + lambda x, _, __: sqrt(3 / (4 * np.pi)) * x, ), ( "l2_mneg2", @@ -83,7 +90,7 @@ def testNormalization(self): [0, 0, 0, np.nan, np.nan], [1, 0, 0, 0, 0], ], - lambda x, y, __: 1 / 2 * np.sqrt(15 / np.pi) * x * y, + lambda x, y, __: 1 / 2 * sqrt(15 / np.pi) * x * y, ), ( "l2_mneg1", @@ -92,7 +99,7 @@ def testNormalization(self): [0, 0, 0, np.nan, np.nan], [0, 1, 0, 0, 0], ], - lambda _, y, z: 1 / 2 * np.sqrt(15 / np.pi) * y * z, + lambda _, y, z: 1 / 2 * sqrt(15 / np.pi) * y * z, ), ( "l2_m0", @@ -103,7 +110,7 @@ def testNormalization(self): ], lambda x, y, z: 1 / 4 - * np.sqrt(5 / np.pi) + * sqrt(5 / np.pi) * (2 * z**2 - x**2 - y**2), ), ( @@ -113,7 +120,7 @@ def testNormalization(self): [0, 0, 0, np.nan, np.nan], [0, 0, 0, 1, 0], ], - lambda x, _, z: 1 / 2 * np.sqrt(15 / np.pi) * x * z, + lambda x, _, z: 1 / 2 * sqrt(15 / np.pi) * x * z, ), ( "l2_m2", @@ -122,14 +129,14 @@ def testNormalization(self): [0, 0, 0, np.nan, np.nan], [0, 0, 0, 0, 1], ], - lambda x, y, _: 1 / 4 * np.sqrt(15 / np.pi) * (x**2 - y**2), + lambda x, y, _: 1 / 4 * sqrt(15 / np.pi) * (x**2 - y**2), ), ] # jscpd:ignore-end ) def test_basis_function(self, name, coeff_mat, result_func): np.random.seed(10) - shd = SphericalHarmonicsDistributionReal(1 / np.sqrt(4 * np.pi)) - shd.coeff_mat = np.array(coeff_mat) + shd = SphericalHarmonicsDistributionReal(1 / sqrt(4 * np.pi)) + shd.coeff_mat = array(coeff_mat) x, y, z = SphericalHarmonicsDistributionRealTest._gen_naive_grid(10) np.testing.assert_allclose( shd.pdf(np.column_stack((x, y, z))), @@ -148,7 +155,7 @@ def _gen_naive_grid(n_per_dim): [ # jscpd:ignore-start-python ( "l0_m0", - np.array( + array( [ [1, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan], @@ -158,7 +165,7 @@ def _gen_naive_grid(n_per_dim): ), ( "l1_mneg1", - np.array( + array( [ [1, np.nan, np.nan, np.nan, np.nan], [1, 0, 0, np.nan, np.nan], @@ -168,7 +175,7 @@ def _gen_naive_grid(n_per_dim): ), ( "l1_m0", - np.array( + array( [ [1, np.nan, np.nan, np.nan, np.nan], [0, 1, 0, np.nan, np.nan], @@ -178,7 +185,7 @@ def _gen_naive_grid(n_per_dim): ), ( "l1_m1", - np.array( + array( [ [1, np.nan, np.nan, np.nan, np.nan], [0, 0, 1, np.nan, np.nan], @@ -188,7 +195,7 @@ def _gen_naive_grid(n_per_dim): ), ( "l2_mneg2", - np.array( + array( [ [1, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan], @@ -198,7 +205,7 @@ def _gen_naive_grid(n_per_dim): ), ( "l2_mneg1", - np.array( + array( [ [1, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan], @@ -208,7 +215,7 @@ def _gen_naive_grid(n_per_dim): ), ( "l2_m0", - np.array( + array( [ [1, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan], @@ -218,7 +225,7 @@ def _gen_naive_grid(n_per_dim): ), ( "l2_m1", - np.array( + array( [ [1, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan], @@ -228,7 +235,7 @@ def _gen_naive_grid(n_per_dim): ), ( "l2_m2", - np.array( + array( [ [1, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan], @@ -238,7 +245,7 @@ def _gen_naive_grid(n_per_dim): ), ( "l3_mneg3", - np.array( + array( [ [1, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan, np.nan, np.nan], @@ -249,7 +256,7 @@ def _gen_naive_grid(n_per_dim): ), ( "l3_mneg2", - np.array( + array( [ [1, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan, np.nan, np.nan], @@ -260,7 +267,7 @@ def _gen_naive_grid(n_per_dim): ), ( "l3_mneg1", - np.array( + array( [ [1, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan, np.nan, np.nan], @@ -271,7 +278,7 @@ def _gen_naive_grid(n_per_dim): ), ( "l3_m0", - np.array( + array( [ [1, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan, np.nan, np.nan], @@ -282,7 +289,7 @@ def _gen_naive_grid(n_per_dim): ), ( "l3_m1", - np.array( + array( [ [1, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan, np.nan, np.nan], @@ -293,7 +300,7 @@ def _gen_naive_grid(n_per_dim): ), ( "l3_m2", - np.array( + array( [ [1, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan, np.nan, np.nan], @@ -304,7 +311,7 @@ def _gen_naive_grid(n_per_dim): ), ( "l3_m3", - np.array( + array( [ [1, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan], [0, 0, 0, np.nan, np.nan, np.nan, np.nan], diff --git a/pyrecest/tests/distributions/test_toroidal_uniform_distribution.py b/pyrecest/tests/distributions/test_toroidal_uniform_distribution.py index e70fb4bb..5580fac0 100644 --- a/pyrecest/tests/distributions/test_toroidal_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_toroidal_uniform_distribution.py @@ -1,3 +1,9 @@ +from pyrecest.backend import tile +from pyrecest.backend import ones +from pyrecest.backend import array +from pyrecest.backend import allclose +from pyrecest.backend import all +from pyrecest.backend import zeros import unittest import numpy as np @@ -9,28 +15,28 @@ class TestToroidalUniformDistribution(unittest.TestCase): def setUp(self): self.tud = ToroidalUniformDistribution() - self.x = np.tile(np.array([[1, 2, 3, 4, 5, 6]]), (2, 1)) + self.x = tile(array([[1, 2, 3, 4, 5, 6]]), (2, 1)) def test_pdf(self): self.assertTrue( - np.allclose( - self.tud.pdf(self.x), (1 / (2 * np.pi) ** 2) * np.ones(self.x.shape[1]) + allclose( + self.tud.pdf(self.x), (1 / (2 * np.pi) ** 2) * ones(self.x.shape[1]) ) ) def test_shift(self): - tud_shifted = self.tud.shift(np.array([1, 2])) + tud_shifted = self.tud.shift(array([1, 2])) self.assertTrue( - np.allclose( + allclose( tud_shifted.pdf(self.x), - (1 / (2 * np.pi) ** 2) * np.ones(self.x.shape[1]), + (1 / (2 * np.pi) ** 2) * ones(self.x.shape[1]), ) ) def test_trigonometric_moments(self): for k in range(4): self.assertTrue( - np.allclose( + allclose( self.tud.trigonometric_moment(k), self.tud.trigonometric_moment_numerical(k), atol=1e-10, @@ -38,14 +44,14 @@ def test_trigonometric_moments(self): ) if k == 0: self.assertTrue( - np.allclose( - self.tud.trigonometric_moment(k), np.ones(2), rtol=1e-10 + allclose( + self.tud.trigonometric_moment(k), ones(2), rtol=1e-10 ) ) else: self.assertTrue( - np.allclose( - self.tud.trigonometric_moment(k), np.zeros(2), rtol=1e-10 + allclose( + self.tud.trigonometric_moment(k), zeros(2), rtol=1e-10 ) ) @@ -67,8 +73,8 @@ def test_sampling(self): n = 10 s = self.tud.sample(n) self.assertEqual(s.shape, (n, 2)) - self.assertTrue(np.all(s >= 0)) - self.assertTrue(np.all(s < 2 * np.pi)) + self.assertTrue(all(s >= 0)) + self.assertTrue(all(s < 2 * np.pi)) if __name__ == "__main__": diff --git a/pyrecest/tests/distributions/test_toroidal_von_mises_sine_distribution.py b/pyrecest/tests/distributions/test_toroidal_von_mises_sine_distribution.py index 8db041b2..84fe6643 100644 --- a/pyrecest/tests/distributions/test_toroidal_von_mises_sine_distribution.py +++ b/pyrecest/tests/distributions/test_toroidal_von_mises_sine_distribution.py @@ -1,3 +1,8 @@ +from pyrecest.backend import sin +from pyrecest.backend import exp +from pyrecest.backend import cos +from pyrecest.backend import array +from pyrecest.backend import arange import unittest import numpy as np @@ -9,8 +14,8 @@ class ToroidalVMSineDistributionTest(unittest.TestCase): def setUp(self): - self.mu = np.array([1, 2]) - self.kappa = np.array([0.7, 1.4]) + self.mu = array([1, 2]) + self.kappa = array([0.7, 1.4]) self.lambda_ = 0.5 self.tvm = ToroidalVonMisesSineDistribution(self.mu, self.kappa, self.lambda_) @@ -29,32 +34,32 @@ def test_integral(self): def test_trigonometric_moment_numerical(self): np.testing.assert_almost_equal( - self.tvm.trigonometric_moment_numerical(0), np.array([1, 1]), decimal=5 + self.tvm.trigonometric_moment_numerical(0), array([1, 1]), decimal=5 ) # jscpd:ignore-start # pylint: disable=R0801 def _unnormalized_pdf(self, xs): - return np.exp( - self.kappa[0] * np.cos(xs[..., 0] - self.mu[0]) - + self.kappa[1] * np.cos(xs[..., 1] - self.mu[1]) + return exp( + self.kappa[0] * cos(xs[..., 0] - self.mu[0]) + + self.kappa[1] * cos(xs[..., 1] - self.mu[1]) + self.lambda_ - * np.sin(xs[..., 0] - self.mu[0]) - * np.sin(xs[..., 1] - self.mu[1]) + * sin(xs[..., 0] - self.mu[0]) + * sin(xs[..., 1] - self.mu[1]) ) # jscpd:ignore-end @parameterized.expand( [ - (np.array([3, 2]),), - (np.array([1, 4]),), - (np.array([5, 6]),), - (np.array([-3, 11]),), - (np.array([[5, 1], [6, 3]]),), + (array([3, 2]),), + (array([1, 4]),), + (array([5, 6]),), + (array([-3, 11]),), + (array([[5, 1], [6, 3]]),), ( np.column_stack( - (np.arange(0, 2 * np.pi, 0.1), np.arange(1 * np.pi, 3 * np.pi, 0.1)) + (arange(0, 2 * np.pi, 0.1), arange(1 * np.pi, 3 * np.pi, 0.1)) ), ), ] diff --git a/pyrecest/tests/distributions/test_toroidal_wrapped_normal_distribution.py b/pyrecest/tests/distributions/test_toroidal_wrapped_normal_distribution.py index 429f271d..992ba566 100644 --- a/pyrecest/tests/distributions/test_toroidal_wrapped_normal_distribution.py +++ b/pyrecest/tests/distributions/test_toroidal_wrapped_normal_distribution.py @@ -1,3 +1,7 @@ +from pyrecest.backend import mod +from pyrecest.backend import array +from pyrecest.backend import allclose +from pyrecest.backend import all import unittest import numpy as np @@ -8,26 +12,26 @@ class TestToroidalWrappedNormalDistribution(unittest.TestCase): def setUp(self): - self.mu = np.array([1, 2]) - self.C = np.array([[1.3, -0.9], [-0.9, 1.2]]) + self.mu = array([1, 2]) + self.C = array([[1.3, -0.9], [-0.9, 1.2]]) self.twn = ToroidalWrappedNormalDistribution(self.mu, self.C) def test_sanity_check(self): self.assertIsInstance(self.twn, ToroidalWrappedNormalDistribution) - self.assertTrue(np.allclose(self.twn.mu, self.mu)) - self.assertTrue(np.allclose(self.twn.C, self.C)) + self.assertTrue(allclose(self.twn.mu, self.mu)) + self.assertTrue(allclose(self.twn.C, self.C)) def test_integrate(self): self.assertAlmostEqual(self.twn.integrate(), 1, delta=1e-5) self.assertTrue( - np.allclose(self.twn.trigonometric_moment(0), np.array([1, 1]), rtol=1e-5) + allclose(self.twn.trigonometric_moment(0), array([1, 1]), rtol=1e-5) ) def test_sampling(self): n_samples = 5 s = self.twn.sample(n_samples) self.assertEqual(s.shape, (n_samples, 2)) - self.assertTrue(np.allclose(s, np.mod(s, 2 * np.pi))) + self.assertTrue(allclose(s, mod(s, 2 * np.pi))) if __name__ == "__main__": diff --git a/pyrecest/tests/distributions/test_von_mises_distribution.py b/pyrecest/tests/distributions/test_von_mises_distribution.py index 8c297f40..6e672081 100644 --- a/pyrecest/tests/distributions/test_von_mises_distribution.py +++ b/pyrecest/tests/distributions/test_von_mises_distribution.py @@ -1,3 +1,5 @@ +from pyrecest.backend import linspace +from pyrecest.backend import array import unittest import matplotlib @@ -17,10 +19,10 @@ def test_vm_init(self): def test_pdf(self): dist = VonMisesDistribution(2, 1) - xs = np.linspace(1, 7, 7) + xs = linspace(1, 7, 7) np.testing.assert_array_almost_equal( dist.pdf(xs), - np.array( + array( [ 0.215781465110296, 0.341710488623463, diff --git a/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py b/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py index e263033c..e768c10c 100644 --- a/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py +++ b/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py @@ -1,3 +1,8 @@ +from pyrecest.backend import sqrt +from pyrecest.backend import array +from pyrecest.backend import allclose +from pyrecest.backend import all +from pyrecest.backend import empty_like import unittest import numpy as np @@ -7,35 +12,35 @@ HypersphericalDiracDistribution, ) -vectors_to_test_2d = np.array( +vectors_to_test_2d = array( [ [1, 0, 0], [0, 1, 0], [0, 0, 1], - [1, 1, 0] / np.sqrt(2), + [1, 1, 0] / sqrt(2), [1, 1, 2] / np.linalg.norm([1, 1, 2]), - -np.array([1, 1, 2]) / np.linalg.norm([1, 1, 2]), + -array([1, 1, 2]) / np.linalg.norm([1, 1, 2]), ] ) class TestVonMisesFisherDistribution(unittest.TestCase): def setUp(self): - self.mu = np.array([1, 2, 3]) + self.mu = array([1, 2, 3]) self.mu = self.mu / np.linalg.norm(self.mu) self.kappa = 2 self.vmf = VonMisesFisherDistribution(self.mu, self.kappa) - self.other = VonMisesFisherDistribution(np.array([0, 0, 1]), self.kappa / 3) + self.other = VonMisesFisherDistribution(array([0, 0, 1]), self.kappa / 3) def test_vmf_distribution_3d_sanity_check(self): self.assertIsInstance(self.vmf, VonMisesFisherDistribution) - self.assertTrue(np.allclose(self.vmf.mu, self.mu)) + self.assertTrue(allclose(self.vmf.mu, self.mu)) self.assertEqual(self.vmf.kappa, self.kappa) self.assertEqual(self.vmf.dim + 1, len(self.mu)) def test_vmf_distribution_3d_mode(self): self.assertTrue( - np.allclose(self.vmf.mode_numerical(), self.vmf.mode(), atol=1e-5) + allclose(self.vmf.mode_numerical(), self.vmf.mode(), atol=1e-5) ) def test_vmf_distribution_3d_integral(self): @@ -44,10 +49,10 @@ def test_vmf_distribution_3d_integral(self): def test_vmf_distribution_3d_multiplication(self): vmf_mul = self.vmf.multiply(self.other) vmf_mul2 = self.other.multiply(self.vmf) - c = vmf_mul.pdf(np.array([1, 0, 0])) / ( - self.vmf.pdf(np.array([1, 0, 0])) * self.other.pdf(np.array([1, 0, 0])) + c = vmf_mul.pdf(array([1, 0, 0])) / ( + self.vmf.pdf(array([1, 0, 0])) * self.other.pdf(array([1, 0, 0])) ) - x = np.array([0, 1, 0]) + x = array([0, 1, 0]) self.assertAlmostEqual( self.vmf.pdf(x) * self.other.pdf(x) * c, vmf_mul.pdf(x), delta=1e-10 ) @@ -57,7 +62,7 @@ def test_vmf_distribution_3d_multiplication(self): def test_vmf_distribution_3d_convolve(self): vmf_conv = self.vmf.convolve(self.other) - self.assertTrue(np.allclose(vmf_conv.mu, self.vmf.mu, atol=1e-10)) + self.assertTrue(allclose(vmf_conv.mu, self.vmf.mu, atol=1e-10)) d = 3 self.assertAlmostEqual( VonMisesFisherDistribution.a_d(d, vmf_conv.kappa), @@ -67,28 +72,28 @@ def test_vmf_distribution_3d_convolve(self): ) def test_init_2d(self): - mu = np.array([1, 1, 2]) + mu = array([1, 1, 2]) mu = mu / np.linalg.norm(mu) kappa = 10 dist = VonMisesFisherDistribution(mu, kappa) np.testing.assert_array_almost_equal(dist.C, 7.22562325261744e-05) def test_init_3d(self): - mu = np.array([1, 1, 2, -3]) + mu = array([1, 1, 2, -3]) mu = mu / np.linalg.norm(mu) kappa = 2 dist = VonMisesFisherDistribution(mu, kappa) np.testing.assert_array_almost_equal(dist.C, 0.0318492506152322) def test_pdf_2d(self): - mu = np.array([1, 1, 2]) + mu = array([1, 1, 2]) mu = mu / np.linalg.norm(mu) kappa = 10 dist = VonMisesFisherDistribution(mu, kappa) np.testing.assert_array_almost_equal( dist.pdf(vectors_to_test_2d), - np.array( + array( [ 0.00428425301914546, 0.00428425301914546, @@ -101,12 +106,12 @@ def test_pdf_2d(self): ) def test_pdf_3d(self): - mu = np.array([1, 1, 2, -3]) + mu = array([1, 1, 2, -3]) mu = mu / np.linalg.norm(mu) kappa = 2 dist = VonMisesFisherDistribution(mu, kappa) - xs_unnorm = np.array( + xs_unnorm = array( [ [1, 0, 0, 0], [0, 1, 0, 0], @@ -124,7 +129,7 @@ def test_pdf_3d(self): np.testing.assert_array_almost_equal( dist.pdf(xs), - np.array( + array( [ 0.0533786916025838, 0.0533786916025838, @@ -141,9 +146,9 @@ def test_pdf_3d(self): ) def test_mean_direction(self): - mu = 1 / np.sqrt(2) * np.array([1, 1, 0]) + mu = 1 / sqrt(2) * array([1, 1, 0]) vmf = VonMisesFisherDistribution(mu, 1) - self.assertTrue(np.allclose(vmf.mean_direction(), mu, atol=1e-13)) + self.assertTrue(allclose(vmf.mean_direction(), mu, atol=1e-13)) def _test_hellinger_distance_helper( self, dist1, dist2, delta=1e-10, numerical_delta=1e-10 @@ -163,21 +168,21 @@ def _test_hellinger_distance_helper( def test_hellinger_distance_2d(self): # 2D - vmf1 = VonMisesFisherDistribution(np.array([1, 0]), 0.9) - vmf2 = VonMisesFisherDistribution(np.array([0, 1]), 1.7) + vmf1 = VonMisesFisherDistribution(array([1, 0]), 0.9) + vmf2 = VonMisesFisherDistribution(array([0, 1]), 1.7) self._test_hellinger_distance_helper(vmf1, vmf2) def test_hellinger_distance_3d(self): # 3D - vmf1 = VonMisesFisherDistribution(np.array([1, 0, 0]), 0.6) - mu2 = np.array([1, 2, 3]) + vmf1 = VonMisesFisherDistribution(array([1, 0, 0]), 0.6) + mu2 = array([1, 2, 3]) vmf2 = VonMisesFisherDistribution(mu2 / np.linalg.norm(mu2), 2.1) self._test_hellinger_distance_helper(vmf1, vmf2, numerical_delta=1e-6) @parameterized.expand( [ - ("2D_case", np.array([-1, 0, 0]), 1.3), - ("3D_case", np.array([0, 1, 0, 0]), 0.5), + ("2D_case", array([-1, 0, 0]), 1.3), + ("3D_case", array([0, 1, 0, 0]), 0.5), ] ) def test_from_distribution_vmf(self, _, mu, kappa): @@ -189,7 +194,7 @@ def test_from_distribution_vmf(self, _, mu, kappa): def test_from_distribution_dirac(self): dirac_dist = HypersphericalDiracDistribution( - np.array( + array( [[0, 0, 1], [0, 1, 0], [1, 0, 0], [0, 1, 1] / np.linalg.norm([0, 1, 1])] ) ) diff --git a/pyrecest/tests/distributions/test_watson_distribution.py b/pyrecest/tests/distributions/test_watson_distribution.py index 70eaac7c..e27f9dda 100644 --- a/pyrecest/tests/distributions/test_watson_distribution.py +++ b/pyrecest/tests/distributions/test_watson_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import array import unittest import numpy as np @@ -6,14 +7,14 @@ class TestWatsonDistribution(unittest.TestCase): def setUp(self): - self.xs = np.array( + self.xs = array( [[1, 0, 0], [1, 2, 2], [0, 1, 0], [0, 0, 1], [1, 1, 1], [-1, -1, -1]], dtype=float, ) self.xs = self.xs / np.linalg.norm(self.xs, axis=1, keepdims=True) def test_constructor(self): - mu = np.array([1, 2, 3]) + mu = array([1, 2, 3]) mu = mu / np.linalg.norm(mu) kappa = 2 w = WatsonDistribution(mu, kappa) @@ -24,12 +25,12 @@ def test_constructor(self): self.assertEqual(w.input_dim, np.size(mu)) def test_pdf(self): - mu = np.array([1, 2, 3]) + mu = array([1, 2, 3]) mu = mu / np.linalg.norm(mu) kappa = 2 w = WatsonDistribution(mu, kappa) - expected_pdf_values = np.array( + expected_pdf_values = array( [ 0.0388240901641662, 0.229710245437696, @@ -44,14 +45,14 @@ def test_pdf(self): np.testing.assert_almost_equal(pdf_values, expected_pdf_values, decimal=5) def test_integrate(self): - mu = np.array([1, 2, 3]) + mu = array([1, 2, 3]) mu = mu / np.linalg.norm(mu) kappa = 2 w = WatsonDistribution(mu, kappa) self.assertAlmostEqual(w.integrate(), 1, delta=1e-5) def test_to_bingham(self): - mu = np.array([1.0, 0.0, 0.0]) + mu = array([1.0, 0.0, 0.0]) kappa = 2.0 watson_dist = WatsonDistribution(mu, kappa) bingham_dist = watson_dist.to_bingham() diff --git a/pyrecest/tests/distributions/test_wrapped_cauchy_distribution.py b/pyrecest/tests/distributions/test_wrapped_cauchy_distribution.py index b8c72117..3a1164a9 100644 --- a/pyrecest/tests/distributions/test_wrapped_cauchy_distribution.py +++ b/pyrecest/tests/distributions/test_wrapped_cauchy_distribution.py @@ -1,3 +1,5 @@ +from pyrecest.backend import array +from pyrecest.backend import arange import unittest import numpy as np @@ -13,7 +15,7 @@ class WrappedCauchyDistributionTest(unittest.TestCase): def setUp(self): self.mu = 0 self.gamma = 0.5 - self.xs = np.arange(10) + self.xs = arange(10) def test_pdf(self): dist = WrappedCauchyDistribution(self.mu, self.gamma) @@ -27,7 +29,7 @@ def pdf_wrapped(x, mu, gamma, terms=2000): return summation custom_wrapped = CustomCircularDistribution( - lambda xs: np.array([pdf_wrapped(x, self.mu, self.gamma) for x in xs]) + lambda xs: array([pdf_wrapped(x, self.mu, self.gamma) for x in xs]) ) np.testing.assert_allclose( @@ -37,7 +39,7 @@ def pdf_wrapped(x, mu, gamma, terms=2000): def test_cdf(self): dist = WrappedCauchyDistribution(self.mu, self.gamma) np.testing.assert_allclose( - dist.cdf(np.array([1])), dist.integrate(np.array([0, 1])) + dist.cdf(array([1])), dist.integrate(array([0, 1])) ) diff --git a/pyrecest/tests/distributions/test_wrapped_laplace_distribution.py b/pyrecest/tests/distributions/test_wrapped_laplace_distribution.py index f0dde446..5ce70ad3 100644 --- a/pyrecest/tests/distributions/test_wrapped_laplace_distribution.py +++ b/pyrecest/tests/distributions/test_wrapped_laplace_distribution.py @@ -1,3 +1,6 @@ +from pyrecest.backend import linspace +from pyrecest.backend import exp +from pyrecest.backend import arange import unittest import numpy as np @@ -17,7 +20,7 @@ def laplace(x): return ( self.lambda_ / (1 / self.kappa + self.kappa) - * np.exp( + * exp( -( abs(x) * self.lambda_ @@ -27,7 +30,7 @@ def laplace(x): ) def pdftemp(x): - return sum(laplace(z) for z in x + 2 * np.pi * np.arange(-20, 21)) + return sum(laplace(z) for z in x + 2 * np.pi * arange(-20, 21)) for x in [0, 1, 2, 3, 4]: np.testing.assert_allclose(self.wl.pdf(x), pdftemp(x), rtol=1e-10) @@ -51,8 +54,8 @@ def test_angular_moments(self): def test_periodicity(self): np.testing.assert_allclose( - self.wl.pdf(np.linspace(-2 * np.pi, 0, 100)), - self.wl.pdf(np.linspace(0, 2 * np.pi, 100)), + self.wl.pdf(linspace(-2 * np.pi, 0, 100)), + self.wl.pdf(linspace(0, 2 * np.pi, 100)), rtol=1e-10, ) diff --git a/pyrecest/tests/distributions/test_wrapped_normal_distribution.py b/pyrecest/tests/distributions/test_wrapped_normal_distribution.py index ec965f9b..9ab1099d 100644 --- a/pyrecest/tests/distributions/test_wrapped_normal_distribution.py +++ b/pyrecest/tests/distributions/test_wrapped_normal_distribution.py @@ -1,3 +1,13 @@ +from pyrecest.backend import sum +from pyrecest.backend import sqrt +from pyrecest.backend import ones_like +from pyrecest.backend import ones +from pyrecest.backend import exp +from pyrecest.backend import array +from pyrecest.backend import arange +from pyrecest.backend import allclose +from pyrecest.backend import all +from pyrecest.backend import zeros import unittest import numpy as np @@ -16,11 +26,11 @@ def test_pdf_values_are_as_expected(self): """ def approx_with_wrapping(x): - k = np.arange(-20, 21) - total = np.sum( - np.exp(-((x - self.mu + 2 * np.pi * k) ** 2) / (2 * self.sigma**2)) + k = arange(-20, 21) + total = sum( + exp(-((x - self.mu + 2 * np.pi * k) ** 2) / (2 * self.sigma**2)) ) - return 1 / np.sqrt(2 * np.pi) / self.sigma * total + return 1 / sqrt(2 * np.pi) / self.sigma * total test_points = [self.mu, self.mu - 1, self.mu + 2] for point in test_points: @@ -29,11 +39,11 @@ def approx_with_wrapping(x): self.wn.pdf(point), approx_with_wrapping(point), places=10 ) - x = np.arange(0, 7) + x = arange(0, 7) self.assertTrue( - np.allclose( + allclose( self.wn.pdf(x), - np.array([approx_with_wrapping(xi) for xi in x]), + array([approx_with_wrapping(xi) for xi in x]), rtol=1e-10, ) ) @@ -43,9 +53,9 @@ def test_pdf_with_large_sigma_is_uniform(self): Test that the pdf with large sigma is approximately a uniform distribution. """ wn_large_sigma = WrappedNormalDistribution(0, 100) - x = np.arange(0, 7) - fx = np.ones_like(x) / (2 * np.pi) - self.assertTrue(np.allclose(wn_large_sigma.pdf(x), fx, rtol=1e-10)) + x = arange(0, 7) + fx = ones_like(x) / (2 * np.pi) + self.assertTrue(allclose(wn_large_sigma.pdf(x), fx, rtol=1e-10)) if __name__ == "__main__": diff --git a/pyrecest/tests/filters/test_circular_particle_filter.py b/pyrecest/tests/filters/test_circular_particle_filter.py index ba537eed..4260ee00 100644 --- a/pyrecest/tests/filters/test_circular_particle_filter.py +++ b/pyrecest/tests/filters/test_circular_particle_filter.py @@ -1,3 +1,7 @@ +from pyrecest.backend import array +from pyrecest.backend import arange +from pyrecest.backend import allclose +from pyrecest.backend import all import unittest import numpy as np @@ -23,7 +27,7 @@ def setUp(self): self.wn = WrappedNormalDistribution(1.3, 0.8) def test_estimate(self): - self.assertTrue(np.allclose(self.dist.trigonometric_moment(1), 0, atol=1e-10)) + self.assertTrue(allclose(self.dist.trigonometric_moment(1), 0, atol=1e-10)) def test_set_state(self): # sanity check @@ -35,7 +39,7 @@ def test_set_state(self): np.testing.assert_almost_equal(self.dist.w, dist1.w) def test_sampling(self): - positions = np.arange(0, 1.1, 0.1) + positions = arange(0, 1.1, 0.1) dist3 = CircularDiracDistribution(positions) np.random.seed(0) num_samples = 20 @@ -70,7 +74,7 @@ def test_nonlinear_prediction_without_noise(self): def f(x): return x**2 - no_noise = CircularDiracDistribution(np.array([0])) + no_noise = CircularDiracDistribution(array([0])) self.filter.predict_nonlinear(f, no_noise) predicted = self.filter.filter_state self.assertIsInstance(predicted, HypertoroidalDiracDistribution) @@ -101,7 +105,7 @@ def likelihood(z, x): def test_association_likelihood(self): dist = CircularDiracDistribution( - np.array([1, 2, 3]), np.array([1 / 3, 1 / 3, 1 / 3]) + array([1, 2, 3]), array([1 / 3, 1 / 3, 1 / 3]) ) pf = CircularParticleFilter(3) pf.set_state(dist) @@ -115,7 +119,7 @@ def test_association_likelihood(self): pf.association_likelihood(VonMisesDistribution(2, 1)), 1 / (2 * np.pi) ) - self.filter.set_state(CircularDiracDistribution(np.arange(0, 1.1, 0.1))) + self.filter.set_state(CircularDiracDistribution(arange(0, 1.1, 0.1))) def likelihood1(_, x): return x == 0.5 diff --git a/pyrecest/tests/filters/test_euclidean_particle_filter.py b/pyrecest/tests/filters/test_euclidean_particle_filter.py index 8ed7a0c3..a67ad910 100644 --- a/pyrecest/tests/filters/test_euclidean_particle_filter.py +++ b/pyrecest/tests/filters/test_euclidean_particle_filter.py @@ -1,3 +1,8 @@ +from pyrecest.backend import ones +from pyrecest.backend import mean +from pyrecest.backend import array +from pyrecest.backend import zeros_like +from pyrecest.backend import zeros import unittest import numpy as np @@ -8,19 +13,19 @@ class EuclideanParticleFilterTest(unittest.TestCase): def setUp(self): np.random.seed(42) - self.C_prior = np.array([[0.7, 0.4, 0.2], [0.4, 0.6, 0.1], [0.2, 0.1, 1]]) - self.mu = np.array([5, 6, 7]) + self.C_prior = array([[0.7, 0.4, 0.2], [0.4, 0.6, 0.1], [0.2, 0.1, 1]]) + self.mu = array([5, 6, 7]) self.prior = GaussianDistribution(self.mu, self.C_prior) self.sys_noise_default = GaussianDistribution( - np.zeros_like(self.mu), 0.5 * self.C_prior + zeros_like(self.mu), 0.5 * self.C_prior ) self.pf = EuclideanParticleFilter(n_particles=500, dim=3) - self.forced_mean = np.array([1, 2, 3]) + self.forced_mean = array([1, 2, 3]) self.pf.filter_state = self.prior def test_predict_update_cycle_3d(self): for _ in range(50): - self.pf.predict_identity(GaussianDistribution(np.zeros(3), self.C_prior)) + self.pf.predict_identity(GaussianDistribution(zeros(3), self.C_prior)) # jscpd:ignore-start self.assertEqual(self.pf.get_point_estimate().shape, (3,)) for _ in range(3): @@ -35,7 +40,7 @@ def test_predict_update_cycle_3d(self): def test_predict_nonlinear_nonadditive(self): n = 5 samples = np.random.rand(n, 3) - weights = np.ones(n) / n + weights = ones(n) / n def f(x, w): return x + w @@ -44,13 +49,13 @@ def f(x, w): est = self.pf.get_point_estimate() self.assertEqual(self.pf.get_point_estimate().shape, (3,)) np.testing.assert_allclose( - est, self.prior.mu + np.mean(samples, axis=0), atol=0.1 + est, self.prior.mu + mean(samples, axis=0), atol=0.1 ) def test_predict_update_cycle_3d_forced_particle_pos_no_pred(self): - self.pf.filter_state = self.prior.set_mean(np.ones(3) + np.pi / 2) + self.pf.filter_state = self.prior.set_mean(ones(3) + np.pi / 2) - force_first_particle_pos = np.array([1.1, 2, 3]) + force_first_particle_pos = array([1.1, 2, 3]) self.pf.filter_state.d[0, :] = force_first_particle_pos for _ in range(50): # jscpd:ignore-start diff --git a/pyrecest/tests/filters/test_global_nearest_neighbor.py b/pyrecest/tests/filters/test_global_nearest_neighbor.py index f6bab07c..77e94379 100644 --- a/pyrecest/tests/filters/test_global_nearest_neighbor.py +++ b/pyrecest/tests/filters/test_global_nearest_neighbor.py @@ -1,3 +1,9 @@ +from pyrecest.backend import sort +from pyrecest.backend import real +from pyrecest.backend import eye +from pyrecest.backend import array +from pyrecest.backend import allclose +from pyrecest.backend import all, zeros import unittest import numpy as np @@ -14,25 +20,25 @@ class GlobalNearestNeighborTest(unittest.TestCase): def setUp(self): """Initialize test variables before each test is run.""" self.kfs_init = [ - KalmanFilter(GaussianDistribution(np.zeros(4), np.diag([1, 2, 3, 4]))), + KalmanFilter(GaussianDistribution(zeros(4), np.diag([1, 2, 3, 4]))), KalmanFilter( - GaussianDistribution(np.array([1, 2, 3, 4]), np.diag([2, 2, 2, 2])) + GaussianDistribution(array([1, 2, 3, 4]), np.diag([2, 2, 2, 2])) ), KalmanFilter( - GaussianDistribution(-np.array([1, 2, 3, 4]), np.diag([4, 3, 2, 1])) + GaussianDistribution(-array([1, 2, 3, 4]), np.diag([4, 3, 2, 1])) ), ] - self.meas_mat = np.array([[1, 0, 0, 0], [0, 0, 1, 0]]) + self.meas_mat = array([[1, 0, 0, 0], [0, 0, 1, 0]]) self.sys_mat = scipy.linalg.block_diag([[1, 1], [0, 1]], [[1, 1], [0, 1]]) self.all_different_meas_covs = np.dstack( [ np.diag([1, 2]), - np.array([[5, 0.1], [0.1, 3]]), - np.array([[2, -0.5], [-0.5, 0.5]]), + array([[5, 0.1], [0.1, 3]]), + array([[2, -0.5], [-0.5, 0.5]]), ] ) self.all_different_meas_covs_4 = np.dstack( - (self.all_different_meas_covs, np.array([[2, -0.5], [-0.5, 0.5]])) + (self.all_different_meas_covs, array([[2, -0.5], [-0.5, 0.5]])) ) def test_set_state_sets_correct_state(self): @@ -51,21 +57,21 @@ def test_get_state_returns_correct_shape(self): self.assertEqual(tracker.get_point_estimate(True).shape, (12,)) @parameterized.expand( - [("no_inputs", np.zeros(4)), ("with_inputs", np.array([1, -1, 1, -1]))] + [("no_inputs", zeros(4)), ("with_inputs", array([1, -1, 1, -1]))] ) def test_predict_linear(self, name, sys_input): C_matrices = [ - scipy.linalg.block_diag([[3, 2], [2, 2]], [[7, 4], [4, 4]]) + np.eye(4), - scipy.linalg.block_diag([[4, 2], [2, 2]], [[4, 2], [2, 2]]) + np.eye(4), - scipy.linalg.block_diag([[7, 3], [3, 3]], [[3, 1], [1, 1]]) + np.eye(4), + scipy.linalg.block_diag([[3, 2], [2, 2]], [[7, 4], [4, 4]]) + eye(4), + scipy.linalg.block_diag([[4, 2], [2, 2]], [[4, 2], [2, 2]]) + eye(4), + scipy.linalg.block_diag([[7, 3], [3, 3]], [[3, 1], [1, 1]]) + eye(4), ] tracker = GlobalNearestNeighbor() tracker.filter_state = self.kfs_init if name == "no_inputs": - tracker.predict_linear(self.sys_mat, np.eye(4)) + tracker.predict_linear(self.sys_mat, eye(4)) else: - tracker.predict_linear(self.sys_mat, np.eye(4), sys_input) + tracker.predict_linear(self.sys_mat, eye(4), sys_input) for i in range(3): with self.subTest(i=i): @@ -84,25 +90,25 @@ def test_predict_linear_different_mats_and_inputs(self): sys_mats = np.dstack( ( scipy.linalg.block_diag([[1, 1], [0, 1]], [[1, 1], [0, 1]]), - np.eye(4), - np.array([[0, 0, 1, 1], [0, 0, 0, 1], [1, 1, 0, 0], [0, 1, 0, 0]]), + eye(4), + array([[0, 0, 1, 1], [0, 0, 0, 1], [1, 1, 0, 0], [0, 1, 0, 0]]), ) ) sys_noises = np.dstack( - (np.eye(4), np.diag([10, 11, 12, 13]), np.diag([1, 5, 3, 5])) + (eye(4), np.diag([10, 11, 12, 13]), np.diag([1, 5, 3, 5])) ) - sys_inputs = np.array([[-1, 1, -1, 1], [1, 2, 3, 4], -np.array([4, 3, 2, 1])]).T + sys_inputs = array([[-1, 1, -1, 1], [1, 2, 3, 4], -array([4, 3, 2, 1])]).T tracker.predict_linear(sys_mats, sys_noises, sys_inputs) np.testing.assert_array_equal( - tracker.filter_bank[0].filter_state.mu, np.array([-1, 1, -1, 1]) + tracker.filter_bank[0].filter_state.mu, array([-1, 1, -1, 1]) ) np.testing.assert_array_equal( - tracker.filter_bank[1].filter_state.mu, np.array([2, 4, 6, 8]) + tracker.filter_bank[1].filter_state.mu, array([2, 4, 6, 8]) ) np.testing.assert_array_equal( - tracker.filter_bank[2].filter_state.mu, np.array([-11, -7, -5, -3]) + tracker.filter_bank[2].filter_state.mu, array([-11, -7, -5, -3]) ) np.testing.assert_array_equal( tracker.filter_bank[0].filter_state.C, @@ -124,23 +130,23 @@ def test_association_no_clutter(self): # Generate perfect measurements, association should then be # optimal. perfect_meas_ordered = ( - self.meas_mat @ np.array([gaussian.mu for gaussian in all_gaussians]).T + self.meas_mat @ array([gaussian.mu for gaussian in all_gaussians]).T ) association = tracker.find_association( - perfect_meas_ordered, self.meas_mat, np.eye(2) + perfect_meas_ordered, self.meas_mat, eye(2) ) np.testing.assert_array_equal(association, [0, 1, 2]) # Shift them measurements = np.roll(perfect_meas_ordered, 1, axis=1) - association = tracker.find_association(measurements, self.meas_mat, np.eye(2)) + association = tracker.find_association(measurements, self.meas_mat, eye(2)) np.testing.assert_array_equal( measurements[:, association], perfect_meas_ordered ) # Shift them and add a bit of noise measurements = np.roll(perfect_meas_ordered, 1, axis=1) + 0.1 - association = tracker.find_association(measurements, self.meas_mat, np.eye(2)) + association = tracker.find_association(measurements, self.meas_mat, eye(2)) np.testing.assert_array_equal( measurements[:, association], perfect_meas_ordered + 0.1 ) @@ -165,8 +171,8 @@ def test_association_with_clutter(self): perfect_meas_ordered = self.meas_mat @ np.column_stack( [gaussian.mu for gaussian in all_gaussians] ) - measurements = np.column_stack([perfect_meas_ordered, np.array([3, 2])]) - association = tracker.find_association(measurements, self.meas_mat, np.eye(2)) + measurements = np.column_stack([perfect_meas_ordered, array([3, 2])]) + association = tracker.find_association(measurements, self.meas_mat, eye(2)) np.testing.assert_array_equal(association, [0, 1, 2]) # Shift them and add one measurement @@ -174,18 +180,18 @@ def test_association_with_clutter(self): [ perfect_meas_ordered[:, 1], perfect_meas_ordered[:, 2], - np.array([2, 2]), + array([2, 2]), perfect_meas_ordered[:, 0], ] ) - association = tracker.find_association(measurements, self.meas_mat, np.eye(2)) + association = tracker.find_association(measurements, self.meas_mat, eye(2)) np.testing.assert_array_equal( measurements[:, association], perfect_meas_ordered ) # Shift them, add one add one meausurement, and add a bit of noise association = tracker.find_association( - measurements + 0.1, self.meas_mat, np.eye(2) + measurements + 0.1, self.meas_mat, eye(2) ) np.testing.assert_array_equal( measurements[:, association] + 0.1, perfect_meas_ordered + 0.1 @@ -210,67 +216,67 @@ def test_update_with_and_without_clutter(self): [gaussian.mu for gaussian in all_gaussians] ) measurements_no_clut = perfect_meas_ordered - tracker_no_clut.update_linear(measurements_no_clut, self.meas_mat, np.eye(2)) + tracker_no_clut.update_linear(measurements_no_clut, self.meas_mat, eye(2)) self.assertTrue( - np.allclose( + allclose( [dist.mu for dist in tracker_no_clut.filter_state], [dist.mu for dist in all_gaussians], ) ) curr_covs = np.dstack([dist.C for dist in tracker_no_clut.filter_state]) self.assertTrue( - np.all(curr_covs <= np.dstack([dist.C for dist in all_gaussians])) + all(curr_covs <= np.dstack([dist.C for dist in all_gaussians])) ) measurements_clut = np.column_stack( - [measurements_no_clut, np.array([2, 2]).reshape(-1, 1)] + [measurements_no_clut, array([2, 2]).reshape(-1, 1)] ) - tracker_clut.update_linear(measurements_clut, self.meas_mat, np.eye(2)) + tracker_clut.update_linear(measurements_clut, self.meas_mat, eye(2)) self.assertTrue( - np.allclose( + allclose( tracker_clut.get_point_estimate(), tracker_no_clut.get_point_estimate() ) ) measurements_no_clut = perfect_meas_ordered[:, [1, 2, 0]] - tracker_no_clut.update_linear(measurements_no_clut, self.meas_mat, np.eye(2)) + tracker_no_clut.update_linear(measurements_no_clut, self.meas_mat, eye(2)) self.assertTrue( - np.allclose( + allclose( [dist.mu for dist in tracker_no_clut.filter_state], [dist.mu for dist in all_gaussians], ) ) previous_covs = curr_covs curr_covs = np.dstack([dist.C for dist in tracker_no_clut.filter_state]) - self.assertTrue(np.all(curr_covs <= previous_covs)) + self.assertTrue(all(curr_covs <= previous_covs)) measurements_clut = np.column_stack( [ perfect_meas_ordered[:, [1, 2]], - np.array([2, 2]).reshape(-1, 1), + array([2, 2]).reshape(-1, 1), perfect_meas_ordered[:, 0], ] ) - tracker_clut.update_linear(measurements_clut, self.meas_mat, np.eye(2)) + tracker_clut.update_linear(measurements_clut, self.meas_mat, eye(2)) self.assertTrue( - np.allclose( + allclose( tracker_clut.get_point_estimate(), tracker_no_clut.get_point_estimate() ) ) measurements_no_clut += 0.1 - tracker_no_clut.update_linear(measurements_no_clut, self.meas_mat, np.eye(2)) + tracker_no_clut.update_linear(measurements_no_clut, self.meas_mat, eye(2)) curr_means = [dist.mu for dist in tracker_no_clut.filter_state] - self.assertFalse(np.allclose(curr_means, [dist.mu for dist in all_gaussians])) + self.assertFalse(allclose(curr_means, [dist.mu for dist in all_gaussians])) previous_covs = curr_covs curr_covs = np.dstack([dist.C for dist in tracker_no_clut.filter_state]) - self.assertTrue(np.all(curr_covs <= previous_covs)) + self.assertTrue(all(curr_covs <= previous_covs)) measurements_clut += 0.1 - tracker_clut.update_linear(measurements_clut, self.meas_mat, np.eye(2)) + tracker_clut.update_linear(measurements_clut, self.meas_mat, eye(2)) self.assertTrue( - np.allclose( + allclose( tracker_clut.get_point_estimate(), tracker_no_clut.get_point_estimate() ) ) @@ -280,7 +286,7 @@ def test_update_with_and_without_clutter(self): ) previous_means = curr_means self.assertFalse( - np.allclose( + allclose( [dist.mu for dist in tracker_no_clut.filter_state], previous_means ) ) @@ -288,9 +294,9 @@ def test_update_with_and_without_clutter(self): curr_covs = np.dstack([dist.C for dist in tracker_no_clut.filter_state]) for i in range(curr_covs.shape[2]): self.assertTrue( - np.all( - np.sort(np.real(scipy.linalg.eigvals(curr_covs[:, :, i]))) - <= np.sort(np.real(scipy.linalg.eigvals(previous_covs[:, :, i]))) + all( + sort(real(scipy.linalg.eigvals(curr_covs[:, :, i]))) + <= sort(real(scipy.linalg.eigvals(previous_covs[:, :, i]))) ) ) @@ -298,7 +304,7 @@ def test_update_with_and_without_clutter(self): measurements_clut, self.meas_mat, self.all_different_meas_covs_4 ) self.assertTrue( - np.allclose( + allclose( tracker_clut.get_point_estimate(), tracker_no_clut.get_point_estimate() ) ) diff --git a/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py b/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py index cf2a7068..e8ae763c 100644 --- a/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py +++ b/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py @@ -1,3 +1,5 @@ +from pyrecest.backend import array +from pyrecest.backend import zeros import unittest import numpy as np @@ -8,13 +10,13 @@ class HypertoroidalParticleFilterTest(unittest.TestCase): def setUp(self): self.seed = 0 - self.covariance_matrix = np.array( + self.covariance_matrix = array( [[0.7, 0.4, 0.2], [0.4, 0.6, 0.1], [0.2, 0.1, 1]] ) - self.mu = np.array([1, 1, 1]) + np.pi / 2 + self.mu = array([1, 1, 1]) + np.pi / 2 self.hwnd = HypertoroidalWNDistribution(self.mu, self.covariance_matrix) self.hpf = HypertoroidalParticleFilter(500, 3) - self.forced_mean = np.array([1, 2, 3]) + self.forced_mean = array([1, 2, 3]) np.random.seed(self.seed) def test_set_state(self): @@ -22,13 +24,13 @@ def test_set_state(self): def test_predict_identity(self): self.hpf.predict_identity( - HypertoroidalWNDistribution(np.zeros(3), 0.5 * self.covariance_matrix) + HypertoroidalWNDistribution(zeros(3), 0.5 * self.covariance_matrix) ) self.assertEqual(self.hpf.get_point_estimate().shape, (3,)) def test_update_identity(self): self.hpf.update_identity( - HypertoroidalWNDistribution(np.zeros(3), 0.5 * self.covariance_matrix), + HypertoroidalWNDistribution(zeros(3), 0.5 * self.covariance_matrix), self.forced_mean, ) self.assertEqual(self.hpf.get_point_estimate().shape, (3,)) diff --git a/pyrecest/tests/filters/test_kalman_filter.py b/pyrecest/tests/filters/test_kalman_filter.py index 55017d76..c17b4df3 100644 --- a/pyrecest/tests/filters/test_kalman_filter.py +++ b/pyrecest/tests/filters/test_kalman_filter.py @@ -1,3 +1,7 @@ +from pyrecest.backend import eye +from pyrecest.backend import array +from pyrecest.backend import allclose +from pyrecest.backend import all import copy import unittest @@ -8,52 +12,52 @@ class KalmanFilterTest(unittest.TestCase): def test_initialization_mean_cov(self): - filter_custom = KalmanFilter((np.array([1]), np.array([[10000]]))) + filter_custom = KalmanFilter((array([1]), array([[10000]]))) self.assertEqual(filter_custom.get_point_estimate(), [1]) def test_initialization_gauss(self): filter_custom = KalmanFilter( - initial_state=GaussianDistribution(np.array([4]), np.array([[10000]])) + initial_state=GaussianDistribution(array([4]), array([[10000]])) ) self.assertEqual(filter_custom.get_point_estimate(), [4]) def test_update_with_likelihood_1d(self): - kf = KalmanFilter((np.array([0]), np.array([[1]]))) - kf.update_identity(np.array(1), np.array(3)) + kf = KalmanFilter((array([0]), array([[1]]))) + kf.update_identity(array(1), array(3)) self.assertEqual(kf.get_point_estimate(), 1.5) def test_update_with_meas_noise_and_meas_1d(self): - kf = KalmanFilter((np.array([0]), np.array([[1]]))) - kf.update_identity(np.array(1), np.array(4)) + kf = KalmanFilter((array([0]), array([[1]]))) + kf.update_identity(array(1), array(4)) self.assertEqual(kf.filter_state.C, 0.5) self.assertEqual(kf.get_point_estimate(), 2) def test_update_linear_2d(self): - filter_add = KalmanFilter((np.array([0, 1]), np.diag([1, 2]))) + filter_add = KalmanFilter((array([0, 1]), np.diag([1, 2]))) filter_id = copy.deepcopy(filter_add) - gauss = GaussianDistribution(np.array([1, 0]), np.diag([2, 1])) - filter_add.update_linear(gauss.mu, np.eye(2), gauss.C) + gauss = GaussianDistribution(array([1, 0]), np.diag([2, 1])) + filter_add.update_linear(gauss.mu, eye(2), gauss.C) filter_id.update_identity(gauss.C, gauss.mu) self.assertTrue( - np.allclose(filter_add.get_point_estimate(), filter_id.get_point_estimate()) + allclose(filter_add.get_point_estimate(), filter_id.get_point_estimate()) ) self.assertTrue( - np.allclose(filter_add.filter_state.C, filter_id.filter_state.C) + allclose(filter_add.filter_state.C, filter_id.filter_state.C) ) def test_predict_identity_1d(self): - kf = KalmanFilter((np.array([0]), np.array([[1]]))) - kf.predict_identity(np.array([[3]]), np.array([1])) + kf = KalmanFilter((array([0]), array([[1]]))) + kf.predict_identity(array([[3]]), array([1])) self.assertEqual(kf.get_point_estimate(), 1) self.assertEqual(kf.filter_state.C, 4) def test_predict_linear_2d(self): - kf = KalmanFilter((np.array([0, 1]), np.diag([1, 2]))) + kf = KalmanFilter((array([0, 1]), np.diag([1, 2]))) kf.predict_linear(np.diag([1, 2]), np.diag([2, 1])) - self.assertTrue(np.allclose(kf.get_point_estimate(), np.array([0, 2]))) - self.assertTrue(np.allclose(kf.filter_state.C, np.diag([3, 9]))) - kf.predict_linear(np.diag([1, 2]), np.diag([2, 1]), np.array([2, -2])) - self.assertTrue(np.allclose(kf.get_point_estimate(), np.array([2, 2]))) + self.assertTrue(allclose(kf.get_point_estimate(), array([0, 2]))) + self.assertTrue(allclose(kf.filter_state.C, np.diag([3, 9]))) + kf.predict_linear(np.diag([1, 2]), np.diag([2, 1]), array([2, -2])) + self.assertTrue(allclose(kf.get_point_estimate(), array([2, 2]))) if __name__ == "__main__": diff --git a/pyrecest/tests/filters/test_random_matrix_tracker.py b/pyrecest/tests/filters/test_random_matrix_tracker.py index 0831cfcc..40cc30da 100644 --- a/pyrecest/tests/filters/test_random_matrix_tracker.py +++ b/pyrecest/tests/filters/test_random_matrix_tracker.py @@ -1,3 +1,8 @@ +from pyrecest.backend import mean +from pyrecest.backend import eye +from pyrecest.backend import concatenate +from pyrecest.backend import array +from pyrecest.backend import zeros import unittest from unittest.mock import patch @@ -13,10 +18,10 @@ class TestRandomMatrixTracker(unittest.TestCase): def setUp(self): - self.initial_state = np.array([1, 2]) - self.initial_covariance = np.array([[0.1, 0], [0, 0.1]]) - self.initial_extent = np.array([[1, 0.1], [0.1, 1]]) - self.measurement_noise = np.array([[0.2, 0], [0, 0.2]]) + self.initial_state = array([1, 2]) + self.initial_covariance = array([[0.1, 0], [0, 0.1]]) + self.initial_extent = array([[1, 0.1], [0.1, 1]]) + self.measurement_noise = array([[0.2, 0], [0, 0.2]]) self.tracker = RandomMatrixTracker( self.initial_state, self.initial_covariance, self.initial_extent @@ -28,8 +33,8 @@ def test_initialization(self): np.testing.assert_array_equal(self.tracker.extent, self.initial_extent) def test_get_point_estimate(self): - expected = np.concatenate( - [self.initial_state, np.array(self.initial_extent).flatten()] + expected = concatenate( + [self.initial_state, array(self.initial_extent).flatten()] ) np.testing.assert_array_equal(self.tracker.get_point_estimate(), expected) @@ -45,16 +50,16 @@ def test_get_point_estimate_extent(self): def test_predict(self): dt = 0.1 - Cw = np.array([[0.05, 0.0], [0.0, 0.05]]) + Cw = array([[0.05, 0.0], [0.0, 0.05]]) tau = 1.0 - system_matrix = np.eye(2) # 2-D random walk + system_matrix = eye(2) # 2-D random walk # Call the predict method self.tracker.predict(dt, Cw, tau, system_matrix) # Check if state and state covariance are updated correctly - expected_state = np.array([1.0, 2.0]) + expected_state = array([1.0, 2.0]) expected_covariance = self.initial_covariance + Cw expected_extent = self.initial_extent @@ -72,20 +77,20 @@ def test_predict(self): [ ( "smaller", - np.array([[0.1, 0], [0, 0.1], [-0.1, 0], [0, -0.1]]), + array([[0.1, 0], [0, 0.1], [-0.1, 0], [0, -0.1]]), "The extent should now be smaller since the measurements are closely spaced", ), ( "larger", - np.array([[1, 0], [0, 1], [-1, 0], [0, -1]]), + array([[1, 0], [0, 1], [-1, 0], [0, -1]]), "The extent should now be larger since the measurements are spaced more widely", ), ] ) def test_update(self, name, offset, _): - ys = np.array([self.initial_state + offset_row for offset_row in offset]).T - Cv = np.array([[0.1, 0.0], [0.0, 0.1]]) - H = np.eye(np.size(self.initial_state)) + ys = array([self.initial_state + offset_row for offset_row in offset]).T + Cv = array([[0.1, 0.0], [0.0, 0.1]]) + H = eye(np.size(self.initial_state)) # Call the update method self.tracker.update(ys, H, Cv) @@ -95,7 +100,7 @@ def test_update(self, name, offset, _): GaussianDistribution(self.initial_state, self.initial_covariance) ) kf.update_linear( - np.mean(ys, axis=1), H, (self.initial_extent + Cv) / ys.shape[1] + mean(ys, axis=1), H, (self.initial_extent + Cv) / ys.shape[1] ) np.testing.assert_array_almost_equal( @@ -108,11 +113,11 @@ def test_update(self, name, offset, _): # Check if extent has changed as expected if name == "smaller": np.testing.assert_array_less( - np.zeros(2), np.linalg.eig(self.initial_extent - self.tracker.extent)[0] + zeros(2), np.linalg.eig(self.initial_extent - self.tracker.extent)[0] ) elif name == "larger": np.testing.assert_array_less( - np.zeros(2), np.linalg.eig(self.tracker.extent - self.initial_extent)[0] + zeros(2), np.linalg.eig(self.tracker.extent - self.initial_extent)[0] ) else: raise ValueError(f"Invalid test name: {name}") @@ -120,10 +125,10 @@ def test_update(self, name, offset, _): @patch("matplotlib.pyplot.show") def test_draw_extent_3d(self, mock_show): self.tracker = RandomMatrixTracker( - np.zeros(3), - np.eye(3), + zeros(3), + eye(3), np.diag([1, 2, 3]), - kinematic_state_to_pos_matrix=np.eye(3), + kinematic_state_to_pos_matrix=eye(3), ) self.tracker.plot_point_estimate() diff --git a/pyrecest/tests/filters/test_toroidal_particle_filter.py b/pyrecest/tests/filters/test_toroidal_particle_filter.py index 264675b8..c5ed5a66 100644 --- a/pyrecest/tests/filters/test_toroidal_particle_filter.py +++ b/pyrecest/tests/filters/test_toroidal_particle_filter.py @@ -1,3 +1,6 @@ +from pyrecest.backend import array +from pyrecest.backend import allclose +from pyrecest.backend import all import unittest import numpy as np @@ -13,24 +16,24 @@ class ToroidalParticleFilterTest(unittest.TestCase): def test_toroidal_particle_filter(self): np.random.seed(0) - C = np.array([[0.7, 0.4], [0.4, 0.6]]) - mu = np.array([1, 1]) + np.pi / 2 + C = array([[0.7, 0.4], [0.4, 0.6]]) + mu = array([1, 1]) + np.pi / 2 hwnd = ToroidalWrappedNormalDistribution(mu, C) tpf = ToroidalParticleFilter(200) tpf.set_state(hwnd) - forced_mean = np.array([1, 1]) + forced_mean = array([1, 1]) for _ in range(50): tpf.predict_identity( - HypertoroidalWrappedNormalDistribution(np.array([0, 0]), C) + HypertoroidalWrappedNormalDistribution(array([0, 0]), C) ) for _ in range(3): tpf.update_identity( - HypertoroidalWrappedNormalDistribution(np.array([0, 0]), 0.5 * C), + HypertoroidalWrappedNormalDistribution(array([0, 0]), 0.5 * C), forced_mean, ) - self.assertTrue(np.allclose(tpf.get_point_estimate(), forced_mean, atol=0.1)) + self.assertTrue(allclose(tpf.get_point_estimate(), forced_mean, atol=0.1)) if __name__ == "__main__": diff --git a/pyrecest/tests/filters/test_toroidal_wrapped_normal_filter.py b/pyrecest/tests/filters/test_toroidal_wrapped_normal_filter.py index 8d4f4cfe..5c843d0e 100644 --- a/pyrecest/tests/filters/test_toroidal_wrapped_normal_filter.py +++ b/pyrecest/tests/filters/test_toroidal_wrapped_normal_filter.py @@ -1,3 +1,5 @@ +from pyrecest.backend import mod +from pyrecest.backend import array import unittest import numpy as np @@ -10,8 +12,8 @@ class ToroidalWrappedNormalFilterTest(unittest.TestCase): def setUp(self): """Initial setup for each test.""" - self.mu = np.array([5, 2.5]) - self.C = np.array([[1.3, 1.4], [1.4, 2]]) + self.mu = array([5, 2.5]) + self.C = array([[1.3, 1.4], [1.4, 2]]) self.twn = ToroidalWrappedNormalDistribution(self.mu, self.C) def test_sanity_check(self): @@ -31,6 +33,6 @@ def test_predict_identity(self): dist_result = curr_filter.filter_state self.assertIsInstance(dist_result, ToroidalWrappedNormalDistribution) np.testing.assert_array_almost_equal( - dist_result.mu, np.mod(self.twn.mu + self.twn.mu, 2 * np.pi) + dist_result.mu, mod(self.twn.mu + self.twn.mu, 2 * np.pi) ) np.testing.assert_array_almost_equal(dist_result.C, self.twn.C + self.twn.C) diff --git a/pyrecest/tests/filters/test_von_mises_fisher_filter.py b/pyrecest/tests/filters/test_von_mises_fisher_filter.py index 207d96a3..21fe2667 100644 --- a/pyrecest/tests/filters/test_von_mises_fisher_filter.py +++ b/pyrecest/tests/filters/test_von_mises_fisher_filter.py @@ -1,3 +1,8 @@ +from pyrecest.backend import sin +from pyrecest.backend import cos +from pyrecest.backend import array +from pyrecest.backend import allclose +from pyrecest.backend import all import unittest import numpy as np @@ -10,7 +15,7 @@ def setUp(self): """Initial setup for each test.""" self.filter = VonMisesFisherFilter() self.phi = 0.3 - self.mu = np.array([np.cos(self.phi), np.sin(self.phi)]) + self.mu = array([cos(self.phi), sin(self.phi)]) self.kappa = 0.7 self.vmf = VonMisesFisherDistribution(self.mu, self.kappa) @@ -19,24 +24,24 @@ def test_VMFFilter2d(self): self.filter.filter_state = self.vmf vmf_result = self.filter.filter_state self.assertEqual(type(vmf_result), VonMisesFisherDistribution) - self.assertTrue(np.allclose(self.vmf.mu, vmf_result.mu)) + self.assertTrue(allclose(self.vmf.mu, vmf_result.mu)) self.assertEqual(self.vmf.kappa, vmf_result.kappa) def test_prediction_identity(self): """Test prediction identity.""" self.filter.state = self.vmf - noise_distribution = VonMisesFisherDistribution(np.array([0, 1]), 0.9) + noise_distribution = VonMisesFisherDistribution(array([0, 1]), 0.9) self.filter.predict_identity(noise_distribution) # Add other assertions and logic here def test_update_identity(self): """Test update identity.""" self.filter.filter_state = self.vmf - noise_distribution = VonMisesFisherDistribution(np.array([0, 1]), 0.9) + noise_distribution = VonMisesFisherDistribution(array([0, 1]), 0.9) self.filter.update_identity(noise_distribution, self.vmf.mu) vmf_updated_identity = self.filter.filter_state self.assertEqual(type(vmf_updated_identity), VonMisesFisherDistribution) - self.assertTrue(np.allclose(self.vmf.mu, vmf_updated_identity.mu, rtol=1e-10)) + self.assertTrue(allclose(self.vmf.mu, vmf_updated_identity.mu, rtol=1e-10)) self.assertGreaterEqual(vmf_updated_identity.kappa, self.vmf.kappa) diff --git a/pyrecest/tests/test_euclidean_sampler.py b/pyrecest/tests/test_euclidean_sampler.py index c3c879d4..5f09a433 100644 --- a/pyrecest/tests/test_euclidean_sampler.py +++ b/pyrecest/tests/test_euclidean_sampler.py @@ -1,3 +1,9 @@ +from pyrecest.backend import std +from pyrecest.backend import ones +from pyrecest.backend import mean +from pyrecest.backend import allclose +from pyrecest.backend import all +from pyrecest.backend import zeros import unittest import numpy as np @@ -18,12 +24,12 @@ def test_sample_stochastic(self): def test_gaussian_properties(self): # Check that the mean is close to 0 for each dimension - means = np.mean(self.samples, axis=0) - self.assertTrue(np.allclose(means, np.zeros(self.dim), atol=0.1)) + means = mean(self.samples, axis=0) + self.assertTrue(allclose(means, zeros(self.dim), atol=0.1)) # Check that the standard deviation is close to 1 for each dimension - std_devs = np.std(self.samples, axis=0) - self.assertTrue(np.allclose(std_devs, np.ones(self.dim), atol=0.1)) + std_devs = std(self.samples, axis=0) + self.assertTrue(allclose(std_devs, ones(self.dim), atol=0.1)) if __name__ == "__main__": diff --git a/pyrecest/tests/test_evaluation_basic.py b/pyrecest/tests/test_evaluation_basic.py index 79761343..b5e1ab69 100644 --- a/pyrecest/tests/test_evaluation_basic.py +++ b/pyrecest/tests/test_evaluation_basic.py @@ -1,3 +1,13 @@ +from pyrecest.backend import sqrt +from pyrecest.backend import shape +from pyrecest.backend import ones +from pyrecest.backend import ndim +from pyrecest.backend import eye +from pyrecest.backend import array +from pyrecest.backend import any +from pyrecest.backend import all +from pyrecest.backend import empty +from pyrecest.backend import zeros import os import tempfile import unittest @@ -73,7 +83,7 @@ def test_plot_results(self): @parameterized.expand( [ - (np.zeros(2),), + (zeros(2),), (None,), ] ) @@ -81,18 +91,18 @@ def test_generate_gt_R2(self, x0): groundtruth = generate_groundtruth(self.simulation_param, x0) # Test if groundtruth and its content is as expected - self.assertEqual(np.shape(groundtruth), (self.n_timesteps_default,)) + self.assertEqual(shape(groundtruth), (self.n_timesteps_default,)) self.assertEqual( - np.shape(groundtruth[0]), (self.simulation_param["initial_prior"].dim,) + shape(groundtruth[0]), (self.simulation_param["initial_prior"].dim,) ) @parameterized.expand([(1,), (3,)]) def test_generate_measurements(self, n_meas): - self.simulation_param["n_meas_at_individual_time_step"] = n_meas * np.ones( + self.simulation_param["n_meas_at_individual_time_step"] = n_meas * ones( self.n_timesteps_default, dtype=int ) measurements = generate_measurements( - np.zeros( + zeros( (self.n_timesteps_default, self.simulation_param["initial_prior"].dim) ), self.simulation_param, @@ -121,23 +131,23 @@ def test_generate_measurements_eot(self, eot_sampling_style: str): state_dim = 2 measurements = generate_measurements( - np.zeros((self.n_timesteps_default, state_dim)), + zeros((self.n_timesteps_default, state_dim)), simulation_param, ) self.assertEqual(np.size(measurements), self.n_timesteps_default) - n_meas_at_individual_time_step = np.array( + n_meas_at_individual_time_step = array( [meas_at_timestep.shape[0] for meas_at_timestep in measurements] ) # If one measurement at every timestep, then the number is apparently not stochastic - self.assertFalse(np.all(n_meas_at_individual_time_step == 1)) - state_dim_at_individual_time_step = np.array( + self.assertFalse(all(n_meas_at_individual_time_step == 1)) + state_dim_at_individual_time_step = array( [meas_at_timestep.shape[-1] for meas_at_timestep in measurements] ) has_state_dim_all = state_dim_at_individual_time_step == state_dim has_dim_zero_all = state_dim_at_individual_time_step == 0 self.assertTrue( - np.all( + all( [ state_dim or dim_zero for state_dim, dim_zero in zip(has_state_dim_all, has_dim_zero_all) @@ -150,10 +160,10 @@ def test_generate_simulated_scenario(self): groundtruths, measurements = generate_simulated_scenarios(self.simulation_param) self.assertEqual( - np.shape(groundtruths), (self.n_runs_default, self.n_timesteps_default) + shape(groundtruths), (self.n_runs_default, self.n_timesteps_default) ) self.assertEqual( - np.shape(measurements), (self.n_runs_default, self.n_timesteps_default) + shape(measurements), (self.n_runs_default, self.n_timesteps_default) ) return groundtruths, measurements @@ -165,14 +175,14 @@ def dummy_distance_function(x, y): return np.linalg.norm(x - y) # Initialize the outer array with object type - groundtruths = np.empty((3, 4), dtype=object) + groundtruths = empty((3, 4), dtype=object) # Populate each entry with (2,) arrays for i in range(3): for j in range(4): - groundtruths[i, j] = np.array([i + j, i - j]) + groundtruths[i, j] = array([i + j, i - j]) - results = np.array([groundtruths[:, -1], groundtruths[:, -1] + 1]) + results = array([groundtruths[:, -1], groundtruths[:, -1] + 1]) # Run the function and get the deviations matrix all_deviations = determine_all_deviations( @@ -192,18 +202,18 @@ def dummy_distance_function(x, y): [0, 0, 0], ) np.testing.assert_allclose( - # Should be np.sqrt(2) away from groundtruths + # Should be sqrt(2) away from groundtruths all_deviations[1], - [np.sqrt(2), np.sqrt(2), np.sqrt(2)], + [sqrt(2), sqrt(2), sqrt(2)], ) def test_configure_kf(self): filterParam = {"name": "kf", "parameter": None} scenarioParam = { - "initial_prior": GaussianDistribution(np.array([0, 0]), np.eye(2)), + "initial_prior": GaussianDistribution(array([0, 0]), eye(2)), "inputs": None, "manifold_type": "Euclidean", - "meas_noise": GaussianDistribution(np.array([0, 0]), np.eye(2)), + "meas_noise": GaussianDistribution(array([0, 0]), eye(2)), } ( @@ -221,7 +231,7 @@ def test_configure_pf(self): filter_config = {"name": "pf", "parameter": 100} scenario_config = { "initial_prior": HypertoroidalWrappedNormalDistribution( - np.array([0, 0]), np.eye(2) + array([0, 0]), eye(2) ), "inputs": None, "manifold": "hypertorus", @@ -259,9 +269,9 @@ def test_perform_predict_update_cycles(self): ) = perform_predict_update_cycles( scenario_param, {"name": "kf", "parameter": None}, - np.zeros((self.n_timesteps_default, 2)), + zeros((self.n_timesteps_default, 2)), generate_measurements( - np.zeros((self.n_timesteps_default, 2)), scenario_param + zeros((self.n_timesteps_default, 2)), scenario_param ), ) @@ -279,7 +289,7 @@ def test_get_distance_function(self): callable(distance_function), f"Expected distanceFunction to be callable, but got {type(distance_function)}", ) - self.assertEqual(distance_function(np.array([0, 0]), np.array([0, 0])), 0) + self.assertEqual(distance_function(array([0, 0]), array([0, 0])), 0) def test_get_mean_calc(self): extract_mean = get_extract_mean("hypertorus") @@ -352,23 +362,23 @@ def _validate_eval_data( self.assertIsInstance(evaluation_config, dict) - self.assertEqual(np.shape(last_filter_states), (n_configs, self.n_runs_default)) - self.assertTrue(np.all(last_filter_states != None)) # noqa + self.assertEqual(shape(last_filter_states), (n_configs, self.n_runs_default)) + self.assertTrue(all(last_filter_states != None)) # noqa - self.assertEqual(np.shape(runtimes), (n_configs, self.n_runs_default)) + self.assertEqual(shape(runtimes), (n_configs, self.n_runs_default)) print(runtimes) - self.assertTrue(np.all(runtimes > 0)) + self.assertTrue(all(runtimes >= 0)) - self.assertEqual(np.shape(run_failed), (n_configs, self.n_runs_default)) - self.assertTrue(not np.any(run_failed)) + self.assertEqual(shape(run_failed), (n_configs, self.n_runs_default)) + self.assertTrue(not any(run_failed)) - self.assertEqual(np.ndim(groundtruths), 2) + self.assertEqual(ndim(groundtruths), 2) self.assertIsInstance(groundtruths[0, 0], np.ndarray) - self.assertIn(np.ndim(groundtruths[0, 0]), (1, 2)) + self.assertIn(ndim(groundtruths[0, 0]), (1, 2)) - self.assertEqual(np.ndim(measurements), 2) + self.assertEqual(ndim(measurements), 2) self.assertIsInstance(measurements[0, 0], np.ndarray) - self.assertIn(np.ndim(measurements[0, 0]), (1, 2)) + self.assertIn(ndim(measurements[0, 0]), (1, 2)) def test_evaluate_for_simulation_config_R2_random_walk(self): filters_configs_input = [ @@ -419,9 +429,9 @@ def test_evaluate_for_file_R2_random_walk(self): scenario_config = { "manifold": "Euclidean", - "initial_prior": GaussianDistribution(np.zeros(2), 0.5 * np.eye(2)), - "meas_noise": GaussianDistribution(np.zeros(2), 0.5 * np.eye(2)), - "sys_noise": GaussianDistribution(np.zeros(2), 0.5 * np.eye(2)), + "initial_prior": GaussianDistribution(zeros(2), 0.5 * eye(2)), + "meas_noise": GaussianDistribution(zeros(2), 0.5 * eye(2)), + "sys_noise": GaussianDistribution(zeros(2), 0.5 * eye(2)), } ( diff --git a/pyrecest/tests/test_hyperspherical_sampler.py b/pyrecest/tests/test_hyperspherical_sampler.py index a0145837..b5e759cd 100644 --- a/pyrecest/tests/test_hyperspherical_sampler.py +++ b/pyrecest/tests/test_hyperspherical_sampler.py @@ -1,3 +1,6 @@ +from pyrecest.backend import prod +from pyrecest.backend import allclose +from pyrecest.backend import all import unittest import numpy as np @@ -102,7 +105,7 @@ def test_fibonacci_hopf_sampler(self): grid_density_parameter = [12, 4] grid, _ = sampler.get_grid(grid_density_parameter) - expected_points = np.prod(grid_density_parameter) + expected_points = prod(grid_density_parameter) self.assertEqual( grid.shape[0], expected_points, @@ -131,7 +134,7 @@ def test_conversion(self): ) # Check if the original quaternions are close to the recovered quaternions. - self.assertTrue(np.allclose(unit_vectors, recovered_quaternions, atol=1e-8)) + self.assertTrue(allclose(unit_vectors, recovered_quaternions, atol=1e-8)) if __name__ == "__main__": diff --git a/pyrecest/tests/test_hypertoroidal_sampler.py b/pyrecest/tests/test_hypertoroidal_sampler.py index a068509d..84acfd8e 100644 --- a/pyrecest/tests/test_hypertoroidal_sampler.py +++ b/pyrecest/tests/test_hypertoroidal_sampler.py @@ -1,3 +1,5 @@ +from pyrecest.backend import std +from pyrecest.backend import all import unittest import numpy as np @@ -16,8 +18,8 @@ def test_sample_stochastic(self): self.assertEqual(samples.shape[0], n_samples) # Check that all samples are within the range [0, 2*pi) - self.assertTrue(np.all(samples >= 0)) - self.assertTrue(np.all(samples < 2 * np.pi)) + self.assertTrue(all(samples >= 0)) + self.assertTrue(all(samples < 2 * np.pi)) def test_get_grid(self): grid_density_parameter = 100 @@ -27,12 +29,12 @@ def test_get_grid(self): self.assertEqual(grid_points.shape[0], grid_density_parameter) # Check that all grid points are within the range [0, 2*pi) - self.assertTrue(np.all(grid_points >= 0)) - self.assertTrue(np.all(grid_points < 2 * np.pi)) + self.assertTrue(all(grid_points >= 0)) + self.assertTrue(all(grid_points < 2 * np.pi)) # Check that the grid points are equidistant diff = np.diff(grid_points) - self.assertAlmostEqual(np.std(diff), 0, places=5) + self.assertAlmostEqual(std(diff), 0, places=5) if __name__ == "__main__": diff --git a/pyrecest/tests/test_metrics.py b/pyrecest/tests/test_metrics.py index 24d19caf..0c9c9127 100644 --- a/pyrecest/tests/test_metrics.py +++ b/pyrecest/tests/test_metrics.py @@ -1,3 +1,5 @@ +from pyrecest.backend import repeat +from pyrecest.backend import array import unittest import numpy as np @@ -6,8 +8,8 @@ class TestANEES(unittest.TestCase): def setUp(self): - self.groundtruths = np.array([[1.5, 2.5], [2.5, 3.5], [4.5, 5.5]]) - self.uncertainties = np.array( + self.groundtruths = array([[1.5, 2.5], [2.5, 3.5], [4.5, 5.5]]) + self.uncertainties = array( [[[1, 0.5], [0.5, 2]], [[1, 0], [0, 1]], [[0.5, 0], [0, 1.5]]] ) self.num_samples = 10000 @@ -23,9 +25,9 @@ def test_ANEES_is_close_to_one(self): ) samples.extend(samples_for_i) - samples = np.array(samples) - repeated_groundtruths = np.repeat(self.groundtruths, self.num_samples, axis=0) - repeated_uncertainties = np.repeat(self.uncertainties, self.num_samples, axis=0) + samples = array(samples) + repeated_groundtruths = repeat(self.groundtruths, self.num_samples, axis=0) + repeated_uncertainties = repeat(self.uncertainties, self.num_samples, axis=0) computed_ANEES = anees(samples, repeated_uncertainties, repeated_groundtruths) diff --git a/pyrecest/utils/metrics.py b/pyrecest/utils/metrics.py index 8c2f391b..5dacdea3 100644 --- a/pyrecest/utils/metrics.py +++ b/pyrecest/utils/metrics.py @@ -1,3 +1,5 @@ +from pyrecest.backend import mean +from pyrecest.backend import zeros import numpy as np @@ -8,10 +10,10 @@ def anees(estimates, uncertainties, groundtruths): assert uncertainties.shape == (n, dim, dim) assert groundtruths.shape == (n, dim) - NEES = np.zeros(n) + NEES = zeros(n) for i in range(n): error = estimates[i] - groundtruths[i] NEES[i] = error.T @ np.linalg.solve(uncertainties[i], error) - return np.mean(NEES) + return mean(NEES) diff --git a/pyrecest/utils/plotting.py b/pyrecest/utils/plotting.py index cebe2c33..711c1966 100644 --- a/pyrecest/utils/plotting.py +++ b/pyrecest/utils/plotting.py @@ -1,3 +1,11 @@ +from pyrecest.backend import sqrt +from pyrecest.backend import sin +from pyrecest.backend import reshape +from pyrecest.backend import outer +from pyrecest.backend import ones +from pyrecest.backend import linspace +from pyrecest.backend import cos +from pyrecest.backend import array import matplotlib.pyplot as plt import numpy as np @@ -12,8 +20,8 @@ def plot_ellipsoid(center, shape_matrix, scaling_factor=1, color="blue"): def plot_ellipsoid_2d(center, shape_matrix, scaling_factor=1, color="blue"): - xs = np.linspace(0, 2 * np.pi, 100) - ps = scaling_factor * shape_matrix @ np.column_stack((np.cos(xs), np.sin(xs))) + xs = linspace(0, 2 * np.pi, 100) + ps = scaling_factor * shape_matrix @ np.column_stack((cos(xs), sin(xs))) plt.plot(ps[0] + center[0], ps[1] + center[1], color=color) plt.show() @@ -21,19 +29,19 @@ def plot_ellipsoid_2d(center, shape_matrix, scaling_factor=1, color="blue"): def plot_ellipsoid_3d(center, shape_matrix, scaling_factor=1, color="blue"): fig = plt.figure() ax = fig.add_subplot(111, projection="3d") - u = np.linspace(0, 2 * np.pi, 100) - v = np.linspace(0, np.pi, 100) - x = np.outer(np.cos(u), np.sin(v)) - y = np.outer(np.sin(u), np.sin(v)) - z = np.outer(np.ones(np.size(u)), np.cos(v)) + u = linspace(0, 2 * np.pi, 100) + v = linspace(0, np.pi, 100) + x = outer(cos(u), sin(v)) + y = outer(sin(u), sin(v)) + z = outer(ones(np.size(u)), cos(v)) V, D = np.linalg.eig(shape_matrix) - all_coords = V @ np.sqrt(D) @ np.array( + all_coords = V @ sqrt(D) @ array( [x.ravel(), y.ravel(), z.ravel()] ) + center.reshape(-1, 1) - x = np.reshape(all_coords[0], x.shape) - y = np.reshape(all_coords[1], y.shape) - z = np.reshape(all_coords[2], z.shape) + x = reshape(all_coords[0], x.shape) + y = reshape(all_coords[1], y.shape) + z = reshape(all_coords[2], z.shape) ax.plot_surface( scaling_factor * x, diff --git a/requirements-dev.txt b/requirements-dev.txt index 81fbb419..13540459 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,31 +1,36 @@ astropy==5.3.4 ; python_version >= "3.10" and python_version < "3.13" autopep8==2.0.4 ; python_version >= "3.10" and python_version < "3.13" -beartype==0.16.2 ; python_version >= "3.10" and python_version < "3.13" +beartype==0.16.3 ; python_version >= "3.10" and python_version < "3.13" certifi==2023.7.22 ; python_version >= "3.10" and python_version < "3.13" charset-normalizer==3.3.0 ; python_version >= "3.10" and python_version < "3.13" colorama==0.4.6 ; python_version >= "3.10" and python_version < "3.13" and (sys_platform == "win32" or platform_system == "Windows") contourpy==1.1.1 ; python_version >= "3.10" and python_version < "3.13" cycler==0.12.1 ; python_version >= "3.10" and python_version < "3.13" exceptiongroup==1.1.3 ; python_version >= "3.10" and python_version < "3.11" +filelock==3.12.4 ; python_version >= "3.10" and python_version < "3.13" filterpy==1.4.5 ; python_version >= "3.10" and python_version < "3.13" fonttools==4.43.1 ; python_version >= "3.10" and python_version < "3.13" +fsspec==2023.9.2 ; python_version >= "3.10" and python_version < "3.13" healpy==1.16.6 ; python_version >= "3.10" and python_version < "3.13" idna==3.4 ; python_version >= "3.10" and python_version < "3.13" iniconfig==2.0.0 ; python_version >= "3.10" and python_version < "3.13" +jinja2==3.1.2 ; python_version >= "3.10" and python_version < "3.13" kiwisolver==1.4.5 ; python_version >= "3.10" and python_version < "3.13" +markupsafe==2.1.3 ; python_version >= "3.10" and python_version < "3.13" matplotlib==3.8.0 ; python_version >= "3.10" and python_version < "3.13" mpmath==1.3.0 ; python_version >= "3.10" and python_version < "3.13" +networkx==3.1 ; python_version >= "3.10" and python_version < "3.13" numpy-quaternion==2022.4.3 ; python_version >= "3.10" and python_version < "3.13" -numpy==1.26.0 ; python_version >= "3.10" and python_version < "3.13" +numpy==1.26.1 ; python_version >= "3.10" and python_version < "3.13" packaging==23.2 ; python_version >= "3.10" and python_version < "3.13" pandas==2.1.1 ; python_version >= "3.10" and python_version < "3.13" parameterized==0.9.0 ; python_version >= "3.10" and python_version < "3.13" -pillow==10.0.1 ; python_version >= "3.10" and python_version < "3.13" +pillow==10.1.0 ; python_version >= "3.10" and python_version < "3.13" platformdirs==3.11.0 ; python_version >= "3.10" and python_version < "3.13" pluggy==1.3.0 ; python_version >= "3.10" and python_version < "3.13" pooch==1.7.0 ; python_version >= "3.10" and python_version < "3.13" pycodestyle==2.11.1 ; python_version >= "3.10" and python_version < "3.13" -pyerfa==2.0.0.3 ; python_version >= "3.10" and python_version < "3.13" +pyerfa==2.0.1 ; python_version >= "3.10" and python_version < "3.13" pyparsing==3.1.1 ; python_version >= "3.10" and python_version < "3.13" pyshtools==4.10.4 ; python_version >= "3.10" and python_version < "3.13" pytest==7.4.2 ; python_version >= "3.10" and python_version < "3.13" @@ -38,7 +43,9 @@ setuptools-scm==8.0.4 ; python_version >= "3.10" and python_version < "3.13" setuptools==68.2.2 ; python_version >= "3.10" and python_version < "3.13" shapely==2.0.2 ; python_version >= "3.10" and python_version < "3.13" six==1.16.0 ; python_version >= "3.10" and python_version < "3.13" +sympy==1.12 ; python_version >= "3.10" and python_version < "3.13" tomli==2.0.1 ; python_version >= "3.10" and python_version < "3.11" +torch==2.1.0 ; python_version >= "3.10" and python_version < "3.13" tqdm==4.66.1 ; python_version >= "3.10" and python_version < "3.13" typing-extensions==4.8.0 ; python_version >= "3.10" and python_version < "3.13" tzdata==2023.3 ; python_version >= "3.10" and python_version < "3.13" diff --git a/requirements.txt b/requirements.txt index 3ebcac17..6fea30d8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ astropy==5.3.4 ; python_version >= "3.10" and python_version < "3.13" -beartype==0.16.2 ; python_version >= "3.10" and python_version < "3.13" +beartype==0.16.3 ; python_version >= "3.10" and python_version < "3.13" certifi==2023.7.22 ; python_version >= "3.10" and python_version < "3.13" charset-normalizer==3.3.0 ; python_version >= "3.10" and python_version < "3.13" colorama==0.4.6 ; python_version >= "3.10" and python_version < "3.13" and platform_system == "Windows" @@ -12,13 +12,13 @@ kiwisolver==1.4.5 ; python_version >= "3.10" and python_version < "3.13" matplotlib==3.8.0 ; python_version >= "3.10" and python_version < "3.13" mpmath==1.3.0 ; python_version >= "3.10" and python_version < "3.13" numpy-quaternion==2022.4.3 ; python_version >= "3.10" and python_version < "3.13" -numpy==1.26.0 ; python_version >= "3.10" and python_version < "3.13" +numpy==1.26.1 ; python_version >= "3.10" and python_version < "3.13" packaging==23.2 ; python_version >= "3.10" and python_version < "3.13" pandas==2.1.1 ; python_version >= "3.10" and python_version < "3.13" -pillow==10.0.1 ; python_version >= "3.10" and python_version < "3.13" +pillow==10.1.0 ; python_version >= "3.10" and python_version < "3.13" platformdirs==3.11.0 ; python_version >= "3.10" and python_version < "3.13" pooch==1.7.0 ; python_version >= "3.10" and python_version < "3.13" -pyerfa==2.0.0.3 ; python_version >= "3.10" and python_version < "3.13" +pyerfa==2.0.1 ; python_version >= "3.10" and python_version < "3.13" pyparsing==3.1.1 ; python_version >= "3.10" and python_version < "3.13" pyshtools==4.10.4 ; python_version >= "3.10" and python_version < "3.13" python-dateutil==2.8.2 ; python_version >= "3.10" and python_version < "3.13" From ede7e3861d86e8febd19e81effa85fef7ec54b78 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 17 Oct 2023 08:04:03 +0100 Subject: [PATCH 003/232] Trying around --- .github/workflows/tests.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index b1e774c6..ed78d76b 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -35,7 +35,9 @@ jobs: - name: List files and check Python and package versions run: | ls -al + python -c "import torch; print(torch.version.cuda)" pip3 install --upgrade --force-reinstall torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu + python -c "import torch; print(torch.version.cuda)" python -c 'import sys; print(sys.version_info[:])' python -m pip freeze From dab30dd491330ec355fd84f225ef98ca9a424c6b Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 17 Oct 2023 08:07:45 +0100 Subject: [PATCH 004/232] Update tests.yml --- .github/workflows/tests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index ed78d76b..7ce9d86b 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -34,6 +34,7 @@ jobs: - name: List files and check Python and package versions run: | + poetry env use python ls -al python -c "import torch; print(torch.version.cuda)" pip3 install --upgrade --force-reinstall torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu From 64a9f9c421898c7d9fda7c600381f6b0e16ebb5c Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 17 Oct 2023 08:16:02 +0100 Subject: [PATCH 005/232] Update tests.yml --- .github/workflows/tests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 7ce9d86b..bd227161 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -27,6 +27,7 @@ jobs: - name: Install dependencies run: | + poetry env use python export CUDA_VISIBLE_DEVICES="" python -m pip install --upgrade pip python -m pip install poetry From a6952d29e949974b6dee1bab90dee11228306031 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 17 Oct 2023 08:17:46 +0100 Subject: [PATCH 006/232] Update tests.yml --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index bd227161..38ff9002 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -27,10 +27,10 @@ jobs: - name: Install dependencies run: | - poetry env use python export CUDA_VISIBLE_DEVICES="" python -m pip install --upgrade pip python -m pip install poetry + poetry env use python poetry install --extras healpy_support --extras pytorch_support - name: List files and check Python and package versions From e63f940888fd10e430714d47d0b6c4c643e347ba Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 17 Oct 2023 08:25:20 +0100 Subject: [PATCH 007/232] Update tests.yml --- .github/workflows/tests.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 38ff9002..9787628a 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -37,11 +37,11 @@ jobs: run: | poetry env use python ls -al - python -c "import torch; print(torch.version.cuda)" - pip3 install --upgrade --force-reinstall torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu - python -c "import torch; print(torch.version.cuda)" - python -c 'import sys; print(sys.version_info[:])' - python -m pip freeze + poetry run python -c "import torch; print(torch.version.cuda)" + poetry run python -m pip3 install --upgrade --force-reinstall torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu + poetry run python -c "import torch; print(torch.version.cuda)" + poetry run python -c 'import sys; print(sys.version_info[:])' + poetry run python -m pip freeze - name: Run tests with numpy backend run: | From e0dcffa60341f3cf51f574cc770992760676075f Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 17 Oct 2023 08:50:56 +0100 Subject: [PATCH 008/232] Update tests.yml --- .github/workflows/tests.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 9787628a..b96aa737 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -36,8 +36,7 @@ jobs: - name: List files and check Python and package versions run: | poetry env use python - ls -al - poetry run python -c "import torch; print(torch.version.cuda)" + #poetry run python -c "import torch; print(torch.version.cuda)" poetry run python -m pip3 install --upgrade --force-reinstall torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu poetry run python -c "import torch; print(torch.version.cuda)" poetry run python -c 'import sys; print(sys.version_info[:])' From fdd4e3cdab4de1bef22309dd8aad640a6803d1f5 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 17 Oct 2023 08:52:58 +0100 Subject: [PATCH 009/232] Update tests.yml --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index b96aa737..47fd1368 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -37,7 +37,7 @@ jobs: run: | poetry env use python #poetry run python -c "import torch; print(torch.version.cuda)" - poetry run python -m pip3 install --upgrade --force-reinstall torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu + poetry run python -m pip install --upgrade --force-reinstall torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu poetry run python -c "import torch; print(torch.version.cuda)" poetry run python -c 'import sys; print(sys.version_info[:])' poetry run python -m pip freeze From d2460775337a062f2f2f12b5876432d8f0e4235e Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 17 Oct 2023 15:21:41 +0100 Subject: [PATCH 010/232] Need to use typing.Union for pytorch --- .../abstract_manifold_specific_distribution.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pyrecest/distributions/abstract_manifold_specific_distribution.py b/pyrecest/distributions/abstract_manifold_specific_distribution.py index 6016399b..1586b307 100644 --- a/pyrecest/distributions/abstract_manifold_specific_distribution.py +++ b/pyrecest/distributions/abstract_manifold_specific_distribution.py @@ -2,6 +2,7 @@ from pyrecest.backend import int64 from pyrecest.backend import int32 from pyrecest.backend import empty +from typing import Union import numbers from abc import ABC, abstractmethod from collections.abc import Callable @@ -63,18 +64,17 @@ def set_mode(self, _): """ raise NotImplementedError("set_mode is not implemented for this distribution") - @beartype - def sample(self, n: int | int32 | int64) -> np.ndarray: + # Need to use Union instead of | to support torch.dtype + def sample(self, n: Union[int, int32, int64]) -> np.ndarray: """Obtain n samples from the distribution.""" return self.sample_metropolis_hastings(n) # jscpd:ignore-start - @beartype def sample_metropolis_hastings( self, - n: int | int32 | int64, - burn_in: int | int32 | int64 = 10, - skipping: int | int32 | int64 = 5, + n: Union[int, int32, int64], + burn_in: Union[int, int32, int64] = 10, + skipping: Union[int, int32, int64] = 5, proposal: Callable | None = None, start_point: np.number | numbers.Real | np.ndarray | None = None, ) -> np.ndarray: From 4f7edded9c33b2e8829e045828a3f8779e9ef3e1 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 17 Oct 2023 19:31:12 +0100 Subject: [PATCH 011/232] Typing fixes --- poetry.lock | 6 ++--- pyrecest/_backend/__init__.py | 5 ++-- pyrecest/_backend/_backend_config.py | 2 +- pyrecest/_backend/_common.py | 2 +- pyrecest/_backend/_dtype_utils.py | 2 +- pyrecest/_backend/_shared_numpy/__init__.py | 2 +- pyrecest/_backend/_shared_numpy/_common.py | 2 +- pyrecest/_backend/_shared_numpy/_dispatch.py | 2 +- pyrecest/_backend/_shared_numpy/linalg.py | 2 +- pyrecest/_backend/_shared_numpy/random.py | 2 +- pyrecest/_backend/autograd/__init__.py | 2 +- pyrecest/_backend/autograd/_common.py | 2 +- pyrecest/_backend/autograd/autodiff.py | 2 +- pyrecest/_backend/autograd/linalg.py | 2 +- pyrecest/_backend/autograd/random.py | 2 +- pyrecest/_backend/numpy/__init__.py | 2 +- pyrecest/_backend/numpy/_common.py | 2 +- pyrecest/_backend/numpy/autodiff.py | 2 +- pyrecest/_backend/numpy/linalg.py | 2 +- pyrecest/_backend/numpy/random.py | 2 +- pyrecest/_backend/pytorch/__init__.py | 2 +- pyrecest/_backend/pytorch/_common.py | 2 +- pyrecest/_backend/pytorch/_dtype.py | 2 +- pyrecest/_backend/pytorch/autodiff.py | 2 +- pyrecest/_backend/pytorch/linalg.py | 2 +- pyrecest/_backend/pytorch/random.py | 2 +- pyrecest/distributions/__init__.py | 2 +- .../abstract_bounded_domain_distribution.py | 2 +- ...stract_bounded_nonperiodic_distribution.py | 2 +- .../abstract_custom_distribution.py | 6 +---- ...bstract_custom_nonperiodic_distribution.py | 2 +- .../abstract_dirac_distribution.py | 11 +++------ .../abstract_disk_distribution.py | 2 +- .../abstract_distribution_type.py | 2 +- .../abstract_ellipsoidal_ball_distribution.py | 4 +--- ...abstract_manifold_specific_distribution.py | 5 +--- pyrecest/distributions/abstract_mixture.py | 8 +++---- .../abstract_nonperiodic_distribution.py | 2 +- .../abstract_orthogonal_basis_distribution.py | 3 +-- .../abstract_periodic_distribution.py | 7 +++--- .../abstract_se3_distribution.py | 5 ++-- .../abstract_uniform_distribution.py | 3 +-- .../abstract_cart_prod_distribution.py | 2 +- ...stom_lin_bounded_cart_prod_distribution.py | 4 +--- .../abstract_hypercylindrical_distribution.py | 6 ++--- ...ract_lin_bounded_cart_prod_distribution.py | 6 ++--- ...t_lin_hemisphere_cart_prod_distribution.py | 2 +- ..._hyperhemisphere_cart_prod_distribution.py | 2 +- ..._lin_hypersphere_cart_prod_distribution.py | 2 +- ...persphere_subset_cart_prod_distribution.py | 2 +- ...act_lin_periodic_cart_prod_distribution.py | 2 +- .../cart_prod_stacked_distribution.py | 2 +- .../custom_hypercylindrical_distribution.py | 2 +- .../hypercylindrical_dirac_distribution.py | 5 ++-- ...in_bounded_cart_prod_dirac_distribution.py | 2 +- ...ypersphere_cart_prod_dirac_distribution.py | 2 +- ...n_hypersphere_subset_dirac_distribution.py | 5 ++-- ...n_periodic_cart_prod_dirac_distribution.py | 2 +- .../partially_wrapped_normal_distribution.py | 8 +++---- .../circle/abstract_circular_distribution.py | 5 +--- .../circle/circular_dirac_distribution.py | 3 +-- .../circle/circular_fourier_distribution.py | 11 +++------ .../distributions/circle/circular_mixture.py | 3 +-- .../circle/circular_uniform_distribution.py | 2 +- .../circle/custom_circular_distribution.py | 5 +--- .../circle/von_mises_distribution.py | 7 +----- .../circle/wrapped_cauchy_distribution.py | 2 +- .../circle/wrapped_laplace_distribution.py | 2 +- .../circle/wrapped_normal_distribution.py | 15 ++++-------- .../abstract_conditional_distribution.py | 2 +- .../custom_hyperrectangular_distribution.py | 4 +--- .../disk_uniform_distribution.py | 2 +- .../ellipsoidal_ball_uniform_distribution.py | 7 +++--- .../abstract_hemispherical_distribution.py | 2 +- ...bstract_hyperhemispherical_distribution.py | 24 +++++++------------ ...t_hypersphere_subset_dirac_distribution.py | 2 +- ...bstract_hypersphere_subset_distribution.py | 23 ++++++------------ ...hypersphere_subset_uniform_distribution.py | 3 +-- .../abstract_hyperspherical_distribution.py | 18 ++++++-------- .../abstract_sphere_subset_distribution.py | 8 +------ .../abstract_spherical_distribution.py | 2 +- ...stract_spherical_harmonics_distribution.py | 2 +- .../bingham_distribution.py | 2 +- .../custom_hemispherical_distribution.py | 4 +--- .../custom_hyperhemispherical_distribution.py | 8 +++---- .../custom_hyperspherical_distribution.py | 2 +- .../hemispherical_uniform_distribution.py | 2 +- .../hyperhemispherical_dirac_distribution.py | 2 +- ...hyperhemispherical_uniform_distribution.py | 6 ++--- .../hyperhemispherical_watson_distribution.py | 11 +++------ .../hyperspherical_dirac_distribution.py | 2 +- .../hyperspherical_mixture.py | 3 +-- .../hyperspherical_uniform_distribution.py | 10 ++++---- ...pherical_harmonics_distribution_complex.py | 2 +- .../spherical_harmonics_distribution_real.py | 2 +- .../von_mises_fisher_distribution.py | 17 ++++--------- .../hypersphere_subset/watson_distribution.py | 5 ++-- .../abstract_hypertoroidal_distribution.py | 22 +++++++---------- .../abstract_toroidal_distribution.py | 7 +++--- .../custom_hypertoroidal_distribution.py | 2 +- .../custom_toroidal_distribution.py | 2 +- .../hypertoroidal_dirac_distribution.py | 13 ++++------ .../hypertorus/hypertoroidal_mixture.py | 6 ++--- .../hypertoroidal_uniform_distribution.py | 7 +++--- ...pertoroidal_wrapped_normal_distribution.py | 5 ++-- .../hypertorus/toroidal_dirac_distribution.py | 2 +- .../hypertorus/toroidal_mixture.py | 2 +- .../toroidal_uniform_distribution.py | 2 +- .../toroidal_von_mises_sine_distribution.py | 2 +- .../toroidal_wrapped_normal_distribution.py | 2 +- .../abstract_hyperrectangular_distribution.py | 2 +- .../abstract_linear_distribution.py | 9 +++---- .../nonperiodic/custom_linear_distribution.py | 2 +- .../nonperiodic/gaussian_distribution.py | 3 +-- .../nonperiodic/gaussian_mixture.py | 4 +--- .../hyperrectangular_uniform_distribution.py | 2 +- .../nonperiodic/linear_dirac_distribution.py | 2 +- .../nonperiodic/linear_mixture.py | 3 +-- .../se3_cart_prod_stacked_distribution.py | 2 +- .../distributions/se3_dirac_distribution.py | 2 +- pyrecest/evaluation/__init__.py | 2 +- pyrecest/evaluation/check_and_fix_config.py | 2 +- pyrecest/evaluation/configure_for_filter.py | 2 +- .../evaluation/determine_all_deviations.py | 3 +-- pyrecest/evaluation/eot_shape_database.py | 2 +- pyrecest/evaluation/evaluate_for_file.py | 2 +- .../evaluate_for_simulation_config.py | 3 +-- pyrecest/evaluation/evaluate_for_variables.py | 2 +- pyrecest/evaluation/generate_groundtruth.py | 2 +- pyrecest/evaluation/generate_measurements.py | 3 +-- .../generate_simulated_scenarios.py | 2 +- pyrecest/evaluation/get_axis_label.py | 2 +- pyrecest/evaluation/get_distance_function.py | 2 +- pyrecest/evaluation/get_extract_mean.py | 2 +- .../evaluation/group_results_by_filter.py | 2 +- .../evaluation/iterate_configs_and_runs.py | 2 +- .../perform_predict_update_cycles.py | 2 +- pyrecest/evaluation/plot_results.py | 3 +-- pyrecest/evaluation/simulation_database.py | 3 +-- .../evaluation/summarize_filter_results.py | 2 +- pyrecest/filters/__init__.py | 2 +- pyrecest/filters/abstract_circular_filter.py | 2 +- pyrecest/filters/abstract_euclidean_filter.py | 2 +- .../abstract_extended_object_tracker.py | 2 +- pyrecest/filters/abstract_filter.py | 2 +- pyrecest/filters/abstract_filter_type.py | 2 +- .../abstract_hypercylindrical_filter.py | 2 +- .../abstract_hyperhemispherical_filter.py | 2 +- .../abstract_hypersphere_subset_filter.py | 2 +- .../filters/abstract_hyperspherical_filter.py | 2 +- .../filters/abstract_hypertoroidal_filter.py | 2 +- .../filters/abstract_lin_bounded_filter.py | 2 +- .../filters/abstract_lin_periodic_filter.py | 2 +- .../abstract_manifold_specific_filter.py | 2 +- .../filters/abstract_multitarget_tracker.py | 2 +- .../abstract_nearest_neighbor_tracker.py | 2 +- pyrecest/filters/abstract_particle_filter.py | 5 +--- pyrecest/filters/abstract_se2_filter.py | 2 +- pyrecest/filters/abstract_toroidal_filter.py | 2 +- .../filters/abstract_tracker_with_logging.py | 2 +- pyrecest/filters/circular_particle_filter.py | 5 ++-- pyrecest/filters/euclidean_particle_filter.py | 8 +++---- pyrecest/filters/global_nearest_neighbor.py | 2 +- .../filters/hypertoroidal_particle_filter.py | 11 ++++----- pyrecest/filters/kalman_filter.py | 9 +------ .../filters/lin_bounded_particle_filter.py | 2 +- .../filters/lin_periodic_particle_filter.py | 2 +- pyrecest/filters/random_matrix_tracker.py | 2 +- pyrecest/filters/toroidal_particle_filter.py | 6 ++--- .../filters/toroidal_wrapped_normal_filter.py | 2 +- pyrecest/filters/von_mises_filter.py | 5 +--- pyrecest/filters/von_mises_fisher_filter.py | 2 +- pyrecest/filters/wrapped_normal_filter.py | 2 +- pyrecest/sampling/__init__.py | 2 +- pyrecest/sampling/abstract_sampler.py | 2 +- pyrecest/sampling/euclidean_sampler.py | 2 +- pyrecest/sampling/hyperspherical_sampler.py | 12 +--------- pyrecest/sampling/hypertoroidal_sampler.py | 4 +--- .../test_abstract_circular_distribution.py | 2 +- ..._abstract_hypercylindrical_distribution.py | 2 +- ...bstract_hyperhemispherical_distribution.py | 2 +- ...bstract_hypersphere_subset_distribution.py | 2 +- ...st_abstract_hyperspherical_distribution.py | 2 +- ...est_abstract_hypertoroidal_distribution.py | 2 +- .../test_abstract_linear_distribution.py | 2 +- .../distributions/test_abstract_mixture.py | 2 +- .../test_bingham_distribution.py | 2 +- .../test_circular_fourier_distribution.py | 2 +- .../test_circular_uniform_distribution.py | 2 +- .../test_custom_hemispherical_distribution.py | 2 +- ...st_custom_hypercylindrical_distribution.py | 2 +- ...st_custom_hyperrectangular_distribution.py | 2 +- ...test_custom_hyperspherical_distribution.py | 2 +- .../test_custom_linear_distribution.py | 2 +- .../test_disk_uniform_distribution.py | 2 +- ...t_ellipsoidal_ball_uniform_distribution.py | 2 +- .../test_gaussian_distribution.py | 2 +- ...test_hemispherical_uniform_distribution.py | 2 +- ...est_hypercylindrical_dirac_distribution.py | 2 +- ...hyperhemispherical_uniform_distribution.py | 2 +- .../test_hyperspherical_dirac_distribution.py | 2 +- .../test_hyperspherical_mixture.py | 2 +- ...est_hyperspherical_uniform_distribution.py | 2 +- .../test_hypertoroidal_dirac_distribution.py | 2 +- ...pertoroidal_wrapped_normal_distribution.py | 2 +- .../test_linear_dirac_distribution.py | 2 +- .../distributions/test_linear_mixture.py | 2 +- ...t_partially_wrapped_normal_distribution.py | 2 +- .../test_se3_dirac_distribution.py | 2 +- .../test_sphere_subset_distribution.py | 2 +- ...pherical_harmonics_distribution_complex.py | 2 +- ...t_spherical_harmonics_distribution_real.py | 2 +- .../test_toroidal_uniform_distribution.py | 2 +- ...st_toroidal_von_mises_sine_distribution.py | 2 +- ...st_toroidal_wrapped_normal_distribution.py | 2 +- .../test_von_mises_distribution.py | 2 +- .../test_von_mises_fisher_distribution.py | 2 +- .../distributions/test_watson_distribution.py | 2 +- .../test_wrapped_cauchy_distribution.py | 2 +- .../test_wrapped_laplace_distribution.py | 2 +- .../test_wrapped_normal_distribution.py | 2 +- .../filters/test_circular_particle_filter.py | 2 +- .../filters/test_euclidean_particle_filter.py | 2 +- .../filters/test_global_nearest_neighbor.py | 2 +- .../test_hypertoroidal_particle_filter.py | 2 +- pyrecest/tests/filters/test_kalman_filter.py | 2 +- .../filters/test_random_matrix_tracker.py | 2 +- .../filters/test_toroidal_particle_filter.py | 2 +- .../test_toroidal_wrapped_normal_filter.py | 2 +- .../tests/filters/test_von_mises_filter.py | 2 +- .../filters/test_von_mises_fisher_filter.py | 2 +- .../filters/test_wrapped_normal_filter.py | 2 +- pyrecest/tests/test_eot_shape_database.py | 2 +- pyrecest/tests/test_euclidean_sampler.py | 2 +- pyrecest/tests/test_evaluation_basic.py | 2 +- pyrecest/tests/test_hyperspherical_sampler.py | 2 +- pyrecest/tests/test_hypertoroidal_sampler.py | 2 +- pyrecest/tests/test_metrics.py | 2 +- pyrecest/utils/metrics.py | 2 +- pyrecest/utils/plotting.py | 2 +- requirements-dev.txt | 2 +- requirements.txt | 2 +- 242 files changed, 340 insertions(+), 474 deletions(-) diff --git a/poetry.lock b/poetry.lock index cb246bec..b096e0ac 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1558,13 +1558,13 @@ files = [ [[package]] name = "urllib3" -version = "2.0.6" +version = "2.0.7" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.7" files = [ - {file = "urllib3-2.0.6-py3-none-any.whl", hash = "sha256:7a7c7003b000adf9e7ca2a377c9688bbc54ed41b985789ed576570342a375cd2"}, - {file = "urllib3-2.0.6.tar.gz", hash = "sha256:b19e1a85d206b56d7df1d5e683df4a7725252a964e3993648dd0fb5a1c157564"}, + {file = "urllib3-2.0.7-py3-none-any.whl", hash = "sha256:fdb6d215c776278489906c2f8916e6e7d4f5a9b602ccbcfdf7f016fc8da0596e"}, + {file = "urllib3-2.0.7.tar.gz", hash = "sha256:c97dfde1f7bd43a71c8d2a58e369e9b2bf692d1334ea9f9cae55add7d0dd0f84"}, ] [package.extras] diff --git a/pyrecest/_backend/__init__.py b/pyrecest/_backend/__init__.py index 84a255a0..3147df87 100644 --- a/pyrecest/_backend/__init__.py +++ b/pyrecest/_backend/__init__.py @@ -13,7 +13,8 @@ def get_backend_name(): - return os.environ.get("PYRECEST_BACKEND", "numpy") + #return os.environ.get("PYRECEST_BACKEND", "numpy") + return os.environ.get("PYRECEST_BACKEND", "pytorch") BACKEND_NAME = get_backend_name() @@ -291,4 +292,4 @@ def load_module(self, fullname): return module -sys.meta_path.append(BackendImporter("pyrecest.backend")) +sys.meta_path.append(BackendImporter("pyrecest.backend")) \ No newline at end of file diff --git a/pyrecest/_backend/_backend_config.py b/pyrecest/_backend/_backend_config.py index 7ec4b5f1..e94659ae 100644 --- a/pyrecest/_backend/_backend_config.py +++ b/pyrecest/_backend/_backend_config.py @@ -6,4 +6,4 @@ DEFAULT_DTYPE = None -DEFAULT_COMPLEX_DTYPE = None +DEFAULT_COMPLEX_DTYPE = None \ No newline at end of file diff --git a/pyrecest/_backend/_common.py b/pyrecest/_backend/_common.py index c9cb1c8c..6144c6f7 100644 --- a/pyrecest/_backend/_common.py +++ b/pyrecest/_backend/_common.py @@ -4,4 +4,4 @@ def comb(n, k): - return _math.factorial(n) // _math.factorial(k) // _math.factorial(n - k) + return _math.factorial(n) // _math.factorial(k) // _math.factorial(n - k) \ No newline at end of file diff --git a/pyrecest/_backend/_dtype_utils.py b/pyrecest/_backend/_dtype_utils.py index 884c990e..806ab336 100644 --- a/pyrecest/_backend/_dtype_utils.py +++ b/pyrecest/_backend/_dtype_utils.py @@ -415,4 +415,4 @@ def _wrapped(x1, x2, *args, **kwargs): if target is None: return _decorator - return _decorator(target) + return _decorator(target) \ No newline at end of file diff --git a/pyrecest/_backend/_shared_numpy/__init__.py b/pyrecest/_backend/_shared_numpy/__init__.py index ff3ac99b..14f2199b 100644 --- a/pyrecest/_backend/_shared_numpy/__init__.py +++ b/pyrecest/_backend/_shared_numpy/__init__.py @@ -419,4 +419,4 @@ def scatter_add(input, dim, index, src): val = float(val._value) input[j, i] += float(val) return input - raise NotImplementedError + raise NotImplementedError \ No newline at end of file diff --git a/pyrecest/_backend/_shared_numpy/_common.py b/pyrecest/_backend/_shared_numpy/_common.py index 172fe318..8c007a81 100644 --- a/pyrecest/_backend/_shared_numpy/_common.py +++ b/pyrecest/_backend/_shared_numpy/_common.py @@ -114,4 +114,4 @@ def _is_iterable(x): return True if isinstance(x, _np.ndarray): return x.ndim > 0 - return False + return False \ No newline at end of file diff --git a/pyrecest/_backend/_shared_numpy/_dispatch.py b/pyrecest/_backend/_shared_numpy/_dispatch.py index 4ad650f6..734dc69c 100644 --- a/pyrecest/_backend/_shared_numpy/_dispatch.py +++ b/pyrecest/_backend/_shared_numpy/_dispatch.py @@ -9,4 +9,4 @@ import numpy import scipy - from ..numpy import _common + from ..numpy import _common \ No newline at end of file diff --git a/pyrecest/_backend/_shared_numpy/linalg.py b/pyrecest/_backend/_shared_numpy/linalg.py index 6e1284c7..df1621dd 100644 --- a/pyrecest/_backend/_shared_numpy/linalg.py +++ b/pyrecest/_backend/_shared_numpy/linalg.py @@ -102,4 +102,4 @@ def fractional_matrix_power(A, t): if A.ndim == 2: return _scipy.linalg.fractional_matrix_power(A, t) - return _np.stack([_scipy.linalg.fractional_matrix_power(A_, t) for A_ in A]) + return _np.stack([_scipy.linalg.fractional_matrix_power(A_, t) for A_ in A]) \ No newline at end of file diff --git a/pyrecest/_backend/_shared_numpy/random.py b/pyrecest/_backend/_shared_numpy/random.py index 00ec08f6..dc25e10b 100644 --- a/pyrecest/_backend/_shared_numpy/random.py +++ b/pyrecest/_backend/_shared_numpy/random.py @@ -26,4 +26,4 @@ def choice(*args, **kwargs): - return _np.random.default_rng().choice(*args, **kwargs) + return _np.random.default_rng().choice(*args, **kwargs) \ No newline at end of file diff --git a/pyrecest/_backend/autograd/__init__.py b/pyrecest/_backend/autograd/__init__.py index 9023cf3b..8fa71145 100644 --- a/pyrecest/_backend/autograd/__init__.py +++ b/pyrecest/_backend/autograd/__init__.py @@ -172,4 +172,4 @@ def outer(a, b): if b.ndim == 2: out = out.swapaxes(-3, -2) - return out + return out \ No newline at end of file diff --git a/pyrecest/_backend/autograd/_common.py b/pyrecest/_backend/autograd/_common.py index d09fae5c..d74f95a5 100644 --- a/pyrecest/_backend/autograd/_common.py +++ b/pyrecest/_backend/autograd/_common.py @@ -33,4 +33,4 @@ zeros = _dyn_update_dtype(target=_np.zeros) eye = _dyn_update_dtype(target=_np.eye) -array = _cast_out_from_dtype(target=_np.array) +array = _cast_out_from_dtype(target=_np.array) \ No newline at end of file diff --git a/pyrecest/_backend/autograd/autodiff.py b/pyrecest/_backend/autograd/autodiff.py index e8a08caf..5c9cfdcb 100644 --- a/pyrecest/_backend/autograd/autodiff.py +++ b/pyrecest/_backend/autograd/autodiff.py @@ -298,4 +298,4 @@ def _jac(x): return _cached_value_and_jacobian( _cached_value_and_jacobian(func), return_cached=True - ) + ) \ No newline at end of file diff --git a/pyrecest/_backend/autograd/linalg.py b/pyrecest/_backend/autograd/linalg.py index 4872864b..dc8e7ca1 100644 --- a/pyrecest/_backend/autograd/linalg.py +++ b/pyrecest/_backend/autograd/linalg.py @@ -47,4 +47,4 @@ def vjp(g): logm = _primitive(_logm) _logm_vjp = _functools.partial(_adjoint, fn=logm) -_defvjp(logm, _logm_vjp) +_defvjp(logm, _logm_vjp) \ No newline at end of file diff --git a/pyrecest/_backend/autograd/random.py b/pyrecest/_backend/autograd/random.py index f1f97d90..cd48a105 100644 --- a/pyrecest/_backend/autograd/random.py +++ b/pyrecest/_backend/autograd/random.py @@ -2,4 +2,4 @@ import autograd.numpy as _np from autograd.numpy.random import randint, seed -from .._shared_numpy.random import choice, multivariate_normal, normal, rand, uniform +from .._shared_numpy.random import choice, multivariate_normal, normal, rand, uniform \ No newline at end of file diff --git a/pyrecest/_backend/numpy/__init__.py b/pyrecest/_backend/numpy/__init__.py index ecffcab1..45b560fa 100644 --- a/pyrecest/_backend/numpy/__init__.py +++ b/pyrecest/_backend/numpy/__init__.py @@ -153,4 +153,4 @@ ones = _modify_func_default_dtype(target=_np.ones) linspace = _dyn_update_dtype(target=_np.linspace, dtype_pos=5) -empty = _dyn_update_dtype(target=_np.empty, dtype_pos=1) +empty = _dyn_update_dtype(target=_np.empty, dtype_pos=1) \ No newline at end of file diff --git a/pyrecest/_backend/numpy/_common.py b/pyrecest/_backend/numpy/_common.py index 857af64e..410721f7 100644 --- a/pyrecest/_backend/numpy/_common.py +++ b/pyrecest/_backend/numpy/_common.py @@ -33,4 +33,4 @@ array = _cast_out_from_dtype(target=_np.array, dtype_pos=1) eye = _modify_func_default_dtype(target=_np.eye) -zeros = _dyn_update_dtype(target=_np.zeros, dtype_pos=1) +zeros = _dyn_update_dtype(target=_np.zeros, dtype_pos=1) \ No newline at end of file diff --git a/pyrecest/_backend/numpy/autodiff.py b/pyrecest/_backend/numpy/autodiff.py index 761f47ac..c24836f3 100644 --- a/pyrecest/_backend/numpy/autodiff.py +++ b/pyrecest/_backend/numpy/autodiff.py @@ -58,4 +58,4 @@ def decorator(func): def value_jacobian_and_hessian(*args, **kwargs): - raise AutodiffNotImplementedError(_USE_OTHER_BACKEND_MSG) + raise AutodiffNotImplementedError(_USE_OTHER_BACKEND_MSG) \ No newline at end of file diff --git a/pyrecest/_backend/numpy/linalg.py b/pyrecest/_backend/numpy/linalg.py index 30305ee8..c9ac9a21 100644 --- a/pyrecest/_backend/numpy/linalg.py +++ b/pyrecest/_backend/numpy/linalg.py @@ -24,4 +24,4 @@ quadratic_assignment, solve_sylvester, sqrtm, -) +) \ No newline at end of file diff --git a/pyrecest/_backend/numpy/random.py b/pyrecest/_backend/numpy/random.py index 0ddb064a..9813d44b 100644 --- a/pyrecest/_backend/numpy/random.py +++ b/pyrecest/_backend/numpy/random.py @@ -4,4 +4,4 @@ from numpy.random import default_rng as _default_rng from numpy.random import randint, seed -from .._shared_numpy.random import choice, multivariate_normal, normal, rand, uniform +from .._shared_numpy.random import choice, multivariate_normal, normal, rand, uniform \ No newline at end of file diff --git a/pyrecest/_backend/pytorch/__init__.py b/pyrecest/_backend/pytorch/__init__.py index 54a9b249..44a0547d 100644 --- a/pyrecest/_backend/pytorch/__init__.py +++ b/pyrecest/_backend/pytorch/__init__.py @@ -801,4 +801,4 @@ def imag(a): a = _torch.tensor(a) if is_complex(a): return _torch.imag(a) - return _torch.zeros(a.shape, dtype=a.dtype) + return _torch.zeros(a.shape, dtype=a.dtype) \ No newline at end of file diff --git a/pyrecest/_backend/pytorch/_common.py b/pyrecest/_backend/pytorch/_common.py index 79c8268c..39be60df 100644 --- a/pyrecest/_backend/pytorch/_common.py +++ b/pyrecest/_backend/pytorch/_common.py @@ -30,4 +30,4 @@ def array(val, dtype=None): def cast(x, dtype): if _torch.is_tensor(x): return x.to(dtype=dtype) - return array(x, dtype=dtype) + return array(x, dtype=dtype) \ No newline at end of file diff --git a/pyrecest/_backend/pytorch/_dtype.py b/pyrecest/_backend/pytorch/_dtype.py index 91a999a4..8b4c1da4 100644 --- a/pyrecest/_backend/pytorch/_dtype.py +++ b/pyrecest/_backend/pytorch/_dtype.py @@ -145,4 +145,4 @@ def _wrapped(x1, x2, *args, **kwargs): if target is None: return _decorator - return _decorator(target) + return _decorator(target) \ No newline at end of file diff --git a/pyrecest/_backend/pytorch/autodiff.py b/pyrecest/_backend/pytorch/autodiff.py index c111c8ad..81119ede 100644 --- a/pyrecest/_backend/pytorch/autodiff.py +++ b/pyrecest/_backend/pytorch/autodiff.py @@ -361,4 +361,4 @@ def _value_jacobian_and_hessian(*args, **kwargs): hessian_vec(func, func_out_ndim=func_out_ndim)(*args, **kwargs), ) - return _value_jacobian_and_hessian + return _value_jacobian_and_hessian \ No newline at end of file diff --git a/pyrecest/_backend/pytorch/linalg.py b/pyrecest/_backend/pytorch/linalg.py index 41afe2ae..a2d06188 100644 --- a/pyrecest/_backend/pytorch/linalg.py +++ b/pyrecest/_backend/pytorch/linalg.py @@ -146,4 +146,4 @@ def fractional_matrix_power(A, t): else: out = _np.stack([_scipy.linalg.fractional_matrix_power(A_, t) for A_ in A]) - return _torch.tensor(out) + return _torch.tensor(out) \ No newline at end of file diff --git a/pyrecest/_backend/pytorch/random.py b/pyrecest/_backend/pytorch/random.py index 17569156..41379ba4 100644 --- a/pyrecest/_backend/pytorch/random.py +++ b/pyrecest/_backend/pytorch/random.py @@ -41,4 +41,4 @@ def uniform(low=0.0, high=1.0, size=(1,), dtype=None): def multivariate_normal(mean, cov, size=(1,)): if not hasattr(size, "__iter__"): size = (size,) - return _MultivariateNormal(mean, cov).sample(size) + return _MultivariateNormal(mean, cov).sample(size) \ No newline at end of file diff --git a/pyrecest/distributions/__init__.py b/pyrecest/distributions/__init__.py index 52826c95..907f1b80 100644 --- a/pyrecest/distributions/__init__.py +++ b/pyrecest/distributions/__init__.py @@ -337,4 +337,4 @@ "LinearMixture", "SE3CartProdStackedDistribution", "SE3DiracDistribution", -] +] \ No newline at end of file diff --git a/pyrecest/distributions/abstract_bounded_domain_distribution.py b/pyrecest/distributions/abstract_bounded_domain_distribution.py index a4a16dc0..0a5072db 100644 --- a/pyrecest/distributions/abstract_bounded_domain_distribution.py +++ b/pyrecest/distributions/abstract_bounded_domain_distribution.py @@ -11,4 +11,4 @@ class AbstractBoundedDomainDistribution(AbstractManifoldSpecificDistribution): serves as the base class for all distributions that are defined over bounded domains. This class does not define any methods or properties and is intended to be subclassed by specific distributions. - """ + """ \ No newline at end of file diff --git a/pyrecest/distributions/abstract_bounded_nonperiodic_distribution.py b/pyrecest/distributions/abstract_bounded_nonperiodic_distribution.py index e65b7c12..a02c02a2 100644 --- a/pyrecest/distributions/abstract_bounded_nonperiodic_distribution.py +++ b/pyrecest/distributions/abstract_bounded_nonperiodic_distribution.py @@ -11,4 +11,4 @@ class AbstractBoundedNonPeriodicDistribution(AbstractBoundedDomainDistribution): """ def mean(self): - raise ValueError("Mean currently not supported.") + raise ValueError("Mean currently not supported.") \ No newline at end of file diff --git a/pyrecest/distributions/abstract_custom_distribution.py b/pyrecest/distributions/abstract_custom_distribution.py index a460c55d..c8ea0d60 100644 --- a/pyrecest/distributions/abstract_custom_distribution.py +++ b/pyrecest/distributions/abstract_custom_distribution.py @@ -25,7 +25,6 @@ class AbstractCustomDistribution(AbstractDistributionType): Normalize the PDF such that its integral is 1. Returns a copy of the original distribution. """ - @beartype def __init__(self, f: Callable[[np.ndarray], np.ndarray], scale_by=1): """ Initialize AbstractCustomDistribution. @@ -36,7 +35,6 @@ def __init__(self, f: Callable[[np.ndarray], np.ndarray], scale_by=1): self.f = f self.scale_by = scale_by - @beartype def pdf(self, xs: np.ndarray) -> np.ndarray | np.number: """ Compute the probability density function at given points. @@ -48,7 +46,6 @@ def pdf(self, xs: np.ndarray) -> np.ndarray | np.number: return self.scale_by * self.f(xs) @abstractmethod - @beartype def integrate(self, integration_boundaries=None): """ Calculate the integral of the probability density function. @@ -57,7 +54,6 @@ def integrate(self, integration_boundaries=None): :returns: The integral of the PDF. """ - @beartype def normalize(self, verify: bool | None = None) -> "AbstractCustomDistribution": """ Normalize the PDF such that its integral is 1. @@ -73,4 +69,4 @@ def normalize(self, verify: bool | None = None) -> "AbstractCustomDistribution": if verify and abs(cd.integrate()[0] - 1) > 0.001: warnings.warn("Density is not yet properly normalized.", UserWarning) - return cd + return cd \ No newline at end of file diff --git a/pyrecest/distributions/abstract_custom_nonperiodic_distribution.py b/pyrecest/distributions/abstract_custom_nonperiodic_distribution.py index 202e9f63..1f700b56 100644 --- a/pyrecest/distributions/abstract_custom_nonperiodic_distribution.py +++ b/pyrecest/distributions/abstract_custom_nonperiodic_distribution.py @@ -10,4 +10,4 @@ class AbstractCustomNonPeriodicDistribution( Custom non-periodic distributions are distributions that are defined by a given probability density function and are not periodic. - """ + """ \ No newline at end of file diff --git a/pyrecest/distributions/abstract_dirac_distribution.py b/pyrecest/distributions/abstract_dirac_distribution.py index fff62321..90a43dd3 100644 --- a/pyrecest/distributions/abstract_dirac_distribution.py +++ b/pyrecest/distributions/abstract_dirac_distribution.py @@ -1,3 +1,4 @@ +from typing import Union from pyrecest.backend import sum from pyrecest.backend import ones from pyrecest.backend import log @@ -21,7 +22,6 @@ class AbstractDiracDistribution(AbstractDistributionType): This class represents an abstract base for Dirac distributions. """ - @beartype def __init__(self, d: np.ndarray, w: np.ndarray | None = None): """ Initialize a Dirac distribution with given Dirac locations and weights. @@ -37,7 +37,6 @@ def __init__(self, d: np.ndarray, w: np.ndarray | None = None): self.w = copy.copy(w) self.normalize_in_place() - @beartype def normalize_in_place(self): """ Normalize the weights in-place to ensure they sum to 1. @@ -46,13 +45,11 @@ def normalize_in_place(self): warnings.warn("Weights are not normalized.", RuntimeWarning) self.w = self.w / sum(self.w) - @beartype def normalize(self) -> "AbstractDiracDistribution": dist = copy.deepcopy(self) dist.normalize_in_place() return dist - @beartype def apply_function( self, f: Callable, f_supports_multiple: bool = True ) -> "AbstractDiracDistribution": @@ -69,7 +66,6 @@ def apply_function( dist.d = np.apply_along_axis(f, 1, dist.d) return dist - @beartype def reweigh(self, f: Callable) -> "AbstractDiracDistribution": dist = copy.deepcopy(self) wNew = f(dist.d) @@ -83,8 +79,7 @@ def reweigh(self, f: Callable) -> "AbstractDiracDistribution": return dist - @beartype - def sample(self, n: int | int32 | int64) -> np.ndarray: + def sample(self, n: Union[int, int32, int64]) -> np.ndarray: ids = np.random.choice(np.size(self.w), size=n, p=self.w) return self.d[ids] @@ -141,4 +136,4 @@ def is_valid_for_conversion(cls, distribution): def from_distribution(cls, distribution, n_particles): assert cls.is_valid_for_conversion(distribution) samples = distribution.sample(n_particles) - return cls(samples) + return cls(samples) \ No newline at end of file diff --git a/pyrecest/distributions/abstract_disk_distribution.py b/pyrecest/distributions/abstract_disk_distribution.py index 73c74c0b..0798fe99 100644 --- a/pyrecest/distributions/abstract_disk_distribution.py +++ b/pyrecest/distributions/abstract_disk_distribution.py @@ -15,4 +15,4 @@ def __init__(self): super().__init__(array([0, 0]), eye(2)) def mean(self): - raise TypeError("Mean not defined for distributions on the disk.") + raise TypeError("Mean not defined for distributions on the disk.") \ No newline at end of file diff --git a/pyrecest/distributions/abstract_distribution_type.py b/pyrecest/distributions/abstract_distribution_type.py index eef203a1..ef422669 100644 --- a/pyrecest/distributions/abstract_distribution_type.py +++ b/pyrecest/distributions/abstract_distribution_type.py @@ -5,4 +5,4 @@ class AbstractDistributionType(ABC): """ This class represents an abstract base for specific types of distributions, regardless of their domain (uniform, mixture, custom, etc.) - """ + """ \ No newline at end of file diff --git a/pyrecest/distributions/abstract_ellipsoidal_ball_distribution.py b/pyrecest/distributions/abstract_ellipsoidal_ball_distribution.py index fe3f39a3..b07f5e89 100644 --- a/pyrecest/distributions/abstract_ellipsoidal_ball_distribution.py +++ b/pyrecest/distributions/abstract_ellipsoidal_ball_distribution.py @@ -15,7 +15,6 @@ class AbstractEllipsoidalBallDistribution(AbstractBoundedNonPeriodicDistribution This class represents distributions on ellipsoidal balls. """ - @beartype def __init__(self, center: np.ndarray, shape_matrix: np.ndarray): """ Initialize the class with a center and shape matrix. @@ -29,7 +28,6 @@ def __init__(self, center: np.ndarray, shape_matrix: np.ndarray): assert center.ndim == 1 and shape_matrix.ndim == 2 assert shape_matrix.shape[0] == self.dim and shape_matrix.shape[1] == self.dim - @beartype def get_manifold_size(self) -> np.number | numbers.Real: """ Calculate the size of the manifold. @@ -51,4 +49,4 @@ def get_manifold_size(self) -> np.number | numbers.Real: else: c = (np.pi ** (self.dim / 2)) / gamma((self.dim / 2) + 1) - return c * sqrt(np.linalg.det(self.shape_matrix)) + return c * sqrt(np.linalg.det(self.shape_matrix)) \ No newline at end of file diff --git a/pyrecest/distributions/abstract_manifold_specific_distribution.py b/pyrecest/distributions/abstract_manifold_specific_distribution.py index 1586b307..089c17dc 100644 --- a/pyrecest/distributions/abstract_manifold_specific_distribution.py +++ b/pyrecest/distributions/abstract_manifold_specific_distribution.py @@ -17,7 +17,6 @@ class AbstractManifoldSpecificDistribution(ABC): Should be inerhited by (abstract) classes limited to specific manifolds. """ - @beartype def __init__(self, dim: int): self._dim = dim @@ -31,7 +30,6 @@ def dim(self) -> int: return self._dim @dim.setter - @beartype def dim(self, value: int): """Set dimension of the manifold. Must be a positive integer or None.""" if value <= 0: @@ -45,7 +43,6 @@ def input_dim(self) -> int: pass @abstractmethod - @beartype def pdf(self, xs: np.ndarray) -> np.ndarray: pass @@ -109,4 +106,4 @@ def sample_metropolis_hastings( i += 1 relevant_samples = s[burn_in::skipping, :] - return squeeze(relevant_samples) + return squeeze(relevant_samples) \ No newline at end of file diff --git a/pyrecest/distributions/abstract_mixture.py b/pyrecest/distributions/abstract_mixture.py index e19ea199..ffb466d4 100644 --- a/pyrecest/distributions/abstract_mixture.py +++ b/pyrecest/distributions/abstract_mixture.py @@ -1,3 +1,4 @@ +from typing import Union from pyrecest.backend import sum from pyrecest.backend import ones from pyrecest.backend import int64 @@ -22,7 +23,6 @@ class AbstractMixture(AbstractDistributionType): Abstract base class for mixture distributions. """ - @beartype def __init__( self, dists: collections.abc.Sequence[AbstractManifoldSpecificDistribution], @@ -64,8 +64,7 @@ def __init__( def input_dim(self) -> int: return self.dists[0].input_dim - @beartype - def sample(self, n: int | int32 | int64) -> np.ndarray: + def sample(self, n: Union[int, int32, int64]) -> np.ndarray: d = np.random.choice(len(self.w), size=n, p=self.w) occurrences = np.bincount(d, minlength=len(self.dists)) @@ -81,7 +80,6 @@ def sample(self, n: int | int32 | int64) -> np.ndarray: return s - @beartype def pdf(self, xs: np.ndarray) -> np.ndarray: assert xs.shape[-1] == self.input_dim, "Dimension mismatch" @@ -90,4 +88,4 @@ def pdf(self, xs: np.ndarray) -> np.ndarray: for i, dist in enumerate(self.dists): p += self.w[i] * dist.pdf(xs) - return p + return p \ No newline at end of file diff --git a/pyrecest/distributions/abstract_nonperiodic_distribution.py b/pyrecest/distributions/abstract_nonperiodic_distribution.py index 7eeff3c6..865e1ae1 100644 --- a/pyrecest/distributions/abstract_nonperiodic_distribution.py +++ b/pyrecest/distributions/abstract_nonperiodic_distribution.py @@ -6,4 +6,4 @@ class AbstractNonperiodicDistribution(AbstractManifoldSpecificDistribution): """ Abstract base class for all distributions on non-periodic manifolds. - """ + """ \ No newline at end of file diff --git a/pyrecest/distributions/abstract_orthogonal_basis_distribution.py b/pyrecest/distributions/abstract_orthogonal_basis_distribution.py index 4cfed29a..f97a6fb4 100644 --- a/pyrecest/distributions/abstract_orthogonal_basis_distribution.py +++ b/pyrecest/distributions/abstract_orthogonal_basis_distribution.py @@ -51,7 +51,6 @@ def normalize(self): result = copy.deepcopy(self) return result.normalize_in_place() - @beartype def pdf(self, xs: np.ndarray | np.number) -> np.ndarray | np.number: """ Calculates probability density function for the given input. @@ -71,4 +70,4 @@ def pdf(self, xs: np.ndarray | np.number) -> np.ndarray | np.number: warnings.warn("Density may not be normalized") return exp(val) - raise ValueError("Transformation not recognized or unsupported") + raise ValueError("Transformation not recognized or unsupported") \ No newline at end of file diff --git a/pyrecest/distributions/abstract_periodic_distribution.py b/pyrecest/distributions/abstract_periodic_distribution.py index 00495ed3..a805450c 100644 --- a/pyrecest/distributions/abstract_periodic_distribution.py +++ b/pyrecest/distributions/abstract_periodic_distribution.py @@ -1,3 +1,4 @@ +from typing import Union from pyrecest.backend import int64 from pyrecest.backend import int32 from abc import abstractmethod @@ -11,11 +12,9 @@ class AbstractPeriodicDistribution(AbstractBoundedDomainDistribution): """Abstract class for a distributions on periodic manifolds.""" - @beartype - def __init__(self, dim: int | int32 | int64): + def __init__(self, dim: Union[int, int32, int64]): super().__init__(dim=dim) - @beartype def mean(self) -> np.ndarray: """ Convenient access to mean_direction to have a consistent interface @@ -35,4 +34,4 @@ def mean_direction(self) -> np.ndarray: ------- mean_direction: np.ndarray The mean direction of the distribution. - """ + """ \ No newline at end of file diff --git a/pyrecest/distributions/abstract_se3_distribution.py b/pyrecest/distributions/abstract_se3_distribution.py index c76b4361..97115f90 100644 --- a/pyrecest/distributions/abstract_se3_distribution.py +++ b/pyrecest/distributions/abstract_se3_distribution.py @@ -1,3 +1,4 @@ +from typing import Union from pyrecest.backend import concatenate from pyrecest.backend import int64 from pyrecest.backend import int32 @@ -32,7 +33,7 @@ def plot_mode(self): def plot_state( self, - orientationSamples: int | int32 | int64 = 10, + orientationSamples: Union[int, int32, int64] = 10, showMarginalized: bool = True, ): samples = self.sample(orientationSamples) @@ -109,4 +110,4 @@ def plot_trajectory(periodicStates, linStates, animate=False, delay=0.05): return h def get_manifold_size(self): - return np.inf + return np.inf \ No newline at end of file diff --git a/pyrecest/distributions/abstract_uniform_distribution.py b/pyrecest/distributions/abstract_uniform_distribution.py index bcae3375..7fce0d85 100644 --- a/pyrecest/distributions/abstract_uniform_distribution.py +++ b/pyrecest/distributions/abstract_uniform_distribution.py @@ -10,7 +10,6 @@ class AbstractUniformDistribution(AbstractDistributionType): """Abstract class for a uniform distribution on a manifold.""" - @beartype def pdf(self, xs: np.ndarray) -> np.ndarray: """Compute the probability density function at each point in xs. @@ -36,4 +35,4 @@ def get_manifold_size(self) -> np.ndarray: def mode(self): """Mode is not defined for a uniform distribution.""" - raise AttributeError("Mode not available for uniform distribution") + raise AttributeError("Mode not available for uniform distribution") \ No newline at end of file diff --git a/pyrecest/distributions/cart_prod/abstract_cart_prod_distribution.py b/pyrecest/distributions/cart_prod/abstract_cart_prod_distribution.py index 92c35886..e6e1b34b 100644 --- a/pyrecest/distributions/cart_prod/abstract_cart_prod_distribution.py +++ b/pyrecest/distributions/cart_prod/abstract_cart_prod_distribution.py @@ -7,4 +7,4 @@ class AbstractCartProdDistribution(AbstractManifoldSpecificDistribution): """ For arbitrary Cartesian products, such as ones of linear and bounded or hypertori and hypersphere, etc. - """ + """ \ No newline at end of file diff --git a/pyrecest/distributions/cart_prod/abstract_custom_lin_bounded_cart_prod_distribution.py b/pyrecest/distributions/cart_prod/abstract_custom_lin_bounded_cart_prod_distribution.py index 7279dc34..c7d66174 100644 --- a/pyrecest/distributions/cart_prod/abstract_custom_lin_bounded_cart_prod_distribution.py +++ b/pyrecest/distributions/cart_prod/abstract_custom_lin_bounded_cart_prod_distribution.py @@ -13,7 +13,6 @@ class AbstractCustomLinBoundedCartProdDistribution( ): """Is abstract because .input_dim (among others) cannot be properly defined without specifying the specific periodic dimension""" - @beartype def __init__(self, f_: Callable, bound_dim: int, lin_dim: int): """ Parameters: @@ -33,9 +32,8 @@ def __init__(self, f_: Callable, bound_dim: int, lin_dim: int): AbstractLinPeriodicCartProdDistribution.__init__(self, bound_dim, lin_dim) @staticmethod - @beartype def from_distribution(distribution: AbstractLinPeriodicCartProdDistribution): chhd = AbstractCustomLinBoundedCartProdDistribution( distribution.pdf, distribution.bound_dim, distribution.lin_dim ) - return chhd + return chhd \ No newline at end of file diff --git a/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py b/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py index 4b701db4..38a50d94 100644 --- a/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py +++ b/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py @@ -1,3 +1,4 @@ +from typing import Union from pyrecest.backend import vstack from pyrecest.backend import tile from pyrecest.backend import sqrt @@ -33,7 +34,7 @@ class AbstractHypercylindricalDistribution(AbstractLinPeriodicCartProdDistribution): def __init__( - self, bound_dim: int | int32 | int64, lin_dim: int | int32 | int64 + self, bound_dim: Union[int, int32, int64], lin_dim: Union[int, int32, int64] ): AbstractLinPeriodicCartProdDistribution.__init__(self, bound_dim, lin_dim) @@ -55,7 +56,6 @@ def f(*args): return integration_result - @beartype def get_reasonable_integration_boundaries(self, scalingFactor=10) -> np.ndarray: """ Returns reasonable integration boundaries for the specific distribution @@ -275,4 +275,4 @@ def mode_numerical(self, starting_point=None): @property def input_dim(self): - return self.dim + return self.dim \ No newline at end of file diff --git a/pyrecest/distributions/cart_prod/abstract_lin_bounded_cart_prod_distribution.py b/pyrecest/distributions/cart_prod/abstract_lin_bounded_cart_prod_distribution.py index 7b451099..8fc9bdcd 100644 --- a/pyrecest/distributions/cart_prod/abstract_lin_bounded_cart_prod_distribution.py +++ b/pyrecest/distributions/cart_prod/abstract_lin_bounded_cart_prod_distribution.py @@ -1,3 +1,4 @@ +from typing import Union from pyrecest.backend import int64 from pyrecest.backend import int32 from abc import abstractmethod @@ -15,9 +16,8 @@ class AbstractLinBoundedCartProdDistribution(AbstractCartProdDistribution): are ordered as follows: bounded dimensions first, then linear dimensions. """ - @beartype def __init__( - self, bound_dim: int | int32 | int64, lin_dim: int | int32 | int64 + self, bound_dim: Union[int, int32, int64], lin_dim: Union[int, int32, int64] ): """ Parameters: @@ -58,4 +58,4 @@ def marginalize_linear(self): @abstractmethod def marginalize_periodic(self): - pass + pass \ No newline at end of file diff --git a/pyrecest/distributions/cart_prod/abstract_lin_hemisphere_cart_prod_distribution.py b/pyrecest/distributions/cart_prod/abstract_lin_hemisphere_cart_prod_distribution.py index 42f37471..a866a73b 100644 --- a/pyrecest/distributions/cart_prod/abstract_lin_hemisphere_cart_prod_distribution.py +++ b/pyrecest/distributions/cart_prod/abstract_lin_hemisphere_cart_prod_distribution.py @@ -6,4 +6,4 @@ class AbstractLinHemisphereCartProdDistribution( AbstractLinHyperhemisphereCartProdDistribution ): - pass + pass \ No newline at end of file diff --git a/pyrecest/distributions/cart_prod/abstract_lin_hyperhemisphere_cart_prod_distribution.py b/pyrecest/distributions/cart_prod/abstract_lin_hyperhemisphere_cart_prod_distribution.py index c28bad24..8a99a3e5 100644 --- a/pyrecest/distributions/cart_prod/abstract_lin_hyperhemisphere_cart_prod_distribution.py +++ b/pyrecest/distributions/cart_prod/abstract_lin_hyperhemisphere_cart_prod_distribution.py @@ -10,4 +10,4 @@ class AbstractLinHyperhemisphereCartProdDistribution( AbstractLinHypersphereSubsetCartProdDistribution, AbstractLinPeriodicCartProdDistribution, ): - pass + pass \ No newline at end of file diff --git a/pyrecest/distributions/cart_prod/abstract_lin_hypersphere_cart_prod_distribution.py b/pyrecest/distributions/cart_prod/abstract_lin_hypersphere_cart_prod_distribution.py index f3368d09..2439382c 100644 --- a/pyrecest/distributions/cart_prod/abstract_lin_hypersphere_cart_prod_distribution.py +++ b/pyrecest/distributions/cart_prod/abstract_lin_hypersphere_cart_prod_distribution.py @@ -10,4 +10,4 @@ class AbstractLinHypersphereCartProdDistribution( AbstractLinHypersphereSubsetCartProdDistribution, AbstractLinPeriodicCartProdDistribution, ): - pass + pass \ No newline at end of file diff --git a/pyrecest/distributions/cart_prod/abstract_lin_hypersphere_subset_cart_prod_distribution.py b/pyrecest/distributions/cart_prod/abstract_lin_hypersphere_subset_cart_prod_distribution.py index 938447bc..a343314e 100644 --- a/pyrecest/distributions/cart_prod/abstract_lin_hypersphere_subset_cart_prod_distribution.py +++ b/pyrecest/distributions/cart_prod/abstract_lin_hypersphere_subset_cart_prod_distribution.py @@ -6,4 +6,4 @@ class AbstractLinHypersphereSubsetCartProdDistribution( AbstractLinBoundedCartProdDistribution ): - pass + pass \ No newline at end of file diff --git a/pyrecest/distributions/cart_prod/abstract_lin_periodic_cart_prod_distribution.py b/pyrecest/distributions/cart_prod/abstract_lin_periodic_cart_prod_distribution.py index bf006a85..7a111b40 100644 --- a/pyrecest/distributions/cart_prod/abstract_lin_periodic_cart_prod_distribution.py +++ b/pyrecest/distributions/cart_prod/abstract_lin_periodic_cart_prod_distribution.py @@ -18,4 +18,4 @@ def get_manifold_size(self): assert ( self.lin_dim > 0 ), "This class is not intended to be used for purely periodic domains." - return np.inf + return np.inf \ No newline at end of file diff --git a/pyrecest/distributions/cart_prod/cart_prod_stacked_distribution.py b/pyrecest/distributions/cart_prod/cart_prod_stacked_distribution.py index 8bcb1f81..b922efc0 100644 --- a/pyrecest/distributions/cart_prod/cart_prod_stacked_distribution.py +++ b/pyrecest/distributions/cart_prod/cart_prod_stacked_distribution.py @@ -56,4 +56,4 @@ def mean(self): return self.hybrid_mean() def mode(self): - return concatenate([dist.mode() for dist in self.dists]) + return concatenate([dist.mode() for dist in self.dists]) \ No newline at end of file diff --git a/pyrecest/distributions/cart_prod/custom_hypercylindrical_distribution.py b/pyrecest/distributions/cart_prod/custom_hypercylindrical_distribution.py index 8606a58e..46ccff7b 100644 --- a/pyrecest/distributions/cart_prod/custom_hypercylindrical_distribution.py +++ b/pyrecest/distributions/cart_prod/custom_hypercylindrical_distribution.py @@ -66,4 +66,4 @@ def marginalize_linear(self): # Needed because abstract method needs to be implemented def marginalize_periodic(self): - return AbstractCustomLinBoundedCartProdDistribution.marginalize_periodic(self) + return AbstractCustomLinBoundedCartProdDistribution.marginalize_periodic(self) \ No newline at end of file diff --git a/pyrecest/distributions/cart_prod/hypercylindrical_dirac_distribution.py b/pyrecest/distributions/cart_prod/hypercylindrical_dirac_distribution.py index c73d6e78..e08623d5 100644 --- a/pyrecest/distributions/cart_prod/hypercylindrical_dirac_distribution.py +++ b/pyrecest/distributions/cart_prod/hypercylindrical_dirac_distribution.py @@ -1,3 +1,4 @@ +from typing import Union from pyrecest.backend import tile from pyrecest.backend import sum from pyrecest.backend import sin @@ -16,7 +17,7 @@ class HypercylindricalDiracDistribution( LinBoundedCartProdDiracDistribution, AbstractHypercylindricalDistribution ): - def __init__(self, bound_dim: int | int32 | int64, d, w=None): + def __init__(self, bound_dim: Union[int, int32, int64], d, w=None): AbstractHypercylindricalDistribution.__init__( self, bound_dim, d.shape[-1] - bound_dim ) @@ -44,4 +45,4 @@ def hybrid_moment(self): return sum( tile(self.w, (self.lin_dim + 2 * self.bound_dim, 1)) * S, axis=1 - ) + ) \ No newline at end of file diff --git a/pyrecest/distributions/cart_prod/lin_bounded_cart_prod_dirac_distribution.py b/pyrecest/distributions/cart_prod/lin_bounded_cart_prod_dirac_distribution.py index b0915604..b0d9d713 100644 --- a/pyrecest/distributions/cart_prod/lin_bounded_cart_prod_dirac_distribution.py +++ b/pyrecest/distributions/cart_prod/lin_bounded_cart_prod_dirac_distribution.py @@ -49,4 +49,4 @@ def from_distribution(cls, distribution, n_particles): """ assert cls.is_valid_for_conversion(distribution) samples = distribution.sample(n_particles) - return cls(distribution.bound_dim, samples) + return cls(distribution.bound_dim, samples) \ No newline at end of file diff --git a/pyrecest/distributions/cart_prod/lin_hypersphere_cart_prod_dirac_distribution.py b/pyrecest/distributions/cart_prod/lin_hypersphere_cart_prod_dirac_distribution.py index f66a86df..48445f65 100644 --- a/pyrecest/distributions/cart_prod/lin_hypersphere_cart_prod_dirac_distribution.py +++ b/pyrecest/distributions/cart_prod/lin_hypersphere_cart_prod_dirac_distribution.py @@ -19,4 +19,4 @@ def __init__(self, bound_dim, d, w=None): @property def input_dim(self): - return self.dim + 1 + return self.dim + 1 \ No newline at end of file diff --git a/pyrecest/distributions/cart_prod/lin_hypersphere_subset_dirac_distribution.py b/pyrecest/distributions/cart_prod/lin_hypersphere_subset_dirac_distribution.py index 6d95b36f..496934f7 100644 --- a/pyrecest/distributions/cart_prod/lin_hypersphere_subset_dirac_distribution.py +++ b/pyrecest/distributions/cart_prod/lin_hypersphere_subset_dirac_distribution.py @@ -1,3 +1,4 @@ +from typing import Union from pyrecest.backend import int64 from pyrecest.backend import int32 import numpy as np @@ -14,8 +15,8 @@ class LinHypersphereSubsetCartProdDiracDistribution( LinBoundedCartProdDiracDistribution, AbstractLinHypersphereSubsetCartProdDistribution, ): - def __init__(self, bound_dim: int | int32 | int64, d, w=None): + def __init__(self, bound_dim: Union[int, int32, int64], d, w=None): AbstractLinHypersphereSubsetCartProdDistribution.__init__( self, bound_dim, d.shape[-1] - bound_dim - 1 ) - LinBoundedCartProdDiracDistribution.__init__(self, d=d, w=w) + LinBoundedCartProdDiracDistribution.__init__(self, d=d, w=w) \ No newline at end of file diff --git a/pyrecest/distributions/cart_prod/lin_periodic_cart_prod_dirac_distribution.py b/pyrecest/distributions/cart_prod/lin_periodic_cart_prod_dirac_distribution.py index 3f40da74..3f184e53 100644 --- a/pyrecest/distributions/cart_prod/lin_periodic_cart_prod_dirac_distribution.py +++ b/pyrecest/distributions/cart_prod/lin_periodic_cart_prod_dirac_distribution.py @@ -4,4 +4,4 @@ class LinPeriodicCartProdDiracDistribution(LinBoundedCartProdDiracDistribution): - pass + pass \ No newline at end of file diff --git a/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py b/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py index 1d1ccd32..0c13b2dd 100644 --- a/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py +++ b/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py @@ -1,3 +1,4 @@ +from typing import Union from pyrecest.backend import tile from pyrecest.backend import sum from pyrecest.backend import sin @@ -29,9 +30,8 @@ class PartiallyWrappedNormalDistribution(AbstractHypercylindricalDistribution): - @beartype def __init__( - self, mu: np.ndarray, C: np.ndarray, bound_dim: int | int32 | int64 + self, mu: np.ndarray, C: np.ndarray, bound_dim: Union[int, int32, int64] ): assert bound_dim >= 0, "bound_dim must be non-negative" assert ndim(mu) == 1, "mu must be a 1-dimensional array" @@ -51,7 +51,7 @@ def __init__( self.mu[:bound_dim] = mod(self.mu[:bound_dim], 2 * np.pi) self.C = C - def pdf(self, xs: np.ndarray, m: int | int32 | int64 = 3): + def pdf(self, xs: np.ndarray, m: Union[int, int32, int64] = 3): xs = np.atleast_2d(xs) if self.bound_dim > 0: xs[:, : self.bound_dim] = mod(xs[:, : self.bound_dim], 2 * np.pi) @@ -149,4 +149,4 @@ def marginalize_linear(self): return HypertoroidalWrappedNormalDistribution( self.mu[: self.bound_dim], self.C[: self.bound_dim, : self.bound_dim], # noqa: E203 - ) + ) \ No newline at end of file diff --git a/pyrecest/distributions/circle/abstract_circular_distribution.py b/pyrecest/distributions/circle/abstract_circular_distribution.py index 181ca579..60284918 100644 --- a/pyrecest/distributions/circle/abstract_circular_distribution.py +++ b/pyrecest/distributions/circle/abstract_circular_distribution.py @@ -15,11 +15,9 @@ class AbstractCircularDistribution(AbstractHypertoroidalDistribution): - @beartype def __init__(self): AbstractHypertoroidalDistribution.__init__(self, dim=1) - @beartype def cdf_numerical(self, xs: np.ndarray, starting_point: float = 0.0) -> np.ndarray: """ Calculates the cumulative distribution function. @@ -35,7 +33,6 @@ def cdf_numerical(self, xs: np.ndarray, starting_point: float = 0.0) -> np.ndarr return array([self._cdf_numerical_single(x, starting_point) for x in xs]) - @beartype def _cdf_numerical_single( self, x: np.number | numbers.Real, @@ -78,4 +75,4 @@ def to_wn(self): def plot_circle(*args, **kwargs): theta = np.append(linspace(0, 2 * np.pi, 320), 0) p = plt.plot(cos(theta), sin(theta), *args, **kwargs) - return p + return p \ No newline at end of file diff --git a/pyrecest/distributions/circle/circular_dirac_distribution.py b/pyrecest/distributions/circle/circular_dirac_distribution.py index b0736028..af8372fe 100644 --- a/pyrecest/distributions/circle/circular_dirac_distribution.py +++ b/pyrecest/distributions/circle/circular_dirac_distribution.py @@ -10,7 +10,6 @@ class CircularDiracDistribution( HypertoroidalDiracDistribution, AbstractCircularDistribution ): - @beartype def __init__(self, d: np.ndarray, w: np.ndarray | None = None): """ Initializes a CircularDiracDistribution instance. @@ -31,4 +30,4 @@ def plot_interpolated(self, _): """ Raises an exception since interpolation is not available for WDDistribution. """ - raise NotImplementedError("No interpolation available for WDDistribution.") + raise NotImplementedError("No interpolation available for WDDistribution.") \ No newline at end of file diff --git a/pyrecest/distributions/circle/circular_fourier_distribution.py b/pyrecest/distributions/circle/circular_fourier_distribution.py index bbbdab68..5e66a824 100644 --- a/pyrecest/distributions/circle/circular_fourier_distribution.py +++ b/pyrecest/distributions/circle/circular_fourier_distribution.py @@ -1,3 +1,4 @@ +from typing import Union from pyrecest.backend import sum from pyrecest.backend import sqrt from pyrecest.backend import sin @@ -27,7 +28,6 @@ class CircularFourierDistribution(AbstractCircularDistribution): Circular Fourier Distribution. This is based on my implementation for pytorch in pyDirectional """ - @beartype # pylint: disable=too-many-arguments def __init__( self, @@ -67,7 +67,6 @@ def __init__( self.multiplied_by_n = multiplied_by_n self.transformation = transformation - @beartype def __sub__( self, other: "CircularFourierDistribution" ) -> "CircularFourierDistribution": @@ -103,7 +102,6 @@ def __sub__( ) # The number should not change! We store it if we use a complex one now and set it to None if we falsely believe we know the number (it is not clear for complex ones) return fdNew - @beartype def pdf(self, xs: np.ndarray) -> np.ndarray: assert xs.ndim <= 2, "xs should have at most 2 dimensions." xs = xs.reshape(-1, 1) @@ -230,7 +228,6 @@ def plot_grid(self): plt.plot(xs, p, "r+") plt.show() - @beartype def plot(self, resolution=128, **kwargs): xs = linspace(0, 2 * np.pi, resolution) @@ -290,10 +287,9 @@ def get_full_c(self): return full_c @staticmethod - @beartype def from_distribution( distribution: AbstractCircularDistribution, - n: int | int32 | int64, + n: Union[int, int32, int64], transformation: str = "sqrt", store_values_multiplied_by_n: bool = True, ) -> "CircularFourierDistribution": @@ -323,7 +319,6 @@ def from_distribution( return fd @staticmethod - @beartype def from_function_values( fvals: np.ndarray, transformation: str = "sqrt", @@ -340,4 +335,4 @@ def from_function_values( multiplied_by_n=store_values_multiplied_by_n, ) - return fd + return fd \ No newline at end of file diff --git a/pyrecest/distributions/circle/circular_mixture.py b/pyrecest/distributions/circle/circular_mixture.py index 449bf7ad..fdee9332 100644 --- a/pyrecest/distributions/circle/circular_mixture.py +++ b/pyrecest/distributions/circle/circular_mixture.py @@ -13,7 +13,6 @@ class CircularMixture(AbstractCircularDistribution, HypertoroidalMixture): - @beartype def __init__( self, dists: collections.abc.Sequence[AbstractCircularDistribution], @@ -47,4 +46,4 @@ def __init__( ) self.dists = dists - self.w = w / sum(w) + self.w = w / sum(w) \ No newline at end of file diff --git a/pyrecest/distributions/circle/circular_uniform_distribution.py b/pyrecest/distributions/circle/circular_uniform_distribution.py index f54dbfbf..44668204 100644 --- a/pyrecest/distributions/circle/circular_uniform_distribution.py +++ b/pyrecest/distributions/circle/circular_uniform_distribution.py @@ -44,4 +44,4 @@ def cdf(self, xa, starting_point=0): val = (xa - starting_point) / (2 * np.pi) val[val < 0] = val[val < 0] + 1 - return val + return val \ No newline at end of file diff --git a/pyrecest/distributions/circle/custom_circular_distribution.py b/pyrecest/distributions/circle/custom_circular_distribution.py index 00a4bda4..c6ee5c06 100644 --- a/pyrecest/distributions/circle/custom_circular_distribution.py +++ b/pyrecest/distributions/circle/custom_circular_distribution.py @@ -12,7 +12,6 @@ class CustomCircularDistribution( AbstractCustomDistribution, AbstractCircularDistribution ): - @beartype def __init__(self, f_: Callable, scale_by: float = 1, shift_by: float = 0): """ Initializes a new instance of the CustomCircularDistribution class. @@ -30,7 +29,6 @@ def __init__(self, f_: Callable, scale_by: float = 1, shift_by: float = 0): AbstractCustomDistribution.__init__(self, f_, scale_by) self.shift_by = shift_by - @beartype def pdf(self, xs: np.ndarray): """ Computes the probability density function at xs. @@ -45,7 +43,6 @@ def pdf(self, xs: np.ndarray): self, mod(xs + self.shift_by, 2 * np.pi) ) - @beartype def integrate(self, integration_boundaries: np.ndarray | None = None) -> float: """ Computes the integral of the pdf over the given boundaries. @@ -59,4 +56,4 @@ def integrate(self, integration_boundaries: np.ndarray | None = None) -> float: """ if integration_boundaries is None: integration_boundaries = array([0, 2 * np.pi]) - return AbstractCircularDistribution.integrate(self, integration_boundaries) + return AbstractCircularDistribution.integrate(self, integration_boundaries) \ No newline at end of file diff --git a/pyrecest/distributions/circle/von_mises_distribution.py b/pyrecest/distributions/circle/von_mises_distribution.py index 141e6028..95ad7996 100644 --- a/pyrecest/distributions/circle/von_mises_distribution.py +++ b/pyrecest/distributions/circle/von_mises_distribution.py @@ -38,13 +38,11 @@ def get_params(self): return self.mu, self.kappa @property - @beartype def norm_const(self) -> np.number: if self._norm_const is None: self._norm_const = 2 * np.pi * iv(0, self.kappa) return self._norm_const - @beartype def pdf(self, xs: np.ndarray) -> np.ndarray | np.number: p = exp(self.kappa * cos(xs - self.mu)) / self.norm_const return p @@ -97,7 +95,6 @@ def to_minus_pi_to_pi_range( return r @staticmethod - @beartype def besselratio_inverse( v: np.number | numbers.Real, x: np.number | numbers.Real ) -> np.number | numbers.Real: @@ -108,7 +105,6 @@ def f(t: float) -> float: (kappa,) = fsolve(f, start) return kappa - @beartype def multiply(self, vm2: "VonMisesDistribution") -> "VonMisesDistribution": C = self.kappa * cos(self.mu) + vm2.kappa * cos(vm2.mu) S = self.kappa * sin(self.mu) + vm2.kappa * sin(vm2.mu) @@ -116,7 +112,6 @@ def multiply(self, vm2: "VonMisesDistribution") -> "VonMisesDistribution": kappa_ = sqrt(C**2 + S**2) return VonMisesDistribution(mu_, kappa_) - @beartype def convolve(self, vm2: "VonMisesDistribution") -> "VonMisesDistribution": mu_ = mod(self.mu + vm2.mu, 2 * np.pi) t = VonMisesDistribution.besselratio( @@ -148,4 +143,4 @@ def from_moment(m): return vm def __str__(self) -> str: - return f"VonMisesDistribution: mu = {self.mu}, kappa = {self.kappa}" + return f"VonMisesDistribution: mu = {self.mu}, kappa = {self.kappa}" \ No newline at end of file diff --git a/pyrecest/distributions/circle/wrapped_cauchy_distribution.py b/pyrecest/distributions/circle/wrapped_cauchy_distribution.py index b88ee4a9..3ea26fbf 100644 --- a/pyrecest/distributions/circle/wrapped_cauchy_distribution.py +++ b/pyrecest/distributions/circle/wrapped_cauchy_distribution.py @@ -37,4 +37,4 @@ def coth(x): def trigonometric_moment(self, n): m = exp(1j * n * self.mu - abs(n) * self.gamma) - return m + return m \ No newline at end of file diff --git a/pyrecest/distributions/circle/wrapped_laplace_distribution.py b/pyrecest/distributions/circle/wrapped_laplace_distribution.py index 45bede0d..27e567f6 100644 --- a/pyrecest/distributions/circle/wrapped_laplace_distribution.py +++ b/pyrecest/distributions/circle/wrapped_laplace_distribution.py @@ -37,4 +37,4 @@ def pdf(self, xs): / (exp(2 * np.pi * self.lambda_ / self.kappa) - 1) ) ) - return p + return p \ No newline at end of file diff --git a/pyrecest/distributions/circle/wrapped_normal_distribution.py b/pyrecest/distributions/circle/wrapped_normal_distribution.py index 0f1282b5..1f403352 100644 --- a/pyrecest/distributions/circle/wrapped_normal_distribution.py +++ b/pyrecest/distributions/circle/wrapped_normal_distribution.py @@ -1,3 +1,4 @@ +from typing import Union from pyrecest.backend import where from pyrecest.backend import squeeze from pyrecest.backend import sqrt @@ -32,7 +33,6 @@ class WrappedNormalDistribution( MAX_SIGMA_BEFORE_UNIFORM = 10 - @beartype def __init__( self, mu: np.number | numbers.Real | np.ndarray, @@ -48,7 +48,6 @@ def __init__( def sigma(self): return sqrt(self.C) - @beartype def pdf(self, xs: np.ndarray | np.number | numbers.Real): if self.sigma <= 0: raise ValueError(f"sigma must be >0, but received {self.sigma}.") @@ -92,12 +91,11 @@ def pdf(self, xs: np.ndarray | np.number | numbers.Real): return result.squeeze() - @beartype def cdf( self, xs: np.ndarray, startingPoint: float = 0, - n_wraps: int | int32 | int64 = 10, + n_wraps: Union[int, int32, int64] = 10, ) -> np.ndarray: startingPoint = mod(startingPoint, 2 * np.pi) xs = mod(xs, 2 * np.pi) @@ -123,9 +121,8 @@ def ncdf(from_, to): val = where(xs < startingPoint, 1 + val, val) return squeeze(val) - @beartype def trigonometric_moment( - self, n: int | int32 | int64 + self, n: Union[int, int32, int64] ) -> complex | np.ndarray: return exp(1j * n * self.mu - n**2 * self.sigma**2 / 2) @@ -141,11 +138,9 @@ def multiply_vm(self, other): wn = vm.to_wn() return wn - @beartype - def sample(self, n: int | int32 | int64) -> np.ndarray: + def sample(self, n: Union[int, int32, int64]) -> np.ndarray: return mod(self.mu + self.sigma * np.random.randn(1, n), 2 * np.pi) - @beartype def shift(self, shift_by): assert np.isscalar(shift_by) return WrappedNormalDistribution(self.mu + shift_by, self.sigma) @@ -164,4 +159,4 @@ def from_moment(m: complex) -> "WrappedNormalDistribution": @staticmethod def sigma_to_kappa(sigma): # Approximate conversion from sigma to kappa for a Von Mises distribution - return 1 / sigma**2 + return 1 / sigma**2 \ No newline at end of file diff --git a/pyrecest/distributions/conditional/abstract_conditional_distribution.py b/pyrecest/distributions/conditional/abstract_conditional_distribution.py index 84002112..2dc392d2 100644 --- a/pyrecest/distributions/conditional/abstract_conditional_distribution.py +++ b/pyrecest/distributions/conditional/abstract_conditional_distribution.py @@ -2,4 +2,4 @@ class AbstractConditionalDistribution(ABC): - pass + pass \ No newline at end of file diff --git a/pyrecest/distributions/custom_hyperrectangular_distribution.py b/pyrecest/distributions/custom_hyperrectangular_distribution.py index 0c5e56f2..c47fe883 100644 --- a/pyrecest/distributions/custom_hyperrectangular_distribution.py +++ b/pyrecest/distributions/custom_hyperrectangular_distribution.py @@ -14,11 +14,9 @@ class CustomHyperrectangularDistribution( AbstractHyperrectangularDistribution, AbstractCustomNonPeriodicDistribution ): - @beartype def __init__(self, f: Callable, bounds: np.ndarray): AbstractHyperrectangularDistribution.__init__(self, bounds) AbstractCustomNonPeriodicDistribution.__init__(self, f) - @beartype def pdf(self, xs: np.ndarray) -> np.ndarray: - return AbstractCustomNonPeriodicDistribution.pdf(self, xs) + return AbstractCustomNonPeriodicDistribution.pdf(self, xs) \ No newline at end of file diff --git a/pyrecest/distributions/disk_uniform_distribution.py b/pyrecest/distributions/disk_uniform_distribution.py index d7d944c3..0c2eb702 100644 --- a/pyrecest/distributions/disk_uniform_distribution.py +++ b/pyrecest/distributions/disk_uniform_distribution.py @@ -21,4 +21,4 @@ def __init__(self): The center of the disk is at [0, 0] and the shape matrix of the ellipsoid is an identity covariance matrix. """ AbstractDiskDistribution.__init__(self) - EllipsoidalBallUniformDistribution.__init__(self, array([0, 0]), eye(2)) + EllipsoidalBallUniformDistribution.__init__(self, array([0, 0]), eye(2)) \ No newline at end of file diff --git a/pyrecest/distributions/ellipsoidal_ball_uniform_distribution.py b/pyrecest/distributions/ellipsoidal_ball_uniform_distribution.py index eeff5efc..5bb69d44 100644 --- a/pyrecest/distributions/ellipsoidal_ball_uniform_distribution.py +++ b/pyrecest/distributions/ellipsoidal_ball_uniform_distribution.py @@ -1,3 +1,4 @@ +from typing import Union from pyrecest.backend import sqrt from pyrecest.backend import power from pyrecest.backend import dot @@ -34,7 +35,6 @@ def input_dim(self) -> int: def mean(self): raise NotImplementedError() - @beartype def pdf(self, xs: np.ndarray): """ Compute the probability density function at given points. @@ -64,8 +64,7 @@ def pdf(self, xs: np.ndarray): return results - @beartype - def sample(self, n: int | int32 | int64) -> np.ndarray: + def sample(self, n: Union[int, int32, int64]) -> np.ndarray: """ Generate samples from the distribution. @@ -88,4 +87,4 @@ def sample(self, n: int | int32 | int64) -> np.ndarray: # For points (d, n), this would be L @ random_points transformed_points = random_points @ L.T + self.center.reshape(1, -1) - return transformed_points + return transformed_points \ No newline at end of file diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hemispherical_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hemispherical_distribution.py index 92393dc2..b01badd9 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hemispherical_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hemispherical_distribution.py @@ -18,4 +18,4 @@ def __init__(self): Initializes a new instance of the AbstractHemisphericalDistribution class. """ AbstractSphereSubsetDistribution.__init__(self) - AbstractHyperhemisphericalDistribution.__init__(self, dim=2) + AbstractHyperhemisphericalDistribution.__init__(self, dim=2) \ No newline at end of file diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py index 6f4334be..507bdf30 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py @@ -1,3 +1,4 @@ +from typing import Union from pyrecest.backend import vstack from pyrecest.backend import ones from pyrecest.backend import meshgrid @@ -20,7 +21,6 @@ class AbstractHyperhemisphericalDistribution(AbstractHypersphereSubsetDistribution): - @beartype def mean(self) -> np.ndarray: """ Convenient access to axis to have a consistent interface @@ -32,12 +32,11 @@ def mean(self) -> np.ndarray: return self.mean_axis() # jscpd:ignore-start - @beartype def sample_metropolis_hastings( self, - n: int | int32 | int64, - burn_in: int | int32 | int64 = 10, - skipping: int | int32 | int64 = 5, + n: Union[int, int32, int64], + burn_in: Union[int, int32, int64] = 10, + skipping: Union[int, int32, int64] = 5, proposal: Callable | None = None, start_point: np.ndarray | None = None, ) -> np.ndarray: @@ -58,7 +57,6 @@ def proposal(_): n, burn_in, skipping, proposal=proposal, start_point=start_point ) - @beartype def mean_direction_numerical(self) -> np.ndarray: warning_msg = ( "The result is the mean direction on the upper hemisphere along the last dimension. " @@ -96,9 +94,8 @@ def mean_direction_numerical(self) -> np.ndarray: mu = mu / np.linalg.norm(mu) return mu - @beartype @staticmethod - def get_full_integration_boundaries(dim: int | int32 | int64) -> np.ndarray: + def get_full_integration_boundaries(dim: Union[int, int32, int64]) -> np.ndarray: if dim == 1: integration_boundaries = [0, np.pi] else: @@ -112,7 +109,6 @@ def get_full_integration_boundaries(dim: int | int32 | int64) -> np.ndarray: ).T return integration_boundaries - @beartype def integrate(self, integration_boundaries: np.ndarray | None = None) -> float: if integration_boundaries is None: integration_boundaries = ( @@ -122,7 +118,6 @@ def integrate(self, integration_boundaries: np.ndarray | None = None) -> float: ) return super().integrate(integration_boundaries) - @beartype def integrate_numerically( self, integration_boundaries: np.ndarray | None = None ) -> float: @@ -134,10 +129,9 @@ def integrate_numerically( ) return super().integrate_numerically(integration_boundaries) - @beartype @staticmethod def integrate_fun_over_domain( - f_hypersph_coords: Callable, dim: int | int32 | int64 + f_hypersph_coords: Callable, dim: Union[int, int32, int64] ) -> float: integration_boundaries = ( AbstractHyperhemisphericalDistribution.get_full_integration_boundaries(dim) @@ -146,7 +140,6 @@ def integrate_fun_over_domain( f_hypersph_coords, dim, integration_boundaries ) - @beartype def mode_numerical(self) -> np.ndarray: def objective_function_2d(s): return -self.pdf(AbstractHypersphereSubsetDistribution.polar_to_cart(s)) @@ -166,9 +159,8 @@ def objective_function_2d(s): m = AbstractHypersphereSubsetDistribution.polar_to_cart(result.x) return (1 - 2 * (m[-1] < 0)) * m - @beartype @staticmethod - def plot_hemisphere(resolution: int | int32 | int64 = 150): + def plot_hemisphere(resolution: Union[int, int32, int64] = 150): x, y, z = meshgrid( linspace(-1, 1, resolution), linspace(-1, 1, resolution), @@ -187,4 +179,4 @@ def get_manifold_size(self): * AbstractHypersphereSubsetDistribution.compute_unit_hypersphere_surface( self.dim ) - ) + ) \ No newline at end of file diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_dirac_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_dirac_distribution.py index 878fa9b4..2a059dee 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_dirac_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_dirac_distribution.py @@ -24,4 +24,4 @@ def entropy(self): return result def integrate(self, integration_boundaries=None): - raise NotImplementedError() + raise NotImplementedError() \ No newline at end of file diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py index b7ea7a84..29ec50d2 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py @@ -1,3 +1,4 @@ +from typing import Union from pyrecest.backend import sort from pyrecest.backend import squeeze from pyrecest.backend import sqrt @@ -29,8 +30,7 @@ def mean_direction(self): @staticmethod @abstractmethod - @beartype - def get_full_integration_boundaries(dim: int | int32 | int64): + def get_full_integration_boundaries(dim: Union[int, int32, int64]): pass def mean_direction_numerical(self, integration_boundaries=None): @@ -91,8 +91,7 @@ def gen_pdf_hyperspherical_coords(self): ) @staticmethod - @beartype - def gen_fun_hyperspherical_coords(f: Callable, dim: int | int32 | int64): + def gen_fun_hyperspherical_coords(f: Callable, dim: Union[int, int32, int64]): def generate_input(angles): dim_eucl = dim + 1 angles = np.column_stack(angles) @@ -169,7 +168,6 @@ def g_3d(phi1, phi2, phi3): return m @staticmethod - @beartype def _compute_mean_axis_from_moment(moment_matrix: np.ndarray) -> np.ndarray: D, V = np.linalg.eig(moment_matrix) Dsorted = sort(D) @@ -182,17 +180,14 @@ def _compute_mean_axis_from_moment(moment_matrix: np.ndarray) -> np.ndarray: m = -Vsorted[:, -1] return m - @beartype def mean_axis(self) -> np.ndarray: mom = self.moment() return AbstractHypersphereSubsetDistribution._compute_mean_axis_from_moment(mom) - @beartype def mean_axis_numerical(self) -> np.ndarray: mom = self.moment_numerical() return AbstractHypersphereSubsetDistribution._compute_mean_axis_from_moment(mom) - @beartype def integrate(self, integration_boundaries: np.ndarray | None = None): if integration_boundaries is None: integration_boundaries = self.__class__.get_full_integration_boundaries( @@ -202,18 +197,16 @@ def integrate(self, integration_boundaries: np.ndarray | None = None): @staticmethod @abstractmethod - @beartype def integrate_fun_over_domain( - f_hypersph_coords: Callable, dim: int | int32 | int64 + f_hypersph_coords: Callable, dim: Union[int, int32, int64] ): # Overwrite with a function that specifies the integration_boundaries for the type of HypersphereSubsetDistribution pass @staticmethod - @beartype def integrate_fun_over_domain_part( f_hypersph_coords: Callable, - dim: int | int32 | int64, + dim: Union[int, int32, int64], integration_boundaries, ): if dim == 1: @@ -346,7 +339,6 @@ def total_variation_distance(pdf1, pdf2): return 0.5 * distance_integral @staticmethod - @beartype def polar_to_cart(polar_coords: np.ndarray) -> np.ndarray: polar_coords = np.atleast_2d(polar_coords) @@ -365,8 +357,7 @@ def polar_to_cart(polar_coords: np.ndarray) -> np.ndarray: return squeeze(coords) @staticmethod - @beartype - def compute_unit_hypersphere_surface(dim: int | int32 | int64) -> float: + def compute_unit_hypersphere_surface(dim: Union[int, int32, int64]) -> float: if dim == 1: surface_area = 2 * np.pi elif dim == 2: @@ -375,4 +366,4 @@ def compute_unit_hypersphere_surface(dim: int | int32 | int64) -> float: surface_area = 2 * np.pi**2 else: surface_area = 2 * np.pi ** ((dim + 1) / 2) / gamma((dim + 1) / 2) - return surface_area + return surface_area \ No newline at end of file diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_uniform_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_uniform_distribution.py index 47f53668..fb2c04f6 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_uniform_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_uniform_distribution.py @@ -15,7 +15,6 @@ class AbstractHypersphereSubsetUniformDistribution( This is an abstract class for a uniform distribution over a subset of a hypersphere. """ - @beartype def pdf(self, xs: np.ndarray) -> np.ndarray: """ Calculates the probability density function over the subset of the hypersphere. @@ -34,4 +33,4 @@ def pdf(self, xs: np.ndarray) -> np.ndarray: if not isinstance(manifold_size, (int, float)): raise TypeError("Manifold size must be a numeric value.") p = (1 / manifold_size) * ones(xs.size // (self.dim + 1)) - return p + return p \ No newline at end of file diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py index ff8eba8e..2391095f 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py @@ -1,3 +1,4 @@ +from typing import Union from pyrecest.backend import vstack from pyrecest.backend import sin from pyrecest.backend import ones @@ -37,12 +38,11 @@ def mean(self): return self.mean_direction() # jscpd:ignore-start - @beartype def sample_metropolis_hastings( self, - n: int | int32 | int64, - burn_in: int | int32 | int64 = 10, - skipping: int | int32 | int64 = 5, + n: Union[int, int32, int64], + burn_in: Union[int, int32, int64] = 10, + skipping: Union[int, int32, int64] = 5, proposal: Callable | None = None, start_point: np.ndarray | None = None, ) -> np.ndarray: @@ -81,11 +81,10 @@ def proposal(_): start_point=start_point, ) - @beartype def plot( self, - faces: int | int32 | int64 = 100, - grid_faces: int | int32 | int64 = 20, + faces: Union[int, int32, int64] = 100, + grid_faces: Union[int, int32, int64] = 20, ) -> None: if self.dim == 1: phi = linspace(0, 2 * np.pi, 320) @@ -151,7 +150,6 @@ def plot( "Cannot plot hyperspherical distribution with this number of dimensions." ) - @beartype def moment(self) -> np.ndarray: return self.moment_numerical() @@ -186,7 +184,6 @@ def integrate_numerically(self, integration_boundaries=None): def entropy(self): return super().entropy_numerical() - @beartype def mode_numerical(self) -> np.ndarray: def fun(s): return -self.pdf(AbstractHypersphereSubsetDistribution.polar_to_cart(s)) @@ -204,7 +201,6 @@ def fun(s): def hellinger_distance(self, other): return super().hellinger_distance_numerical(other) - @beartype def total_variation_distance(self, other: "AbstractHypersphericalDistribution"): return super().total_variation_distance_numerical(other) @@ -260,4 +256,4 @@ def plot_unit_sphere(): def get_manifold_size(self): return AbstractHypersphereSubsetDistribution.compute_unit_hypersphere_surface( self.dim - ) + ) \ No newline at end of file diff --git a/pyrecest/distributions/hypersphere_subset/abstract_sphere_subset_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_sphere_subset_distribution.py index 87c87186..f27b8d7c 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_sphere_subset_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_sphere_subset_distribution.py @@ -24,7 +24,6 @@ def __init__(self): super().__init__(2) @staticmethod - @beartype def sph_to_cart(phi: np.ndarray, theta: np.ndarray, mode="colatitude") -> tuple: """ Convert spherical coordinates to Cartesian coordinates. @@ -52,7 +51,6 @@ def sph_to_cart(phi: np.ndarray, theta: np.ndarray, mode="colatitude") -> tuple: return x, y, z @staticmethod - @beartype def cart_to_sph( x: np.ndarray, y: np.ndarray, z: np.ndarray, mode="colatitude" ) -> tuple: @@ -84,7 +82,6 @@ def cart_to_sph( return phi, theta @staticmethod - @beartype def _sph_to_cart_colatitude(azimuth: np.ndarray, colatitude: np.ndarray) -> tuple: assert ndim(azimuth) == 1 and ndim( colatitude @@ -95,7 +92,6 @@ def _sph_to_cart_colatitude(azimuth: np.ndarray, colatitude: np.ndarray) -> tupl return x, y, z @staticmethod - @beartype def _sph_to_cart_elevation(azimuth: np.ndarray, elevation: np.ndarray) -> tuple: """ Convert spherical coordinates (using elevation) to Cartesian coordinates. @@ -119,7 +115,6 @@ def _sph_to_cart_elevation(azimuth: np.ndarray, elevation: np.ndarray) -> tuple: return x, y, z @staticmethod - @beartype def _cart_to_sph_colatitude(x: np.ndarray, y: np.ndarray, z: np.ndarray) -> tuple: assert ndim(x) == 1 and ndim(y) == 1 and ndim(z) radius = 1 @@ -129,11 +124,10 @@ def _cart_to_sph_colatitude(x: np.ndarray, y: np.ndarray, z: np.ndarray) -> tupl return azimuth, colatitude @staticmethod - @beartype def _cart_to_sph_elevation(x: np.ndarray, y: np.ndarray, z: np.ndarray) -> tuple: assert ndim(x) == 1 and ndim(y) == 1 and ndim(z) == 1 radius = 1 azimuth = arctan2(y, x) azimuth = where(azimuth < 0, azimuth + 2 * np.pi, azimuth) elevation = np.pi / 2 - arccos(z / radius) # elevation is π/2 - colatitude - return azimuth, elevation + return azimuth, elevation \ No newline at end of file diff --git a/pyrecest/distributions/hypersphere_subset/abstract_spherical_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_spherical_distribution.py index 74b2e341..e5d90c2a 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_spherical_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_spherical_distribution.py @@ -7,4 +7,4 @@ class AbstractSphericalDistribution( ): def __init__(self): AbstractSphereSubsetDistribution.__init__(self) - AbstractHypersphericalDistribution.__init__(self, dim=2) + AbstractHypersphericalDistribution.__init__(self, dim=2) \ No newline at end of file diff --git a/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py index 4fb2b11d..0aa4b4f0 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py @@ -101,4 +101,4 @@ def truncate(self, degree): new_coeff_mat[i, 2 * i + 1 :] = np.nan # noqa: E203 result.coeff_mat = new_coeff_mat - return result + return result \ No newline at end of file diff --git a/pyrecest/distributions/hypersphere_subset/bingham_distribution.py b/pyrecest/distributions/hypersphere_subset/bingham_distribution.py index bde76db7..53239842 100644 --- a/pyrecest/distributions/hypersphere_subset/bingham_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/bingham_distribution.py @@ -127,4 +127,4 @@ def moment(self): D = D / sum(np.diag(D)) S = self.M @ D @ self.M.T S = (S + S.T) / 2 # Enforce symmetry - return S + return S \ No newline at end of file diff --git a/pyrecest/distributions/hypersphere_subset/custom_hemispherical_distribution.py b/pyrecest/distributions/hypersphere_subset/custom_hemispherical_distribution.py index b62a2ab9..1abb5634 100644 --- a/pyrecest/distributions/hypersphere_subset/custom_hemispherical_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/custom_hemispherical_distribution.py @@ -15,13 +15,11 @@ class CustomHemisphericalDistribution( CustomHyperhemisphericalDistribution, AbstractHemisphericalDistribution ): - @beartype def __init__(self, f: Callable): AbstractHemisphericalDistribution.__init__(self) CustomHyperhemisphericalDistribution.__init__(self, f, 2) @staticmethod - @beartype def from_distribution(distribution: "AbstractHypersphericalDistribution"): if distribution.dim != 2: raise ValueError("Dimension of the distribution should be 2.") @@ -46,4 +44,4 @@ def from_distribution(distribution: "AbstractHypersphericalDistribution"): chsd.scale_by = 1 / norm_const_inv return chsd - raise ValueError("Input variable dist is of wrong class.") + raise ValueError("Input variable dist is of wrong class.") \ No newline at end of file diff --git a/pyrecest/distributions/hypersphere_subset/custom_hyperhemispherical_distribution.py b/pyrecest/distributions/hypersphere_subset/custom_hyperhemispherical_distribution.py index d097536e..932c9a93 100644 --- a/pyrecest/distributions/hypersphere_subset/custom_hyperhemispherical_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/custom_hyperhemispherical_distribution.py @@ -1,3 +1,4 @@ +from typing import Union from pyrecest.backend import int64 from pyrecest.backend import int32 from collections.abc import Callable @@ -16,9 +17,8 @@ class CustomHyperhemisphericalDistribution( AbstractCustomDistribution, AbstractHyperhemisphericalDistribution ): - @beartype def __init__( - self, f: Callable, dim: int | int32 | int64, scale_by: float = 1 + self, f: Callable, dim: Union[int, int32, int64], scale_by: float = 1 ): """ Initialize a CustomHyperhemisphericalDistribution. @@ -30,7 +30,6 @@ def __init__( AbstractHyperhemisphericalDistribution.__init__(self, dim=dim) AbstractCustomDistribution.__init__(self, f=f, scale_by=scale_by) - @beartype def pdf(self, xs): """ Calculate the probability density function at given points. @@ -55,7 +54,6 @@ def integrate(self, integration_boundaries=None): ) @staticmethod - @beartype def from_distribution(distribution: "AbstractHypersphericalDistribution"): """ Create a CustomHyperhemisphericalDistribution from another distribution. @@ -85,4 +83,4 @@ def from_distribution(distribution: "AbstractHypersphericalDistribution"): distribution.pdf / norm_const_inv, distribution.dim ) - raise ValueError("Input variable distribution is of the wrong class.") + raise ValueError("Input variable distribution is of the wrong class.") \ No newline at end of file diff --git a/pyrecest/distributions/hypersphere_subset/custom_hyperspherical_distribution.py b/pyrecest/distributions/hypersphere_subset/custom_hyperspherical_distribution.py index e32e2251..50317bca 100644 --- a/pyrecest/distributions/hypersphere_subset/custom_hyperspherical_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/custom_hyperspherical_distribution.py @@ -19,4 +19,4 @@ def from_distribution(distribution): def integrate(self, integration_boundaries=None): return AbstractHypersphericalDistribution.integrate( self, integration_boundaries - ) + ) \ No newline at end of file diff --git a/pyrecest/distributions/hypersphere_subset/hemispherical_uniform_distribution.py b/pyrecest/distributions/hypersphere_subset/hemispherical_uniform_distribution.py index 7742a943..bcc3125c 100644 --- a/pyrecest/distributions/hypersphere_subset/hemispherical_uniform_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/hemispherical_uniform_distribution.py @@ -7,4 +7,4 @@ class HemisphericalUniformDistribution( AbstractHypersphereSubsetUniformDistribution, AbstractHemisphericalDistribution ): - pass + pass \ No newline at end of file diff --git a/pyrecest/distributions/hypersphere_subset/hyperhemispherical_dirac_distribution.py b/pyrecest/distributions/hypersphere_subset/hyperhemispherical_dirac_distribution.py index 6be43cd0..76cf9127 100644 --- a/pyrecest/distributions/hypersphere_subset/hyperhemispherical_dirac_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/hyperhemispherical_dirac_distribution.py @@ -9,4 +9,4 @@ class HyperhemisphericalDiracDistribution( AbstractHypersphereSubsetDiracDistribution, AbstractHyperhemisphericalDistribution ): - pass + pass \ No newline at end of file diff --git a/pyrecest/distributions/hypersphere_subset/hyperhemispherical_uniform_distribution.py b/pyrecest/distributions/hypersphere_subset/hyperhemispherical_uniform_distribution.py index 51f6b6c7..025d36d4 100644 --- a/pyrecest/distributions/hypersphere_subset/hyperhemispherical_uniform_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/hyperhemispherical_uniform_distribution.py @@ -1,3 +1,4 @@ +from typing import Union from pyrecest.backend import int64 from pyrecest.backend import int32 import numpy as np @@ -18,8 +19,7 @@ class HyperhemisphericalUniformDistribution( AbstractHyperhemisphericalDistribution, AbstractHypersphereSubsetUniformDistribution ): - @beartype - def sample(self, n: int | int32 | int64) -> np.ndarray: + def sample(self, n: Union[int, int32, int64]) -> np.ndarray: """ Sample n points from the hyperhemispherical distribution. @@ -49,4 +49,4 @@ def get_manifold_size(self) -> float: self.dim ) / 2 - ) + ) \ No newline at end of file diff --git a/pyrecest/distributions/hypersphere_subset/hyperhemispherical_watson_distribution.py b/pyrecest/distributions/hypersphere_subset/hyperhemispherical_watson_distribution.py index 180c0d3b..854136ab 100644 --- a/pyrecest/distributions/hypersphere_subset/hyperhemispherical_watson_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/hyperhemispherical_watson_distribution.py @@ -1,3 +1,4 @@ +from typing import Union from pyrecest.backend import allclose from pyrecest.backend import all from pyrecest.backend import int64 @@ -15,7 +16,6 @@ class HyperhemisphericalWatsonDistribution(AbstractHyperhemisphericalDistribution): - @beartype def __init__(self, mu: np.ndarray, kappa: np.number | numbers.Real): assert mu[-1] >= 0 self.dist_full_sphere = WatsonDistribution(mu, kappa) @@ -26,14 +26,12 @@ def __init__(self, mu: np.ndarray, kappa: np.number | numbers.Real): def pdf(self, xs): return 2 * self.dist_full_sphere.pdf(xs) - @beartype def set_mode(self, mu: np.ndarray) -> "HyperhemisphericalWatsonDistribution": w = self w.mu = mu return w - @beartype - def sample(self, n: int | int32 | int64) -> np.ndarray: + def sample(self, n: Union[int, int32, int64]) -> np.ndarray: s_full = self.dist_full_sphere.sample(n) s = s_full * (-1) ** (s_full[-1] < 0) # Mirror to upper hemisphere return s @@ -43,7 +41,6 @@ def mu(self) -> np.ndarray: return self.dist_full_sphere.mu @mu.setter - @beartype def mu(self, mu: np.ndarray): self.dist_full_sphere.mu = mu @@ -52,18 +49,16 @@ def kappa(self) -> float: return self.dist_full_sphere.kappa @kappa.setter - @beartype def kappa(self, kappa: float): self.dist_full_sphere.kappa = kappa def mode(self) -> np.ndarray: return self.mu - @beartype def shift(self, shift_by) -> "HyperhemisphericalWatsonDistribution": assert allclose( self.mu, np.append(zeros(self.dim - 1), 1) ), "There is no true shifting for the hyperhemisphere. This is a function for compatibility and only works when mu is [0,0,...,1]." dist_shifted = self dist_shifted.mu = shift_by - return dist_shifted + return dist_shifted \ No newline at end of file diff --git a/pyrecest/distributions/hypersphere_subset/hyperspherical_dirac_distribution.py b/pyrecest/distributions/hypersphere_subset/hyperspherical_dirac_distribution.py index eed89550..b335fd4b 100644 --- a/pyrecest/distributions/hypersphere_subset/hyperspherical_dirac_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/hyperspherical_dirac_distribution.py @@ -37,4 +37,4 @@ def to_circular_dirac_distribution(self): def mean_direction(self): vec_sum = sum(self.d * reshape(self.w, (-1, 1)), axis=0) mu = vec_sum / np.linalg.norm(vec_sum) - return mu + return mu \ No newline at end of file diff --git a/pyrecest/distributions/hypersphere_subset/hyperspherical_mixture.py b/pyrecest/distributions/hypersphere_subset/hyperspherical_mixture.py index c18116b1..1204288a 100644 --- a/pyrecest/distributions/hypersphere_subset/hyperspherical_mixture.py +++ b/pyrecest/distributions/hypersphere_subset/hyperspherical_mixture.py @@ -10,7 +10,6 @@ class HypersphericalMixture(AbstractMixture, AbstractHypersphericalDistribution) A class used to represent a mixture of hyperspherical distributions. """ - @beartype def __init__( self, dists: list[AbstractHypersphericalDistribution], @@ -28,4 +27,4 @@ def __init__( isinstance(dist, AbstractHypersphericalDistribution) for dist in dists ), "dists must be a list of hyperspherical distributions" - AbstractMixture.__init__(self, dists, w) + AbstractMixture.__init__(self, dists, w) \ No newline at end of file diff --git a/pyrecest/distributions/hypersphere_subset/hyperspherical_uniform_distribution.py b/pyrecest/distributions/hypersphere_subset/hyperspherical_uniform_distribution.py index 50d1ddf2..3969ca50 100644 --- a/pyrecest/distributions/hypersphere_subset/hyperspherical_uniform_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/hyperspherical_uniform_distribution.py @@ -1,3 +1,4 @@ +from typing import Union from pyrecest.backend import sqrt from pyrecest.backend import sin from pyrecest.backend import cos @@ -16,16 +17,13 @@ class HypersphericalUniformDistribution( AbstractHypersphericalDistribution, AbstractHypersphereSubsetUniformDistribution ): - @beartype - def __init__(self, dim: int | int32 | int64): + def __init__(self, dim: Union[int, int32, int64]): AbstractHypersphereSubsetUniformDistribution.__init__(self, dim) - @beartype def pdf(self, xs: np.ndarray): return AbstractHypersphereSubsetUniformDistribution.pdf(self, xs) - @beartype - def sample(self, n: int | int32 | int64): + def sample(self, n: Union[int, int32, int64]): assert isinstance(n, int) and n > 0, "n must be a positive integer" if self.dim == 2: @@ -46,4 +44,4 @@ def sample(self, n: int | int32 | int64): return s def get_manifold_size(self): - return AbstractHypersphericalDistribution.get_manifold_size(self) + return AbstractHypersphericalDistribution.get_manifold_size(self) \ No newline at end of file diff --git a/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py b/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py index 2a17bb3b..6fd36c84 100644 --- a/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py +++ b/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py @@ -180,4 +180,4 @@ def imag_part(phi, theta, n, m): coeff_mat[n, m + n] = real_integral + 1j * imag_integral - return SphericalHarmonicsDistributionComplex(coeff_mat, transformation) + return SphericalHarmonicsDistributionComplex(coeff_mat, transformation) \ No newline at end of file diff --git a/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_real.py b/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_real.py index f316d4d4..3803b655 100644 --- a/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_real.py +++ b/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_real.py @@ -78,4 +78,4 @@ def to_spherical_harmonics_distribution_complex(self): return SphericalHarmonicsDistributionComplex( complex_coeff_mat, self.transformation - ) + ) \ No newline at end of file diff --git a/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py b/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py index 8fd3d915..b0842162 100644 --- a/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py @@ -1,3 +1,4 @@ +from typing import Union from pyrecest.backend import sinh from pyrecest.backend import sin from pyrecest.backend import ndim @@ -20,7 +21,6 @@ class VonMisesFisherDistribution(AbstractHypersphericalDistribution): - @beartype def __init__(self, mu: np.ndarray, kappa: np.number | numbers.Real): AbstractHypersphericalDistribution.__init__(self, dim=mu.shape[0] - 1) epsilon = 1e-6 @@ -39,7 +39,6 @@ def __init__(self, mu: np.ndarray, kappa: np.number | numbers.Real): (2 * np.pi) ** ((self.dim + 1) / 2) * iv((self.dim + 1) / 2 - 1, kappa) ) - @beartype def pdf(self, xs: np.ndarray | np.number) -> np.ndarray | np.number: assert xs.shape[-1] == self.input_dim @@ -93,7 +92,6 @@ def get_rotation_matrix(self): Q = -Q return Q - @beartype def moment(self) -> np.ndarray: """ Returns the mean resultant vector. @@ -102,7 +100,6 @@ def moment(self) -> np.ndarray: return r @staticmethod - @beartype def from_distribution(d: AbstractHypersphericalDistribution): assert d.input_dim >= 2, "mu must be at least 2-D for the circular case" @@ -110,7 +107,6 @@ def from_distribution(d: AbstractHypersphericalDistribution): return VonMisesFisherDistribution.from_moment(m) @staticmethod - @beartype def from_moment(m: np.ndarray): assert ndim(m) == 1, "mu must be a vector" assert len(m) >= 2, "mu must be at least 2 for the circular case" @@ -125,14 +121,12 @@ def from_moment(m: np.ndarray): def mode(self): return self.mu - @beartype def set_mode(self, new_mode: np.ndarray): assert new_mode.shape == self.mu.shape dist = self dist.mu = new_mode return dist - @beartype def multiply(self, other: "VonMisesFisherDistribution"): assert self.mu.shape == other.mu.shape @@ -141,7 +135,6 @@ def multiply(self, other: "VonMisesFisherDistribution"): mu_ = mu_ / kappa_ return VonMisesFisherDistribution(mu_, kappa_) - @beartype def convolve(self, other: "VonMisesFisherDistribution"): assert other.mu[-1] == 1, "Other is not zonal" assert all(self.mu.shape == other.mu.shape) @@ -156,8 +149,7 @@ def convolve(self, other: "VonMisesFisherDistribution"): return VonMisesFisherDistribution(mu_, kappa_) @staticmethod - @beartype - def a_d(d: int | int32 | int64, kappa: np.number | numbers.Real): + def a_d(d: Union[int, int32, int64], kappa: np.number | numbers.Real): bessel1 = iv(d / 2, kappa) bessel2 = iv(d / 2 - 1, kappa) if isnan(bessel1) or isnan(bessel2): @@ -165,8 +157,7 @@ def a_d(d: int | int32 | int64, kappa: np.number | numbers.Real): return bessel1 / bessel2 @staticmethod - @beartype - def a_d_inverse(d: int | int32 | int64, x: float): + def a_d_inverse(d: Union[int, int32, int64], x: float): kappa_ = x * (d - x**2) / (1 - x**2) if isnan(kappa_): print(f"Initial kappa_ is NaN for d={d}, x={x}") @@ -194,4 +185,4 @@ def a_d_inverse(d: int | int32 | int64, x: float): if abs(kappa_ - kappa_old) < epsilon: break - return kappa_ + return kappa_ \ No newline at end of file diff --git a/pyrecest/distributions/hypersphere_subset/watson_distribution.py b/pyrecest/distributions/hypersphere_subset/watson_distribution.py index 96737a95..c99dac36 100644 --- a/pyrecest/distributions/hypersphere_subset/watson_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/watson_distribution.py @@ -22,7 +22,6 @@ class WatsonDistribution(AbstractHypersphericalDistribution): EPSILON = 1e-6 - @beartype def __init__(self, mu: np.ndarray, kappa: np.number | numbers.Real): """ Initializes a new instance of the WatsonDistribution class. @@ -43,7 +42,7 @@ def __init__(self, mu: np.ndarray, kappa: np.number | numbers.Real): / (2 * mpmath.pi ** ((self.dim + 1) / 2)) / mpmath.hyper([0.5], [(self.dim + 1) / 2.0], self.kappa) ) - self.C = float64(C_mpf) + self.C = array(float(C_mpf)) def pdf(self, xs): """ @@ -94,4 +93,4 @@ def set_mode(self, new_mode): def shift(self, shift_by): np.testing.assert_almost_equal(self.mu, vstack([zeros((self.dim, 1)), 1]), "There is no true shifting for the hypersphere. This is a function for compatibility and only works when mu is [0,0,...,1].") - return self.set_mode(shift_by) + return self.set_mode(shift_by) \ No newline at end of file diff --git a/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py b/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py index d8122a9d..b1b576eb 100644 --- a/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py +++ b/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py @@ -1,3 +1,4 @@ +from typing import Union from pyrecest.backend import vstack from pyrecest.backend import sqrt from pyrecest.backend import sin @@ -37,8 +38,7 @@ def input_dim(self) -> int: return self.dim @staticmethod - @beartype - def integrate_fun_over_domain(f: Callable, dim: int | int32 | int64) -> float: + def integrate_fun_over_domain(f: Callable, dim: Union[int, int32, int64]) -> float: integration_boundaries = [(0, 2 * np.pi)] * dim return AbstractHypertoroidalDistribution.integrate_fun_over_domain_part( f, dim, integration_boundaries @@ -72,9 +72,8 @@ def shifted_pdf(xs): return shifted_distribution @staticmethod - @beartype def integrate_fun_over_domain_part( - f: Callable, dim: int | int32 | int64, integration_boundaries + f: Callable, dim: Union[int, int32, int64], integration_boundaries ) -> float: if len(integration_boundaries) != dim: raise ValueError( @@ -99,9 +98,8 @@ def integrate_numerically( lambda *args: self.pdf(array(args)), self.dim, integration_boundaries ) - @beartype def trigonometric_moment_numerical( - self, n: int | int32 | int64 + self, n: Union[int, int32, int64] ) -> np.ndarray: """Calculates the complex trignometric moments. Since nquad does not support complex functions, the calculation is split up (as used in the alternative representation of trigonometric polonymials @@ -238,8 +236,7 @@ def mode_numerical(self) -> np.ndarray: # Implement the optimization function fminunc equivalent in Python (e.g., using scipy.optimize.minimize) raise NotImplementedError("Mode calculation is not implemented") - @beartype - def trigonometric_moment(self, n: int | int32 | int64) -> np.ndarray: + def trigonometric_moment(self, n: Union[int, int32, int64]) -> np.ndarray: return self.trigonometric_moment_numerical(n) def integrate(self, integration_boundaries=None): @@ -253,9 +250,9 @@ def mean_2dimD(self) -> np.ndarray: # jscpd:ignore-start def sample_metropolis_hastings( self, - n: int | int32 | int64, - burn_in: int | int32 | int64 = 10, - skipping: int | int32 | int64 = 5, + n: Union[int, int32, int64], + burn_in: Union[int, int32, int64] = 10, + skipping: Union[int, int32, int64] = 5, proposal: Callable | None = None, start_point: np.number | numbers.Real | np.ndarray | None = None, ) -> np.ndarray: @@ -275,7 +272,6 @@ def proposal(x): return s @staticmethod - @beartype def setup_axis_circular(axis_name: str = "x", ax=plt.gca()) -> None: ticks = [0, np.pi, 2 * np.pi] tick_labels = ["0", r"$\pi$", r"$2\pi$"] @@ -292,4 +288,4 @@ def setup_axis_circular(axis_name: str = "x", ax=plt.gca()) -> None: ax.set_zticks(ticks) ax.set_zticklabels(tick_labels) else: - raise ValueError("invalid axis") + raise ValueError("invalid axis") \ No newline at end of file diff --git a/pyrecest/distributions/hypertorus/abstract_toroidal_distribution.py b/pyrecest/distributions/hypertorus/abstract_toroidal_distribution.py index 782a4460..8c33e158 100644 --- a/pyrecest/distributions/hypertorus/abstract_toroidal_distribution.py +++ b/pyrecest/distributions/hypertorus/abstract_toroidal_distribution.py @@ -1,3 +1,4 @@ +from typing import Union from pyrecest.backend import sqrt from pyrecest.backend import sin from pyrecest.backend import cos @@ -21,8 +22,8 @@ def covariance_4D_numerical(self) -> np.ndarray: def f( x: float, y: float, - i: int | int32 | int64, - j: int | int32 | int64, + i: Union[int, int32, int64], + j: Union[int, int32, int64], ) -> float: funcs = [ lambda x, _: cos(x) - m[0], @@ -74,4 +75,4 @@ def mean_4D(self) -> np.ndarray: """ m = self.trigonometric_moment(1) mu = array([m[0].real, m[0].imag, m[1].real, m[1].imag]).ravel() - return mu + return mu \ No newline at end of file diff --git a/pyrecest/distributions/hypertorus/custom_hypertoroidal_distribution.py b/pyrecest/distributions/hypertorus/custom_hypertoroidal_distribution.py index f611ed86..e01c5cdb 100644 --- a/pyrecest/distributions/hypertorus/custom_hypertoroidal_distribution.py +++ b/pyrecest/distributions/hypertorus/custom_hypertoroidal_distribution.py @@ -52,4 +52,4 @@ def to_custom_toroidal(self): assert self.dim == 2 ctd = CustomToroidalDistribution(self.f) - return ctd + return ctd \ No newline at end of file diff --git a/pyrecest/distributions/hypertorus/custom_toroidal_distribution.py b/pyrecest/distributions/hypertorus/custom_toroidal_distribution.py index 364e89c8..f938a7c7 100644 --- a/pyrecest/distributions/hypertorus/custom_toroidal_distribution.py +++ b/pyrecest/distributions/hypertorus/custom_toroidal_distribution.py @@ -7,4 +7,4 @@ class CustomToroidalDistribution( ): def __init__(self, f): AbstractToroidalDistribution.__init__(self) - CustomHypertoroidalDistribution.__init__(self, f, 2) + CustomHypertoroidalDistribution.__init__(self, f, 2) \ No newline at end of file diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py b/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py index a7d85d3e..88993f15 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py @@ -1,3 +1,4 @@ +from typing import Union from pyrecest.backend import tile from pyrecest.backend import sum from pyrecest.backend import reshape @@ -21,7 +22,6 @@ class HypertoroidalDiracDistribution( AbstractDiracDistribution, AbstractHypertoroidalDistribution ): - @beartype def __init__( self, d: np.ndarray, w: np.ndarray | None = None, dim: int | None = None ): @@ -53,8 +53,7 @@ def mean_direction(self) -> np.ndarray: m = mod(arctan2(imag(a), real(a)), 2 * np.pi) return m - @beartype - def trigonometric_moment(self, n: int | int32 | int64) -> np.ndarray: + def trigonometric_moment(self, n: Union[int, int32, int64]) -> np.ndarray: """ Calculate the trigonometric moment of the HypertoroidalDiracDistribution. @@ -66,7 +65,6 @@ def trigonometric_moment(self, n: int | int32 | int64) -> np.ndarray: exp(1j * n * self.d.T) * tile(self.w, (self.dim, 1)), axis=1 ) - @beartype def apply_function(self, f: Callable) -> "HypertoroidalDiracDistribution": dist = super().apply_function(f) dist.d = mod(dist.d, 2 * np.pi) @@ -79,13 +77,11 @@ def to_toroidal_wd(self): twd = ToroidalDiracDistribution(self.d, self.w) return twd - @beartype - def marginalize_to_1D(self, dimension: int | int32 | int64): + def marginalize_to_1D(self, dimension: Union[int, int32, int64]): from ..circle.circular_dirac_distribution import CircularDiracDistribution return CircularDiracDistribution(self.d[:, dimension], self.w) - @beartype def marginalize_out(self, dimensions: int | list[int]): from ..circle.circular_dirac_distribution import CircularDiracDistribution @@ -93,7 +89,6 @@ def marginalize_out(self, dimensions: int | list[int]): remaining_dims = [dim for dim in remaining_dims if dim != dimensions] return CircularDiracDistribution(self.d[:, remaining_dims], self.w) - @beartype def shift(self, shift_by) -> "HypertoroidalDiracDistribution": assert shift_by.shape[-1] == self.dim hd = copy.copy(self) @@ -108,4 +103,4 @@ def to_wd(self): assert self.dim == 1 from ..circle.circular_dirac_distribution import CircularDiracDistribution - return CircularDiracDistribution(self.d, self.w) + return CircularDiracDistribution(self.d, self.w) \ No newline at end of file diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_mixture.py b/pyrecest/distributions/hypertorus/hypertoroidal_mixture.py index ec4409d0..26e8e5d4 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_mixture.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_mixture.py @@ -1,3 +1,4 @@ +from typing import Union from pyrecest.backend import int64 from pyrecest.backend import int32 from pyrecest.backend import zeros @@ -12,7 +13,6 @@ class HypertoroidalMixture(AbstractMixture, AbstractHypertoroidalDistribution): - @beartype def __init__( self, dists: collections.abc.Sequence[AbstractHypertoroidalDistribution], @@ -31,7 +31,7 @@ def __init__( AbstractHypertoroidalDistribution ] = self.dists - def trigonometric_moment(self, n: int | int32 | int64) -> np.ndarray: + def trigonometric_moment(self, n: Union[int, int32, int64]) -> np.ndarray: """ Calculate n-th trigonometric moment @@ -80,4 +80,4 @@ def to_toroidal_mixture(self): @property def input_dim(self): - return AbstractHypertoroidalDistribution.input_dim.fget(self) + return AbstractHypertoroidalDistribution.input_dim.fget(self) \ No newline at end of file diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_uniform_distribution.py b/pyrecest/distributions/hypertorus/hypertoroidal_uniform_distribution.py index d8a4f348..32e6f6e3 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_uniform_distribution.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_uniform_distribution.py @@ -1,3 +1,4 @@ +from typing import Union from pyrecest.backend import prod from pyrecest.backend import ones from pyrecest.backend import ndim @@ -23,7 +24,7 @@ def pdf(self, xs: np.ndarray) -> np.ndarray: """ return 1 / self.get_manifold_size() * ones(xs.size // self.dim) - def trigonometric_moment(self, n: int | int32 | int64) -> np.ndarray: + def trigonometric_moment(self, n: Union[int, int32, int64]) -> np.ndarray: """ Returns the n-th trigonometric moment @@ -54,7 +55,7 @@ def mean_direction(self): "Hypertoroidal uniform distributions do not have a unique mean" ) - def sample(self, n: int | int32 | int64) -> np.ndarray: + def sample(self, n: Union[int, int32, int64]) -> np.ndarray: """ Returns a sample of size n from the distribution @@ -93,4 +94,4 @@ def integrate( assert ndim(right) == 0 and self.dim == 1 or right.shape == (self.dim,) volume = prod(right - left) - return 1 / (2 * np.pi) ** self.dim * volume + return 1 / (2 * np.pi) ** self.dim * volume \ No newline at end of file diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py b/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py index abccb29b..b8f8a046 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py @@ -1,3 +1,4 @@ +from typing import Union from pyrecest.backend import reshape from pyrecest.backend import mod from pyrecest.backend import meshgrid @@ -40,7 +41,7 @@ def __init__(self, mu: np.ndarray, C: np.ndarray): self.mu = mod(mu, 2 * np.pi) self.C = C - def pdf(self, xs: np.ndarray, m: int | int32 | int64 = 3) -> np.ndarray: + def pdf(self, xs: np.ndarray, m: Union[int, int32, int64] = 3) -> np.ndarray: """ Compute the PDF at given points. @@ -133,4 +134,4 @@ def mode(self): # Returns: # m (vector) # the mode - return self.mu + return self.mu \ No newline at end of file diff --git a/pyrecest/distributions/hypertorus/toroidal_dirac_distribution.py b/pyrecest/distributions/hypertorus/toroidal_dirac_distribution.py index 3de7310c..1a346475 100644 --- a/pyrecest/distributions/hypertorus/toroidal_dirac_distribution.py +++ b/pyrecest/distributions/hypertorus/toroidal_dirac_distribution.py @@ -58,4 +58,4 @@ def covariance_4D(self) -> np.ndarray: C = (dbar - tile(mu, (n, 1))).T @ ( np.diag(self.w) @ (dbar - tile(mu, (n, 1))) ) - return C + return C \ No newline at end of file diff --git a/pyrecest/distributions/hypertorus/toroidal_mixture.py b/pyrecest/distributions/hypertorus/toroidal_mixture.py index 69a3c95e..d09c69c6 100644 --- a/pyrecest/distributions/hypertorus/toroidal_mixture.py +++ b/pyrecest/distributions/hypertorus/toroidal_mixture.py @@ -17,4 +17,4 @@ def __init__(self, hds: list[AbstractToroidalDistribution], w: np.ndarray): ), "hds must be a list of toroidal distributions" HypertoroidalMixture.__init__(self, hds, w) - AbstractToroidalDistribution.__init__(self) + AbstractToroidalDistribution.__init__(self) \ No newline at end of file diff --git a/pyrecest/distributions/hypertorus/toroidal_uniform_distribution.py b/pyrecest/distributions/hypertorus/toroidal_uniform_distribution.py index b2eedda5..9f237534 100644 --- a/pyrecest/distributions/hypertorus/toroidal_uniform_distribution.py +++ b/pyrecest/distributions/hypertorus/toroidal_uniform_distribution.py @@ -6,4 +6,4 @@ class ToroidalUniformDistribution( HypertoroidalUniformDistribution, AbstractToroidalDistribution ): def get_manifold_size(self): - return AbstractToroidalDistribution.get_manifold_size(self) + return AbstractToroidalDistribution.get_manifold_size(self) \ No newline at end of file diff --git a/pyrecest/distributions/hypertorus/toroidal_von_mises_sine_distribution.py b/pyrecest/distributions/hypertorus/toroidal_von_mises_sine_distribution.py index 14dc065c..e667f2ea 100644 --- a/pyrecest/distributions/hypertorus/toroidal_von_mises_sine_distribution.py +++ b/pyrecest/distributions/hypertorus/toroidal_von_mises_sine_distribution.py @@ -46,4 +46,4 @@ def pdf(self, xs): * sin(xs[..., 0] - self.mu[0]) * sin(xs[..., 1] - self.mu[1]) ) - return p + return p \ No newline at end of file diff --git a/pyrecest/distributions/hypertorus/toroidal_wrapped_normal_distribution.py b/pyrecest/distributions/hypertorus/toroidal_wrapped_normal_distribution.py index 3451cbcf..44807c57 100644 --- a/pyrecest/distributions/hypertorus/toroidal_wrapped_normal_distribution.py +++ b/pyrecest/distributions/hypertorus/toroidal_wrapped_normal_distribution.py @@ -123,4 +123,4 @@ def covariance_4D(self) -> np.ndarray: C[2, 1] = C[1, 2] C[3, 1] = C[1, 3] # jscpd:ignore-end - return C + return C \ No newline at end of file diff --git a/pyrecest/distributions/nonperiodic/abstract_hyperrectangular_distribution.py b/pyrecest/distributions/nonperiodic/abstract_hyperrectangular_distribution.py index ad3b1c05..6fa64da4 100644 --- a/pyrecest/distributions/nonperiodic/abstract_hyperrectangular_distribution.py +++ b/pyrecest/distributions/nonperiodic/abstract_hyperrectangular_distribution.py @@ -42,4 +42,4 @@ def integrate(self, integration_boundaries=None) -> float: left, right = integration_boundaries integration_boundaries = zip(left, right) - return nquad(lambda *args: self.pdf(array(args)), integration_boundaries)[0] + return nquad(lambda *args: self.pdf(array(args)), integration_boundaries)[0] \ No newline at end of file diff --git a/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py b/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py index 475e4734..011710d1 100644 --- a/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py +++ b/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py @@ -1,3 +1,4 @@ +from typing import Union from pyrecest.backend import squeeze from pyrecest.backend import sqrt from pyrecest.backend import reshape @@ -58,9 +59,9 @@ def neg_pdf(x): def sample_metropolis_hastings( self, - n: int | int32 | int64, - burn_in: int | int32 | int64 = 10, - skipping: int | int32 | int64 = 5, + n: Union[int, int32, int64], + burn_in: Union[int, int32, int64] = 10, + skipping: Union[int, int32, int64] = 5, proposal: Callable | None = None, start_point: np.number | numbers.Real | np.ndarray | None = None, ) -> np.ndarray: @@ -264,4 +265,4 @@ def plot_state(self, scaling_factor=1, color=(0, 0.4470, 0.7410)): mean = self.mean() plot_ellipsoid(mean, covariance, scaling_factor, color) - raise ValueError("Dimension currently not supported for plotting the state.") + raise ValueError("Dimension currently not supported for plotting the state.") \ No newline at end of file diff --git a/pyrecest/distributions/nonperiodic/custom_linear_distribution.py b/pyrecest/distributions/nonperiodic/custom_linear_distribution.py index 41bf1f03..d5f9c8e3 100644 --- a/pyrecest/distributions/nonperiodic/custom_linear_distribution.py +++ b/pyrecest/distributions/nonperiodic/custom_linear_distribution.py @@ -72,4 +72,4 @@ def from_distribution(distribution): return chd def integrate(self, left=None, right=None): - return AbstractLinearDistribution.integrate(self, left, right) + return AbstractLinearDistribution.integrate(self, left, right) \ No newline at end of file diff --git a/pyrecest/distributions/nonperiodic/gaussian_distribution.py b/pyrecest/distributions/nonperiodic/gaussian_distribution.py index a6d512e6..09cfc013 100644 --- a/pyrecest/distributions/nonperiodic/gaussian_distribution.py +++ b/pyrecest/distributions/nonperiodic/gaussian_distribution.py @@ -11,7 +11,6 @@ class GaussianDistribution(AbstractLinearDistribution): - @beartype def __init__(self, mu: np.ndarray, C: np.ndarray, check_validity=True): AbstractLinearDistribution.__init__(self, dim=np.size(mu)) assert ( @@ -98,4 +97,4 @@ def from_distribution(distribution): ) # Assuming to_gaussian method is defined in GaussianMixtureDistribution else: gaussian = GaussianDistribution(distribution.mean, distribution.covariance) - return gaussian + return gaussian \ No newline at end of file diff --git a/pyrecest/distributions/nonperiodic/gaussian_mixture.py b/pyrecest/distributions/nonperiodic/gaussian_mixture.py index acdb582e..332b4e43 100644 --- a/pyrecest/distributions/nonperiodic/gaussian_mixture.py +++ b/pyrecest/distributions/nonperiodic/gaussian_mixture.py @@ -15,7 +15,6 @@ class GaussianMixture(LinearMixture, AbstractLinearDistribution): - @beartype def __init__(self, dists: list[GaussianDistribution], w: np.ndarray): AbstractLinearDistribution.__init__(self, dim=dists[0].dim) LinearMixture.__init__(self, dists, w) @@ -24,7 +23,6 @@ def mean(self): gauss_array = self.dists return dot(array([g.mu for g in gauss_array]), self.w) - @beartype def set_mean(self, new_mean: np.ndarray | numbers.Real): mean_offset = new_mean - self.mean() for dist in self.dists: @@ -61,4 +59,4 @@ def mixture_parameters_to_gaussian_parameters( ) C = C_from_cov + C_from_means - return mu, C + return mu, C \ No newline at end of file diff --git a/pyrecest/distributions/nonperiodic/hyperrectangular_uniform_distribution.py b/pyrecest/distributions/nonperiodic/hyperrectangular_uniform_distribution.py index 03fc9609..e4284596 100644 --- a/pyrecest/distributions/nonperiodic/hyperrectangular_uniform_distribution.py +++ b/pyrecest/distributions/nonperiodic/hyperrectangular_uniform_distribution.py @@ -10,4 +10,4 @@ def __init__(self, bounds): AbstractHyperrectangularDistribution.__init__(self, bounds) def get_manifold_size(self): - return AbstractHyperrectangularDistribution.get_manifold_size(self) + return AbstractHyperrectangularDistribution.get_manifold_size(self) \ No newline at end of file diff --git a/pyrecest/distributions/nonperiodic/linear_dirac_distribution.py b/pyrecest/distributions/nonperiodic/linear_dirac_distribution.py index dc941bd4..890bae55 100644 --- a/pyrecest/distributions/nonperiodic/linear_dirac_distribution.py +++ b/pyrecest/distributions/nonperiodic/linear_dirac_distribution.py @@ -54,4 +54,4 @@ def weighted_samples_to_mean_and_cov(samples, weights=None): deviation = samples - mean covariance = np.cov(deviation.T, aweights=weights, bias=True) - return mean, covariance + return mean, covariance \ No newline at end of file diff --git a/pyrecest/distributions/nonperiodic/linear_mixture.py b/pyrecest/distributions/nonperiodic/linear_mixture.py index 9be4b795..5b50e2bb 100644 --- a/pyrecest/distributions/nonperiodic/linear_mixture.py +++ b/pyrecest/distributions/nonperiodic/linear_mixture.py @@ -9,7 +9,6 @@ class LinearMixture(AbstractMixture, AbstractLinearDistribution): - @beartype def __init__(self, dists: list[AbstractLinearDistribution], w: np.ndarray): from .gaussian_mixture import GaussianMixture @@ -28,4 +27,4 @@ def __init__(self, dists: list[AbstractLinearDistribution], w: np.ndarray): @property def input_dim(self): - return AbstractLinearDistribution.input_dim.fget(self) + return AbstractLinearDistribution.input_dim.fget(self) \ No newline at end of file diff --git a/pyrecest/distributions/se3_cart_prod_stacked_distribution.py b/pyrecest/distributions/se3_cart_prod_stacked_distribution.py index 6418ef04..71fe68dc 100644 --- a/pyrecest/distributions/se3_cart_prod_stacked_distribution.py +++ b/pyrecest/distributions/se3_cart_prod_stacked_distribution.py @@ -21,4 +21,4 @@ def get_manifold_size(self): return np.inf def pdf(self, xs): - return CartProdStackedDistribution.pdf(self, xs) + return CartProdStackedDistribution.pdf(self, xs) \ No newline at end of file diff --git a/pyrecest/distributions/se3_dirac_distribution.py b/pyrecest/distributions/se3_dirac_distribution.py index 1a3f6120..5d1ebbac 100644 --- a/pyrecest/distributions/se3_dirac_distribution.py +++ b/pyrecest/distributions/se3_dirac_distribution.py @@ -45,4 +45,4 @@ def from_distribution(distribution, n_particles): distribution.sample(n_particles), 1 / n_particles * ones((1, n_particles)), ) - return ddist + return ddist \ No newline at end of file diff --git a/pyrecest/evaluation/__init__.py b/pyrecest/evaluation/__init__.py index 7f61bdf5..b1206122 100644 --- a/pyrecest/evaluation/__init__.py +++ b/pyrecest/evaluation/__init__.py @@ -34,4 +34,4 @@ "evaluate_for_file", "evaluate_for_simulation_config", "evaluate_for_variables", -] +] \ No newline at end of file diff --git a/pyrecest/evaluation/check_and_fix_config.py b/pyrecest/evaluation/check_and_fix_config.py index b0589656..6a4dac8e 100644 --- a/pyrecest/evaluation/check_and_fix_config.py +++ b/pyrecest/evaluation/check_and_fix_config.py @@ -90,4 +90,4 @@ def check_and_fix_config(simulation_param): simulation_param["initial_prior"], AbstractManifoldSpecificDistribution ) - return simulation_param + return simulation_param \ No newline at end of file diff --git a/pyrecest/evaluation/configure_for_filter.py b/pyrecest/evaluation/configure_for_filter.py index 1d3558a0..6219ebcc 100644 --- a/pyrecest/evaluation/configure_for_filter.py +++ b/pyrecest/evaluation/configure_for_filter.py @@ -149,4 +149,4 @@ def prediction_routine(curr_input): # type: ignore[misc] prediction_routine, likelihood_for_filter, meas_noise_for_filter, - ) + ) \ No newline at end of file diff --git a/pyrecest/evaluation/determine_all_deviations.py b/pyrecest/evaluation/determine_all_deviations.py index d0d4b048..691f3a80 100644 --- a/pyrecest/evaluation/determine_all_deviations.py +++ b/pyrecest/evaluation/determine_all_deviations.py @@ -9,7 +9,6 @@ from beartype import beartype -@beartype def determine_all_deviations( results, extract_mean, @@ -58,4 +57,4 @@ def determine_all_deviations( "times. Check if this is plausible." ) - return all_deviations_last_mat + return all_deviations_last_mat \ No newline at end of file diff --git a/pyrecest/evaluation/eot_shape_database.py b/pyrecest/evaluation/eot_shape_database.py index 41ce34cf..1b73b077 100644 --- a/pyrecest/evaluation/eot_shape_database.py +++ b/pyrecest/evaluation/eot_shape_database.py @@ -221,4 +221,4 @@ def __new__(cls, scaling_factor=1): polygon = super().__new__(cls, shell=zip(x, y), holes=None) # nosec polygon.__class__ = cls - return polygon + return polygon \ No newline at end of file diff --git a/pyrecest/evaluation/evaluate_for_file.py b/pyrecest/evaluation/evaluate_for_file.py index 5d91e18c..681786f8 100644 --- a/pyrecest/evaluation/evaluate_for_file.py +++ b/pyrecest/evaluation/evaluate_for_file.py @@ -71,4 +71,4 @@ def evaluate_for_file( extract_all_point_estimates=extract_all_point_estimates, tolerate_failure=tolerate_failure, auto_warning_on_off=auto_warning_on_off, - ) + ) \ No newline at end of file diff --git a/pyrecest/evaluation/evaluate_for_simulation_config.py b/pyrecest/evaluation/evaluate_for_simulation_config.py index 780ededd..e0e4b913 100644 --- a/pyrecest/evaluation/evaluate_for_simulation_config.py +++ b/pyrecest/evaluation/evaluate_for_simulation_config.py @@ -70,7 +70,6 @@ def evaluate_for_simulation_config( ) -@beartype def get_all_seeds(n_runs: int, seed_input=None, consecutive_seed: bool = True): if seed_input is None: seed_input = np.uint32(random.randint(1, 0xFFFFFFFF)) # nosec @@ -88,4 +87,4 @@ def get_all_seeds(n_runs: int, seed_input=None, consecutive_seed: bool = True): "The number of seeds provided must be either 1 or equal to the number of runs." ) - return all_seeds + return all_seeds \ No newline at end of file diff --git a/pyrecest/evaluation/evaluate_for_variables.py b/pyrecest/evaluation/evaluate_for_variables.py index 184e7247..1604dbdf 100644 --- a/pyrecest/evaluation/evaluate_for_variables.py +++ b/pyrecest/evaluation/evaluate_for_variables.py @@ -78,4 +78,4 @@ def evaluate_for_variables( scenario_config, # pylint: disable=R0801 filter_configs, # pylint: disable=R0801 evaluation_config, # pylint: disable=R0801 - ) + ) \ No newline at end of file diff --git a/pyrecest/evaluation/generate_groundtruth.py b/pyrecest/evaluation/generate_groundtruth.py index 8666f4ea..9815fa49 100644 --- a/pyrecest/evaluation/generate_groundtruth.py +++ b/pyrecest/evaluation/generate_groundtruth.py @@ -92,4 +92,4 @@ def generate_groundtruth(simulation_param, x0=None): for t in range(simulation_param["n_timesteps"]): groundtruth[t] = squeeze(groundtruth[t]) - return groundtruth + return groundtruth \ No newline at end of file diff --git a/pyrecest/evaluation/generate_measurements.py b/pyrecest/evaluation/generate_measurements.py index 708da392..33fe310c 100644 --- a/pyrecest/evaluation/generate_measurements.py +++ b/pyrecest/evaluation/generate_measurements.py @@ -191,9 +191,8 @@ def generate_measurements(groundtruth, simulation_config): return measurements -@beartype def generate_n_measurements_PPP(area: float, intensity_lambda: float) -> int: # Compute the expected number of points expected_num_points = intensity_lambda * area # Get the actual number of points to generate as a realization from a Poisson distribution - return poisson.rvs(expected_num_points) + return poisson.rvs(expected_num_points) \ No newline at end of file diff --git a/pyrecest/evaluation/generate_simulated_scenarios.py b/pyrecest/evaluation/generate_simulated_scenarios.py index a292e9cb..ca68b66c 100644 --- a/pyrecest/evaluation/generate_simulated_scenarios.py +++ b/pyrecest/evaluation/generate_simulated_scenarios.py @@ -38,4 +38,4 @@ def generate_simulated_scenarios( groundtruths[run, :], simulation_params ) - return groundtruths, measurements + return groundtruths, measurements \ No newline at end of file diff --git a/pyrecest/evaluation/get_axis_label.py b/pyrecest/evaluation/get_axis_label.py index 6eebac08..dfa94054 100644 --- a/pyrecest/evaluation/get_axis_label.py +++ b/pyrecest/evaluation/get_axis_label.py @@ -36,4 +36,4 @@ def get_axis_label(manifold_name): else: raise ValueError("Mode not recognized") - return error_label + return error_label \ No newline at end of file diff --git a/pyrecest/evaluation/get_distance_function.py b/pyrecest/evaluation/get_distance_function.py index c5f5ed18..8fbe83cb 100644 --- a/pyrecest/evaluation/get_distance_function.py +++ b/pyrecest/evaluation/get_distance_function.py @@ -68,4 +68,4 @@ def distance_function(x1, x2): else: raise ValueError("Mode not recognized") - return distance_function + return distance_function \ No newline at end of file diff --git a/pyrecest/evaluation/get_extract_mean.py b/pyrecest/evaluation/get_extract_mean.py index 17b7b178..64539bf3 100644 --- a/pyrecest/evaluation/get_extract_mean.py +++ b/pyrecest/evaluation/get_extract_mean.py @@ -48,4 +48,4 @@ def extract_mean(_): else: raise ValueError("Mode not recognized") - return extract_mean + return extract_mean \ No newline at end of file diff --git a/pyrecest/evaluation/group_results_by_filter.py b/pyrecest/evaluation/group_results_by_filter.py index f9e852a4..35781f7f 100644 --- a/pyrecest/evaluation/group_results_by_filter.py +++ b/pyrecest/evaluation/group_results_by_filter.py @@ -20,4 +20,4 @@ def group_results_by_filter(data): # Initialize the entry in the output_dict with lists for each value output_dict[name] = {k: [v] for k, v in entry_values.items()} - return output_dict + return output_dict \ No newline at end of file diff --git a/pyrecest/evaluation/iterate_configs_and_runs.py b/pyrecest/evaluation/iterate_configs_and_runs.py index 020aa8ab..efdf00ae 100644 --- a/pyrecest/evaluation/iterate_configs_and_runs.py +++ b/pyrecest/evaluation/iterate_configs_and_runs.py @@ -77,4 +77,4 @@ def iterate_configs_and_runs( f"Filter {config_no} config {filter_config['parameter']} run {run} FAILED: {str(err)}" ) - return last_filter_states, run_times, run_failed, groundtruths, measurements + return last_filter_states, run_times, run_failed, groundtruths, measurements \ No newline at end of file diff --git a/pyrecest/evaluation/perform_predict_update_cycles.py b/pyrecest/evaluation/perform_predict_update_cycles.py index 24b6b2a8..161d66d9 100644 --- a/pyrecest/evaluation/perform_predict_update_cycles.py +++ b/pyrecest/evaluation/perform_predict_update_cycles.py @@ -91,4 +91,4 @@ def perform_predict_update_cycles( else: last_estimate = filter_obj.get_point_estimate() - return last_filter_state, time_elapsed, last_estimate, all_estimates + return last_filter_state, time_elapsed, last_estimate, all_estimates \ No newline at end of file diff --git a/pyrecest/evaluation/plot_results.py b/pyrecest/evaluation/plot_results.py index 8440d630..c34cdb8b 100644 --- a/pyrecest/evaluation/plot_results.py +++ b/pyrecest/evaluation/plot_results.py @@ -235,7 +235,6 @@ def get_plot_style_for_filter(filter_name): return color, style_marker, style_line -@beartype def long_name_to_short_name(short_name: str) -> str: """Get short name from long name.""" @@ -293,4 +292,4 @@ def apply_log_scale_to_axes(axes_list, log_array): ax.set_xscale("log") if log_array[1, plot_idx]: # Check if y-axis should be log scale - ax.set_yscale("log") + ax.set_yscale("log") \ No newline at end of file diff --git a/pyrecest/evaluation/simulation_database.py b/pyrecest/evaluation/simulation_database.py index f9e38af2..dffddc2c 100644 --- a/pyrecest/evaluation/simulation_database.py +++ b/pyrecest/evaluation/simulation_database.py @@ -7,7 +7,6 @@ from pyrecest.distributions import GaussianDistribution -@beartype def simulation_database( scenario_name: str = "custom", scenario_customization_params: Optional[dict] = None ) -> dict: @@ -41,4 +40,4 @@ def simulation_database( else: raise ValueError("Scenario not recognized.") - return simulation_param + return simulation_param \ No newline at end of file diff --git a/pyrecest/evaluation/summarize_filter_results.py b/pyrecest/evaluation/summarize_filter_results.py index 40dcb210..8ee28ae9 100644 --- a/pyrecest/evaluation/summarize_filter_results.py +++ b/pyrecest/evaluation/summarize_filter_results.py @@ -57,4 +57,4 @@ def summarize_filter_results( d["time_mean"] = curr_time d["failure_rate"] = curr_fail_rate - return results_summarized + return results_summarized \ No newline at end of file diff --git a/pyrecest/filters/__init__.py b/pyrecest/filters/__init__.py index 479c6b9b..04a15427 100644 --- a/pyrecest/filters/__init__.py +++ b/pyrecest/filters/__init__.py @@ -18,4 +18,4 @@ "HypertoroidalParticleFilter", "KalmanFilter", "EuclideanParticleFilter", -] +] \ No newline at end of file diff --git a/pyrecest/filters/abstract_circular_filter.py b/pyrecest/filters/abstract_circular_filter.py index 5007a63c..51871795 100644 --- a/pyrecest/filters/abstract_circular_filter.py +++ b/pyrecest/filters/abstract_circular_filter.py @@ -5,4 +5,4 @@ class AbstractCircularFilter(AbstractHypertoroidalFilter): """ This class represents an abstract circular filter. While it currently does not add any functionality to its superclass, it serves as a basis for creating more specific types of circular filters. - """ + """ \ No newline at end of file diff --git a/pyrecest/filters/abstract_euclidean_filter.py b/pyrecest/filters/abstract_euclidean_filter.py index 9701fe41..63900947 100644 --- a/pyrecest/filters/abstract_euclidean_filter.py +++ b/pyrecest/filters/abstract_euclidean_filter.py @@ -7,4 +7,4 @@ class AbstractEuclideanFilter(AbstractManifoldSpecificFilter): def get_point_estimate(self): est = self.filter_state.mean() - return est + return est \ No newline at end of file diff --git a/pyrecest/filters/abstract_extended_object_tracker.py b/pyrecest/filters/abstract_extended_object_tracker.py index 407e5904..464bbf03 100644 --- a/pyrecest/filters/abstract_extended_object_tracker.py +++ b/pyrecest/filters/abstract_extended_object_tracker.py @@ -76,4 +76,4 @@ def get_point_estimate_extent(self, flatten_matrix=False): Returns: - A matrix or vector representing the estimated extent. - """ + """ \ No newline at end of file diff --git a/pyrecest/filters/abstract_filter.py b/pyrecest/filters/abstract_filter.py index 8c0c9af6..a7ba4e08 100644 --- a/pyrecest/filters/abstract_filter.py +++ b/pyrecest/filters/abstract_filter.py @@ -33,4 +33,4 @@ def dim(self) -> int: def plot_filter_state(self): """Plot the filter state.""" - self.filter_state.plot() + self.filter_state.plot() \ No newline at end of file diff --git a/pyrecest/filters/abstract_filter_type.py b/pyrecest/filters/abstract_filter_type.py index f47c7556..3b991428 100644 --- a/pyrecest/filters/abstract_filter_type.py +++ b/pyrecest/filters/abstract_filter_type.py @@ -2,4 +2,4 @@ class AbstractFilterType(AbstractFilter): - pass + pass \ No newline at end of file diff --git a/pyrecest/filters/abstract_hypercylindrical_filter.py b/pyrecest/filters/abstract_hypercylindrical_filter.py index 8b791857..7beb0067 100644 --- a/pyrecest/filters/abstract_hypercylindrical_filter.py +++ b/pyrecest/filters/abstract_hypercylindrical_filter.py @@ -3,4 +3,4 @@ class AbstractHypercylindricalFilter(AbstractLinPeriodicFilter): def get_point_estimate(self): - return self.filter_state.hybrid_mean() + return self.filter_state.hybrid_mean() \ No newline at end of file diff --git a/pyrecest/filters/abstract_hyperhemispherical_filter.py b/pyrecest/filters/abstract_hyperhemispherical_filter.py index 5d66ec82..675b4b86 100644 --- a/pyrecest/filters/abstract_hyperhemispherical_filter.py +++ b/pyrecest/filters/abstract_hyperhemispherical_filter.py @@ -4,4 +4,4 @@ class AbstractHyperhemisphericalFilter(AbstractManifoldSpecificFilter): """ Abstract class representing a hyperhemispherical filter. - """ + """ \ No newline at end of file diff --git a/pyrecest/filters/abstract_hypersphere_subset_filter.py b/pyrecest/filters/abstract_hypersphere_subset_filter.py index 9ce61002..e5623099 100644 --- a/pyrecest/filters/abstract_hypersphere_subset_filter.py +++ b/pyrecest/filters/abstract_hypersphere_subset_filter.py @@ -2,4 +2,4 @@ class AbstractHypersphereSubsetFilter(AbstractManifoldSpecificFilter): - pass + pass \ No newline at end of file diff --git a/pyrecest/filters/abstract_hyperspherical_filter.py b/pyrecest/filters/abstract_hyperspherical_filter.py index d8c96a3b..c842ea3f 100644 --- a/pyrecest/filters/abstract_hyperspherical_filter.py +++ b/pyrecest/filters/abstract_hyperspherical_filter.py @@ -2,4 +2,4 @@ class AbstractHypersphericalFilter(AbstractManifoldSpecificFilter): - pass + pass \ No newline at end of file diff --git a/pyrecest/filters/abstract_hypertoroidal_filter.py b/pyrecest/filters/abstract_hypertoroidal_filter.py index a4e833d8..7911fee0 100644 --- a/pyrecest/filters/abstract_hypertoroidal_filter.py +++ b/pyrecest/filters/abstract_hypertoroidal_filter.py @@ -24,4 +24,4 @@ def get_point_estimate(self) -> np.ndarray: :return: The mean direction of the filter state. """ - return self.filter_state.mean_direction() + return self.filter_state.mean_direction() \ No newline at end of file diff --git a/pyrecest/filters/abstract_lin_bounded_filter.py b/pyrecest/filters/abstract_lin_bounded_filter.py index 515fe37a..60d148e2 100644 --- a/pyrecest/filters/abstract_lin_bounded_filter.py +++ b/pyrecest/filters/abstract_lin_bounded_filter.py @@ -2,4 +2,4 @@ class AbstractLinBoundedFilter(AbstractManifoldSpecificFilter): - pass + pass \ No newline at end of file diff --git a/pyrecest/filters/abstract_lin_periodic_filter.py b/pyrecest/filters/abstract_lin_periodic_filter.py index fc6aebee..2e465906 100644 --- a/pyrecest/filters/abstract_lin_periodic_filter.py +++ b/pyrecest/filters/abstract_lin_periodic_filter.py @@ -2,4 +2,4 @@ class AbstractLinPeriodicFilter(AbstractLinBoundedFilter): - pass + pass \ No newline at end of file diff --git a/pyrecest/filters/abstract_manifold_specific_filter.py b/pyrecest/filters/abstract_manifold_specific_filter.py index c9a1f853..cb5bc243 100644 --- a/pyrecest/filters/abstract_manifold_specific_filter.py +++ b/pyrecest/filters/abstract_manifold_specific_filter.py @@ -2,4 +2,4 @@ class AbstractManifoldSpecificFilter(AbstractFilter): - pass + pass \ No newline at end of file diff --git a/pyrecest/filters/abstract_multitarget_tracker.py b/pyrecest/filters/abstract_multitarget_tracker.py index 0d158964..3a8343f9 100644 --- a/pyrecest/filters/abstract_multitarget_tracker.py +++ b/pyrecest/filters/abstract_multitarget_tracker.py @@ -30,4 +30,4 @@ def get_point_estimate(self, flatten_vector=False): @abstractmethod def get_number_of_targets(self): - pass + pass \ No newline at end of file diff --git a/pyrecest/filters/abstract_nearest_neighbor_tracker.py b/pyrecest/filters/abstract_nearest_neighbor_tracker.py index a3665c40..2f593ac4 100644 --- a/pyrecest/filters/abstract_nearest_neighbor_tracker.py +++ b/pyrecest/filters/abstract_nearest_neighbor_tracker.py @@ -149,4 +149,4 @@ def get_point_estimate(self, flatten_vector=False): point_ests[:, i] = self.filter_bank[i].get_point_estimate() if flatten_vector: point_ests = point_ests.flatten() - return point_ests + return point_ests \ No newline at end of file diff --git a/pyrecest/filters/abstract_particle_filter.py b/pyrecest/filters/abstract_particle_filter.py index 88dce73d..0ccc86c1 100644 --- a/pyrecest/filters/abstract_particle_filter.py +++ b/pyrecest/filters/abstract_particle_filter.py @@ -21,7 +21,6 @@ def __init__(self, initial_filter_state=None): def predict_identity(self, noise_distribution): self.predict_nonlinear(f=lambda x: x, noise_distribution=noise_distribution) - @beartype def predict_nonlinear( self, f: Callable, @@ -62,7 +61,6 @@ def predict_nonlinear_nonadditive(self, f, samples, weights): self.filter_state.d = d - @beartype def update_identity( self, meas_noise, measurement, shift_instead_of_add: bool = True ): @@ -94,9 +92,8 @@ def update_nonlinear_using_likelihood(self, likelihood, measurement=None): 1 / self.filter_state.w.shape[0] * ones_like(self.filter_state.w) ) - @beartype def association_likelihood(self, likelihood: AbstractManifoldSpecificDistribution): likelihood_val = sum( likelihood.pdf(self.filter_state.d) * self.filter_state.w ) - return likelihood_val + return likelihood_val \ No newline at end of file diff --git a/pyrecest/filters/abstract_se2_filter.py b/pyrecest/filters/abstract_se2_filter.py index 113083c1..eacf6294 100644 --- a/pyrecest/filters/abstract_se2_filter.py +++ b/pyrecest/filters/abstract_se2_filter.py @@ -2,4 +2,4 @@ class AbstractSE2Filter(AbstractManifoldSpecificFilter): - """This class represents an abstract filter for the SE(2) manifold.""" + """This class represents an abstract filter for the SE(2) manifold.""" \ No newline at end of file diff --git a/pyrecest/filters/abstract_toroidal_filter.py b/pyrecest/filters/abstract_toroidal_filter.py index 8407b6eb..72a028b0 100644 --- a/pyrecest/filters/abstract_toroidal_filter.py +++ b/pyrecest/filters/abstract_toroidal_filter.py @@ -2,4 +2,4 @@ class AbstractToroidalFilter(AbstractHypertoroidalFilter): - pass + pass \ No newline at end of file diff --git a/pyrecest/filters/abstract_tracker_with_logging.py b/pyrecest/filters/abstract_tracker_with_logging.py index 87822ad0..704e0f54 100644 --- a/pyrecest/filters/abstract_tracker_with_logging.py +++ b/pyrecest/filters/abstract_tracker_with_logging.py @@ -33,4 +33,4 @@ def _store_estimates(self, curr_ests, estimates_over_time): estimates_over_time_new[:, -1] = curr_ests.flatten() estimates_over_time = estimates_over_time_new - return estimates_over_time + return estimates_over_time \ No newline at end of file diff --git a/pyrecest/filters/circular_particle_filter.py b/pyrecest/filters/circular_particle_filter.py index d5a731d4..addb7a03 100644 --- a/pyrecest/filters/circular_particle_filter.py +++ b/pyrecest/filters/circular_particle_filter.py @@ -1,3 +1,4 @@ +from typing import Union from pyrecest.backend import sum from pyrecest.backend import float64 from pyrecest.backend import int64 @@ -8,7 +9,7 @@ class CircularParticleFilter(HypertoroidalParticleFilter): - def __init__(self, n_particles: int | int32 | int64) -> None: + def __init__(self, n_particles: Union[int, int32, int64]) -> None: """ Initialize the CircularParticleFilter. @@ -27,4 +28,4 @@ def compute_association_likelihood(self, likelihood) -> float64: likelihood_val = sum( likelihood.pdf(self.filter_state.d) * self.filter_state.w ) - return likelihood_val + return likelihood_val \ No newline at end of file diff --git a/pyrecest/filters/euclidean_particle_filter.py b/pyrecest/filters/euclidean_particle_filter.py index 4003ac73..dda22c6f 100644 --- a/pyrecest/filters/euclidean_particle_filter.py +++ b/pyrecest/filters/euclidean_particle_filter.py @@ -1,3 +1,4 @@ +from typing import Union from pyrecest.backend import int64 from pyrecest.backend import int32 from pyrecest.backend import zeros @@ -22,8 +23,8 @@ class EuclideanParticleFilter(AbstractParticleFilter, AbstractEuclideanFilter): def __init__( self, - n_particles: int | int32 | int64, - dim: int | int32 | int64, + n_particles: Union[int, int32, int64], + dim: Union[int, int32, int64], ): if not (isinstance(n_particles, int) and n_particles > 0): raise ValueError("n_particles must be a positive integer") @@ -58,7 +59,6 @@ def filter_state( self._filter_state = dist_dirac - @beartype def predict_nonlinear( self, f: Callable, @@ -69,4 +69,4 @@ def predict_nonlinear( """Predict for nonlinear system model.""" AbstractParticleFilter.predict_nonlinear( self, f, noise_distribution, function_is_vectorized, shift_instead_of_add - ) + ) \ No newline at end of file diff --git a/pyrecest/filters/global_nearest_neighbor.py b/pyrecest/filters/global_nearest_neighbor.py index 2c2160d3..5c44832e 100644 --- a/pyrecest/filters/global_nearest_neighbor.py +++ b/pyrecest/filters/global_nearest_neighbor.py @@ -151,4 +151,4 @@ def find_association( "GNN: No measurement was within gating threshold for at least one target." ) - return association + return association \ No newline at end of file diff --git a/pyrecest/filters/hypertoroidal_particle_filter.py b/pyrecest/filters/hypertoroidal_particle_filter.py index 1e21cd90..439a984b 100644 --- a/pyrecest/filters/hypertoroidal_particle_filter.py +++ b/pyrecest/filters/hypertoroidal_particle_filter.py @@ -1,3 +1,4 @@ +from typing import Union from pyrecest.backend import tile from pyrecest.backend import sum from pyrecest.backend import squeeze @@ -25,11 +26,10 @@ class HypertoroidalParticleFilter(AbstractParticleFilter, AbstractHypertoroidalFilter): - @beartype def __init__( self, - n_particles: int | int32 | int64, - dim: int | int32 | int64, + n_particles: Union[int, int32, int64], + dim: Union[int, int32, int64], ): assert np.isscalar(n_particles) assert n_particles > 1, "Use CircularParticleFilter for 1-D case" @@ -49,7 +49,6 @@ def __init__( AbstractHypertoroidalFilter.__init__(self, filter_state) AbstractParticleFilter.__init__(self, filter_state) - @beartype def set_state(self, new_state: AbstractHypertoroidalDistribution): if not isinstance(new_state, HypertoroidalDiracDistribution): # Convert to DiracDistribution if it is a different type of distribution @@ -59,7 +58,6 @@ def set_state(self, new_state: AbstractHypertoroidalDistribution): ) self.filter_state = copy.deepcopy(new_state) - @beartype def predict_nonlinear( self, f: Callable, @@ -76,7 +74,6 @@ def predict_nonlinear( self.filter_state.d += squeeze(noise) self.filter_state.d = mod(self.filter_state.d, 2 * np.pi) - @beartype def predict_nonlinear_nonadditive( self, f: Callable, samples: np.ndarray, weights: np.ndarray ): @@ -90,4 +87,4 @@ def predict_nonlinear_nonadditive( d = zeros_like(self.filter_state) for i in range(n): d[i, :] = f(self.filter_state[i, :], samples[noise_ids[i, :]]) - self.filter_state = d + self.filter_state = d \ No newline at end of file diff --git a/pyrecest/filters/kalman_filter.py b/pyrecest/filters/kalman_filter.py index a871f6f5..c49e0db9 100644 --- a/pyrecest/filters/kalman_filter.py +++ b/pyrecest/filters/kalman_filter.py @@ -8,7 +8,6 @@ class KalmanFilter(AbstractEuclideanFilter): - @beartype def __init__( self, initial_state: GaussianDistribution | tuple[np.ndarray, np.ndarray] ): @@ -36,7 +35,6 @@ def filter_state( return GaussianDistribution(self._filter_state.x, self._filter_state.P) @filter_state.setter - @beartype def filter_state( self, new_state: GaussianDistribution | tuple[np.ndarray, np.ndarray] ): @@ -56,7 +54,6 @@ def filter_state( "new_state must be a GaussianDistribution or a tuple of (mean, covariance)" ) - @beartype def predict_identity(self, sys_noise_cov: np.ndarray, sys_input: np.ndarray = None): """ Predicts the next state assuming identity transition matrix. @@ -68,7 +65,6 @@ def predict_identity(self, sys_noise_cov: np.ndarray, sys_input: np.ndarray = No B = eye(system_matrix.shape[0]) if sys_input is not None else None self._filter_state.predict(F=system_matrix, Q=sys_noise_cov, B=B, u=sys_input) - @beartype def predict_linear( self, system_matrix: np.ndarray, @@ -90,7 +86,6 @@ def predict_linear( B = eye(system_matrix.shape[0]) if sys_input is not None else None self._filter_state.predict(F=system_matrix, Q=sys_noise_cov, B=B, u=sys_input) - @beartype def update_identity(self, meas_noise: np.ndarray, measurement: np.ndarray): """ Update the filter state with measurement, assuming identity measurement matrix. @@ -104,7 +99,6 @@ def update_identity(self, meas_noise: np.ndarray, measurement: np.ndarray): meas_noise=meas_noise, ) - @beartype def update_linear( self, measurement: np.ndarray, @@ -121,7 +115,6 @@ def update_linear( self._filter_state.dim_z = measurement_matrix.shape[0] self._filter_state.update(z=measurement, R=meas_noise, H=measurement_matrix) - @beartype def get_point_estimate(self) -> np.ndarray: """Returns the mean of the current filter state.""" - return self._filter_state.x + return self._filter_state.x \ No newline at end of file diff --git a/pyrecest/filters/lin_bounded_particle_filter.py b/pyrecest/filters/lin_bounded_particle_filter.py index 3b7aca72..d9cd11b3 100644 --- a/pyrecest/filters/lin_bounded_particle_filter.py +++ b/pyrecest/filters/lin_bounded_particle_filter.py @@ -3,4 +3,4 @@ class LinBoundedParticleFilter(AbstractParticleFilter, AbstractLinBoundedFilter): - pass + pass \ No newline at end of file diff --git a/pyrecest/filters/lin_periodic_particle_filter.py b/pyrecest/filters/lin_periodic_particle_filter.py index 07613769..f0746417 100644 --- a/pyrecest/filters/lin_periodic_particle_filter.py +++ b/pyrecest/filters/lin_periodic_particle_filter.py @@ -2,4 +2,4 @@ class LinPeriodicParticleFilter(LinBoundedParticleFilter): - pass + pass \ No newline at end of file diff --git a/pyrecest/filters/random_matrix_tracker.py b/pyrecest/filters/random_matrix_tracker.py index 2ef04c3c..f6381125 100644 --- a/pyrecest/filters/random_matrix_tracker.py +++ b/pyrecest/filters/random_matrix_tracker.py @@ -102,4 +102,4 @@ def plot_point_estimate(self, scaling_factor=1, color=(0, 0.4470, 0.7410)): before plotting.""" ) position_estimate = self.kinematic_state_to_pos_matrix @ self.kinematic_state - plot_ellipsoid(position_estimate, self.extent, scaling_factor, color) + plot_ellipsoid(position_estimate, self.extent, scaling_factor, color) \ No newline at end of file diff --git a/pyrecest/filters/toroidal_particle_filter.py b/pyrecest/filters/toroidal_particle_filter.py index 5c830756..dd0cdf72 100644 --- a/pyrecest/filters/toroidal_particle_filter.py +++ b/pyrecest/filters/toroidal_particle_filter.py @@ -1,3 +1,4 @@ +from typing import Union from pyrecest.backend import int64 from pyrecest.backend import int32 import numpy as np @@ -7,6 +8,5 @@ class ToroidalParticleFilter(HypertoroidalParticleFilter): - @beartype - def __init__(self, n_particles: int | int32 | int64): - HypertoroidalParticleFilter.__init__(self, n_particles, 2) + def __init__(self, n_particles: Union[int, int32, int64]): + HypertoroidalParticleFilter.__init__(self, n_particles, 2) \ No newline at end of file diff --git a/pyrecest/filters/toroidal_wrapped_normal_filter.py b/pyrecest/filters/toroidal_wrapped_normal_filter.py index 24b7f4a4..29f34815 100644 --- a/pyrecest/filters/toroidal_wrapped_normal_filter.py +++ b/pyrecest/filters/toroidal_wrapped_normal_filter.py @@ -16,4 +16,4 @@ def __init__(self): def predict_identity(self, twn_sys): assert isinstance(twn_sys, ToroidalWrappedNormalDistribution) - self.filter_state = self.filter_state.convolve(twn_sys) + self.filter_state = self.filter_state.convolve(twn_sys) \ No newline at end of file diff --git a/pyrecest/filters/von_mises_filter.py b/pyrecest/filters/von_mises_filter.py index 78d05597..8ec91630 100644 --- a/pyrecest/filters/von_mises_filter.py +++ b/pyrecest/filters/von_mises_filter.py @@ -28,7 +28,6 @@ def __init__(self): """ AbstractCircularFilter.__init__(self, VonMisesDistribution(0, 1)) - @beartype def set_state(self, new_state: VonMisesDistribution): """ Sets the current system state @@ -38,7 +37,6 @@ def set_state(self, new_state: VonMisesDistribution): """ self.filter_state = copy.deepcopy(new_state) - @beartype def predict_identity(self, vmSys: VonMisesDistribution): """ Predicts assuming identity system model, i.e., @@ -50,7 +48,6 @@ def predict_identity(self, vmSys: VonMisesDistribution): """ self.filter_state = self.filter_state.convolve(vmSys) - @beartype def update_identity(self, vmMeas: VonMisesDistribution, z=0.0): """ Updates assuming identity measurement model, i.e., @@ -73,4 +70,4 @@ def update_identity(self, vmMeas: VonMisesDistribution, z=0.0): muWnew = mod(z - vmMeas.mu, 2 * np.pi) vmMeasShifted = VonMisesDistribution(muWnew, vmMeas.kappa) - self.filter_state = self.filter_state.multiply(vmMeasShifted) + self.filter_state = self.filter_state.multiply(vmMeasShifted) \ No newline at end of file diff --git a/pyrecest/filters/von_mises_fisher_filter.py b/pyrecest/filters/von_mises_fisher_filter.py index 1c69184d..fa0570db 100644 --- a/pyrecest/filters/von_mises_fisher_filter.py +++ b/pyrecest/filters/von_mises_fisher_filter.py @@ -49,4 +49,4 @@ def update_identity(self, meas_noise, z): ), "Dimension mismatch between measurement and state." assert ndim(z) == 1, "z should be a vector." meas_noise.mu = z - self.filter_state = self.filter_state.multiply(meas_noise) + self.filter_state = self.filter_state.multiply(meas_noise) \ No newline at end of file diff --git a/pyrecest/filters/wrapped_normal_filter.py b/pyrecest/filters/wrapped_normal_filter.py index 4f2b5669..c970d67e 100644 --- a/pyrecest/filters/wrapped_normal_filter.py +++ b/pyrecest/filters/wrapped_normal_filter.py @@ -72,4 +72,4 @@ def update_nonlinear_progressive( wd_new = wd.reweigh(lambda x: likelihood(z, x) ** current_lambda) self.filter_state = wd_new.to_wn() lambda_ = lambda_ - current_lambda - steps += 1 + steps += 1 \ No newline at end of file diff --git a/pyrecest/sampling/__init__.py b/pyrecest/sampling/__init__.py index 9249ae3b..fd4498fa 100644 --- a/pyrecest/sampling/__init__.py +++ b/pyrecest/sampling/__init__.py @@ -2,4 +2,4 @@ __all__ = [ "AbstractSampler", -] +] \ No newline at end of file diff --git a/pyrecest/sampling/abstract_sampler.py b/pyrecest/sampling/abstract_sampler.py index 502adff2..b55366da 100644 --- a/pyrecest/sampling/abstract_sampler.py +++ b/pyrecest/sampling/abstract_sampler.py @@ -6,4 +6,4 @@ class AbstractSampler(ABC): @abstractmethod def sample_stochastic(self, n_samples: int, dim: int) -> np.ndarray: - raise NotImplementedError("Abstract method not implemented!") + raise NotImplementedError("Abstract method not implemented!") \ No newline at end of file diff --git a/pyrecest/sampling/euclidean_sampler.py b/pyrecest/sampling/euclidean_sampler.py index 57bd009e..97ec56b2 100644 --- a/pyrecest/sampling/euclidean_sampler.py +++ b/pyrecest/sampling/euclidean_sampler.py @@ -12,4 +12,4 @@ class AbstractEuclideanSampler(AbstractSampler): class GaussianSampler(AbstractEuclideanSampler): def sample_stochastic(self, n_samples: int, dim: int) -> np.ndarray: - return GaussianDistribution(zeros(dim), eye(dim)).sample(n_samples) + return GaussianDistribution(zeros(dim), eye(dim)).sample(n_samples) \ No newline at end of file diff --git a/pyrecest/sampling/hyperspherical_sampler.py b/pyrecest/sampling/hyperspherical_sampler.py index 49df1926..617f80c1 100644 --- a/pyrecest/sampling/hyperspherical_sampler.py +++ b/pyrecest/sampling/hyperspherical_sampler.py @@ -21,7 +21,6 @@ from .hypertoroidal_sampler import CircularUniformSampler -@beartype def get_grid_hypersphere(method: str, grid_density_parameter: int): if method == "healpix": samples, grid_specific_description = HealpixSampler().get_grid( @@ -49,7 +48,6 @@ def get_grid_hypersphere(method: str, grid_density_parameter: int): class AbstractHypersphericalUniformSampler(AbstractSampler): - @beartype def sample_stochastic(self, n_samples: int, dim: int) -> np.ndarray: return HypersphericalUniformDistribution(dim).sample(n_samples) @@ -73,7 +71,6 @@ def get_grid_spherical_coordinates( ) -> tuple[np.ndarray, np.ndarray, dict]: raise NotImplementedError() - @beartype def get_grid(self, grid_density_parameter: int) -> tuple[np.ndarray, dict]: phi, theta, grid_specific_description = self.get_grid_spherical_coordinates( grid_density_parameter @@ -85,7 +82,6 @@ def get_grid(self, grid_density_parameter: int) -> tuple[np.ndarray, dict]: class HealpixSampler(AbstractHypersphericalUniformSampler): - @beartype def get_grid(self, grid_density_parameter: int) -> tuple[np.ndarray, dict]: import healpy as hp @@ -103,7 +99,6 @@ def get_grid(self, grid_density_parameter: int) -> tuple[np.ndarray, dict]: class DriscollHealySampler(AbstractSphericalCoordinatesBasedSampler): - @beartype def get_grid_spherical_coordinates( self, grid_density_parameter: int ) -> tuple[np.ndarray, np.ndarray, dict]: @@ -134,7 +129,6 @@ def get_grid_spherical_coordinates( class SphericalFibonacciSampler(AbstractSphericalCoordinatesBasedSampler): - @beartype def get_grid_spherical_coordinates( self, grid_density_parameter: int ) -> tuple[np.ndarray, np.ndarray, dict]: @@ -150,7 +144,6 @@ def get_grid_spherical_coordinates( class AbstractHopfBasedS3Sampler(AbstractHypersphericalUniformSampler): @staticmethod - @beartype def hopf_coordinates_to_quaterion_yershova( θ: np.ndarray, ϕ: np.ndarray, ψ: np.ndarray ): @@ -171,7 +164,6 @@ def hopf_coordinates_to_quaterion_yershova( return quaterions @staticmethod - @beartype def quaternion_to_hopf_yershova(q: np.ndarray): θ = 2 * arccos(sqrt(q[:, 0] ** 2 + q[:, 1] ** 2)) ϕ = arctan2(q[:, 3], q[:, 2]) - arctan2(q[:, 1], q[:, 0]) @@ -181,7 +173,6 @@ def quaternion_to_hopf_yershova(q: np.ndarray): # pylint: disable=too-many-locals class HealpixHopfSampler(AbstractHopfBasedS3Sampler): - @beartype def get_grid(self, grid_density_parameter: int | list[int]): """ Hopf coordinates are (θ, ϕ, ψ) where θ and ϕ are the angles for the sphere and ψ is the angle on the circle @@ -232,7 +223,6 @@ def get_grid(self, grid_density_parameter: int | list[int]): class FibonacciHopfSampler(AbstractHopfBasedS3Sampler): - @beartype def get_grid(self, grid_density_parameter: int | list[int]): """ Hopf coordinates are (θ, ϕ, ψ) where θ and ϕ are the angles for the sphere and ψ is the angle on the circle @@ -275,4 +265,4 @@ def get_grid(self, grid_density_parameter: int | list[int]): "scheme": "fibonacci_hopf", "layer-parameter": grid_density_parameter, } - return grid, grid_specific_description + return grid, grid_specific_description \ No newline at end of file diff --git a/pyrecest/sampling/hypertoroidal_sampler.py b/pyrecest/sampling/hypertoroidal_sampler.py index ed28460b..4ae72546 100644 --- a/pyrecest/sampling/hypertoroidal_sampler.py +++ b/pyrecest/sampling/hypertoroidal_sampler.py @@ -15,11 +15,9 @@ class AbstractCircularSampler(AbstractHypertoroidalSampler): class CircularUniformSampler(AbstractCircularSampler): - @beartype def sample_stochastic(self, n_samples: int): return CircularUniformDistribution().sample(n_samples) - @beartype def get_grid(self, grid_density_parameter: int) -> np.ndarray: """ Returns an equidistant grid of points on the circle [0,2*pi). @@ -27,4 +25,4 @@ def get_grid(self, grid_density_parameter: int) -> np.ndarray: points = linspace(0, 2 * np.pi, grid_density_parameter, endpoint=False) # Set it to the middle of the interval instead of the start points += (2 * np.pi / grid_density_parameter) / 2 - return points + return points \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_abstract_circular_distribution.py b/pyrecest/tests/distributions/test_abstract_circular_distribution.py index d21d678a..54741e31 100644 --- a/pyrecest/tests/distributions/test_abstract_circular_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_circular_distribution.py @@ -74,4 +74,4 @@ def test_integral_numerical(self): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py b/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py index fb107a25..130ad295 100644 --- a/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py @@ -77,4 +77,4 @@ def test_condition_on_linear(self): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_abstract_hyperhemispherical_distribution.py b/pyrecest/tests/distributions/test_abstract_hyperhemispherical_distribution.py index 9a4e565f..2b3806b3 100644 --- a/pyrecest/tests/distributions/test_abstract_hyperhemispherical_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hyperhemispherical_distribution.py @@ -52,4 +52,4 @@ def test_sample_metropolis_hastings_basics_only(self): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_abstract_hypersphere_subset_distribution.py b/pyrecest/tests/distributions/test_abstract_hypersphere_subset_distribution.py index cf7a3a5f..6fa1d71c 100644 --- a/pyrecest/tests/distributions/test_abstract_hypersphere_subset_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hypersphere_subset_distribution.py @@ -81,4 +81,4 @@ def fangles_3d(phi1, phi2, phi3): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_abstract_hyperspherical_distribution.py b/pyrecest/tests/distributions/test_abstract_hyperspherical_distribution.py index 04910e25..6ed406f1 100644 --- a/pyrecest/tests/distributions/test_abstract_hyperspherical_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hyperspherical_distribution.py @@ -65,4 +65,4 @@ def test_plotting_error_free_2d(self): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_abstract_hypertoroidal_distribution.py b/pyrecest/tests/distributions/test_abstract_hypertoroidal_distribution.py index 942f3835..5d6e699c 100644 --- a/pyrecest/tests/distributions/test_abstract_hypertoroidal_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hypertoroidal_distribution.py @@ -15,4 +15,4 @@ def test_angular_error(self): np.testing.assert_allclose( AbstractHypertoroidalDistribution.angular_error(np.pi / 4, 7 * np.pi / 4), np.pi / 2, - ) + ) \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_abstract_linear_distribution.py b/pyrecest/tests/distributions/test_abstract_linear_distribution.py index 62fb8e1f..fe0ad6f3 100644 --- a/pyrecest/tests/distributions/test_abstract_linear_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_linear_distribution.py @@ -81,4 +81,4 @@ def test_plot_state_r2(self): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_abstract_mixture.py b/pyrecest/tests/distributions/test_abstract_mixture.py index 3f9427fc..eb00f755 100644 --- a/pyrecest/tests/distributions/test_abstract_mixture.py +++ b/pyrecest/tests/distributions/test_abstract_mixture.py @@ -50,4 +50,4 @@ def test_sample_metropolis_hastings_basics_only_h2(self): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_bingham_distribution.py b/pyrecest/tests/distributions/test_bingham_distribution.py index fcc778f2..7d61b820 100644 --- a/pyrecest/tests/distributions/test_bingham_distribution.py +++ b/pyrecest/tests/distributions/test_bingham_distribution.py @@ -37,4 +37,4 @@ def test_pdf(self): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_circular_fourier_distribution.py b/pyrecest/tests/distributions/test_circular_fourier_distribution.py index 369c8ac2..db39b61a 100644 --- a/pyrecest/tests/distributions/test_circular_fourier_distribution.py +++ b/pyrecest/tests/distributions/test_circular_fourier_distribution.py @@ -202,4 +202,4 @@ def test_distance(self, mult_by_n): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_circular_uniform_distribution.py b/pyrecest/tests/distributions/test_circular_uniform_distribution.py index f7fdb9b2..3ff665ed 100644 --- a/pyrecest/tests/distributions/test_circular_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_circular_uniform_distribution.py @@ -77,4 +77,4 @@ def test_sampling(self): cu = CircularUniformDistribution() n = 10 s = cu.sample(n) - np.testing.assert_allclose(s.shape[0], n) + np.testing.assert_allclose(s.shape[0], n) \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_custom_hemispherical_distribution.py b/pyrecest/tests/distributions/test_custom_hemispherical_distribution.py index 49c84ae6..f51bf8b7 100644 --- a/pyrecest/tests/distributions/test_custom_hemispherical_distribution.py +++ b/pyrecest/tests/distributions/test_custom_hemispherical_distribution.py @@ -71,4 +71,4 @@ def test_warning_asymmetric(self): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py b/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py index 04f4fc3f..0b20c220 100644 --- a/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py +++ b/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py @@ -58,4 +58,4 @@ def test_condition_on_periodic(self): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_custom_hyperrectangular_distribution.py b/pyrecest/tests/distributions/test_custom_hyperrectangular_distribution.py index 198170ee..5ec3b0cb 100644 --- a/pyrecest/tests/distributions/test_custom_hyperrectangular_distribution.py +++ b/pyrecest/tests/distributions/test_custom_hyperrectangular_distribution.py @@ -41,4 +41,4 @@ def test_pdf_method(self): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_custom_hyperspherical_distribution.py b/pyrecest/tests/distributions/test_custom_hyperspherical_distribution.py index 414fa07e..2bdc9858 100644 --- a/pyrecest/tests/distributions/test_custom_hyperspherical_distribution.py +++ b/pyrecest/tests/distributions/test_custom_hyperspherical_distribution.py @@ -55,4 +55,4 @@ def test_from_distribution(self): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_custom_linear_distribution.py b/pyrecest/tests/distributions/test_custom_linear_distribution.py index 7ab41c62..8300a9b4 100644 --- a/pyrecest/tests/distributions/test_custom_linear_distribution.py +++ b/pyrecest/tests/distributions/test_custom_linear_distribution.py @@ -39,4 +39,4 @@ def verify_pdf_equal(dist1, dist2, tol): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_disk_uniform_distribution.py b/pyrecest/tests/distributions/test_disk_uniform_distribution.py index fd2af46f..b923701a 100644 --- a/pyrecest/tests/distributions/test_disk_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_disk_uniform_distribution.py @@ -39,4 +39,4 @@ def test_pdf(self): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_ellipsoidal_ball_uniform_distribution.py b/pyrecest/tests/distributions/test_ellipsoidal_ball_uniform_distribution.py index c15ad3c3..82f6ebe3 100644 --- a/pyrecest/tests/distributions/test_ellipsoidal_ball_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_ellipsoidal_ball_uniform_distribution.py @@ -24,4 +24,4 @@ def test_sampling(self): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_gaussian_distribution.py b/pyrecest/tests/distributions/test_gaussian_distribution.py index ea9ff5d9..177a7720 100644 --- a/pyrecest/tests/distributions/test_gaussian_distribution.py +++ b/pyrecest/tests/distributions/test_gaussian_distribution.py @@ -84,4 +84,4 @@ def integrand(y, x): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_hemispherical_uniform_distribution.py b/pyrecest/tests/distributions/test_hemispherical_uniform_distribution.py index 70663f8d..5823360b 100644 --- a/pyrecest/tests/distributions/test_hemispherical_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_hemispherical_uniform_distribution.py @@ -26,4 +26,4 @@ def test_pdf_2d(self): hhud.pdf(points), ones(points.shape[0]) / (2 * np.pi), atol=1e-6 ) ) - # jscpd:ignore-end + # jscpd:ignore-end \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py b/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py index d3b49f8d..e9998cde 100644 --- a/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py @@ -105,4 +105,4 @@ def test_from_distribution(self): C = wishart.rvs(df, scale, random_state=random_gen) hwn = PartiallyWrappedNormalDistribution(array([1, 2, 3, 4]), C, 2) hddist = HypercylindricalDiracDistribution.from_distribution(hwn, 100000) - np.testing.assert_allclose(hddist.hybrid_mean(), hwn.hybrid_mean(), atol=0.15) + np.testing.assert_allclose(hddist.hybrid_mean(), hwn.hybrid_mean(), atol=0.15) \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_hyperhemispherical_uniform_distribution.py b/pyrecest/tests/distributions/test_hyperhemispherical_uniform_distribution.py index cbbd6d26..476159e3 100644 --- a/pyrecest/tests/distributions/test_hyperhemispherical_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_hyperhemispherical_uniform_distribution.py @@ -53,4 +53,4 @@ def test_integrate_S3(self): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py b/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py index 1f359c2a..f63a142a 100644 --- a/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py @@ -72,4 +72,4 @@ def test_from_distribution(self): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_hyperspherical_mixture.py b/pyrecest/tests/distributions/test_hyperspherical_mixture.py index 8da16d3e..29524c5e 100644 --- a/pyrecest/tests/distributions/test_hyperspherical_mixture.py +++ b/pyrecest/tests/distributions/test_hyperspherical_mixture.py @@ -54,4 +54,4 @@ def test_pdf_4d(self): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_hyperspherical_uniform_distribution.py b/pyrecest/tests/distributions/test_hyperspherical_uniform_distribution.py index c637f2b8..c556219c 100644 --- a/pyrecest/tests/distributions/test_hyperspherical_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_hyperspherical_uniform_distribution.py @@ -47,4 +47,4 @@ def test_sample(self): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py b/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py index 5f28e6c3..ef09acfd 100644 --- a/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py @@ -122,4 +122,4 @@ def test_marginalization(self): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_hypertoroidal_wrapped_normal_distribution.py b/pyrecest/tests/distributions/test_hypertoroidal_wrapped_normal_distribution.py index 9eee518a..734885a0 100644 --- a/pyrecest/tests/distributions/test_hypertoroidal_wrapped_normal_distribution.py +++ b/pyrecest/tests/distributions/test_hypertoroidal_wrapped_normal_distribution.py @@ -22,4 +22,4 @@ def test_pdf(self): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_linear_dirac_distribution.py b/pyrecest/tests/distributions/test_linear_dirac_distribution.py index 48a45b52..4e05d3f5 100644 --- a/pyrecest/tests/distributions/test_linear_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_linear_dirac_distribution.py @@ -30,4 +30,4 @@ def test_mean_and_cov(self): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_linear_mixture.py b/pyrecest/tests/distributions/test_linear_mixture.py index 428b18b8..0f764856 100644 --- a/pyrecest/tests/distributions/test_linear_mixture.py +++ b/pyrecest/tests/distributions/test_linear_mixture.py @@ -44,4 +44,4 @@ def test_pdf(self): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_partially_wrapped_normal_distribution.py b/pyrecest/tests/distributions/test_partially_wrapped_normal_distribution.py index a73b9255..6b33354d 100644 --- a/pyrecest/tests/distributions/test_partially_wrapped_normal_distribution.py +++ b/pyrecest/tests/distributions/test_partially_wrapped_normal_distribution.py @@ -35,4 +35,4 @@ def test_hybrid_moment_2d(self): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_se3_dirac_distribution.py b/pyrecest/tests/distributions/test_se3_dirac_distribution.py index 1c750c4c..a77e57a8 100644 --- a/pyrecest/tests/distributions/test_se3_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_se3_dirac_distribution.py @@ -42,4 +42,4 @@ def test_from_distribution(self): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_sphere_subset_distribution.py b/pyrecest/tests/distributions/test_sphere_subset_distribution.py index 4da5380a..9c96bf88 100644 --- a/pyrecest/tests/distributions/test_sphere_subset_distribution.py +++ b/pyrecest/tests/distributions/test_sphere_subset_distribution.py @@ -57,4 +57,4 @@ def test_sph_to_cart_to_sph(self, mode): # The new spherical coordinates should be close to the original ones np.testing.assert_allclose(azimuth_new, azimuth, atol=1e-15) - np.testing.assert_allclose(theta_new, theta, atol=1e-15) + np.testing.assert_allclose(theta_new, theta, atol=1e-15) \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py index 4aaa74db..3350f6b1 100644 --- a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py +++ b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py @@ -1046,4 +1046,4 @@ def test_mean(self, _, coeff_mat, expected_output): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py index 65e7fcbe..20306cce 100644 --- a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py +++ b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py @@ -362,4 +362,4 @@ def test_integral_analytical(self): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_toroidal_uniform_distribution.py b/pyrecest/tests/distributions/test_toroidal_uniform_distribution.py index 5580fac0..ac9e7ea0 100644 --- a/pyrecest/tests/distributions/test_toroidal_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_toroidal_uniform_distribution.py @@ -78,4 +78,4 @@ def test_sampling(self): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_toroidal_von_mises_sine_distribution.py b/pyrecest/tests/distributions/test_toroidal_von_mises_sine_distribution.py index 84fe6643..a2ef2f33 100644 --- a/pyrecest/tests/distributions/test_toroidal_von_mises_sine_distribution.py +++ b/pyrecest/tests/distributions/test_toroidal_von_mises_sine_distribution.py @@ -76,4 +76,4 @@ def pdf(x): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_toroidal_wrapped_normal_distribution.py b/pyrecest/tests/distributions/test_toroidal_wrapped_normal_distribution.py index 992ba566..66bb23ec 100644 --- a/pyrecest/tests/distributions/test_toroidal_wrapped_normal_distribution.py +++ b/pyrecest/tests/distributions/test_toroidal_wrapped_normal_distribution.py @@ -35,4 +35,4 @@ def test_sampling(self): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_von_mises_distribution.py b/pyrecest/tests/distributions/test_von_mises_distribution.py index 6e672081..74694b00 100644 --- a/pyrecest/tests/distributions/test_von_mises_distribution.py +++ b/pyrecest/tests/distributions/test_von_mises_distribution.py @@ -42,4 +42,4 @@ def test_plot(self): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py b/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py index e768c10c..7862295d 100644 --- a/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py +++ b/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py @@ -204,4 +204,4 @@ def test_from_distribution_dirac(self): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_watson_distribution.py b/pyrecest/tests/distributions/test_watson_distribution.py index e27f9dda..7caeba1a 100644 --- a/pyrecest/tests/distributions/test_watson_distribution.py +++ b/pyrecest/tests/distributions/test_watson_distribution.py @@ -63,4 +63,4 @@ def test_to_bingham(self): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_wrapped_cauchy_distribution.py b/pyrecest/tests/distributions/test_wrapped_cauchy_distribution.py index 3a1164a9..ca6bb41b 100644 --- a/pyrecest/tests/distributions/test_wrapped_cauchy_distribution.py +++ b/pyrecest/tests/distributions/test_wrapped_cauchy_distribution.py @@ -44,4 +44,4 @@ def test_cdf(self): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_wrapped_laplace_distribution.py b/pyrecest/tests/distributions/test_wrapped_laplace_distribution.py index 5ce70ad3..55d0287e 100644 --- a/pyrecest/tests/distributions/test_wrapped_laplace_distribution.py +++ b/pyrecest/tests/distributions/test_wrapped_laplace_distribution.py @@ -61,4 +61,4 @@ def test_periodicity(self): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_wrapped_normal_distribution.py b/pyrecest/tests/distributions/test_wrapped_normal_distribution.py index 9ab1099d..b36e4e8c 100644 --- a/pyrecest/tests/distributions/test_wrapped_normal_distribution.py +++ b/pyrecest/tests/distributions/test_wrapped_normal_distribution.py @@ -59,4 +59,4 @@ def test_pdf_with_large_sigma_is_uniform(self): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/filters/test_circular_particle_filter.py b/pyrecest/tests/filters/test_circular_particle_filter.py index 4260ee00..753c2d22 100644 --- a/pyrecest/tests/filters/test_circular_particle_filter.py +++ b/pyrecest/tests/filters/test_circular_particle_filter.py @@ -144,4 +144,4 @@ def likelihood2(x): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/filters/test_euclidean_particle_filter.py b/pyrecest/tests/filters/test_euclidean_particle_filter.py index a67ad910..b003aef7 100644 --- a/pyrecest/tests/filters/test_euclidean_particle_filter.py +++ b/pyrecest/tests/filters/test_euclidean_particle_filter.py @@ -71,4 +71,4 @@ def test_predict_update_cycle_3d_forced_particle_pos_no_pred(self): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/filters/test_global_nearest_neighbor.py b/pyrecest/tests/filters/test_global_nearest_neighbor.py index 77e94379..5b3859ba 100644 --- a/pyrecest/tests/filters/test_global_nearest_neighbor.py +++ b/pyrecest/tests/filters/test_global_nearest_neighbor.py @@ -311,4 +311,4 @@ def test_update_with_and_without_clutter(self): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py b/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py index e8ae763c..dda61fc6 100644 --- a/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py +++ b/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py @@ -47,4 +47,4 @@ def test_predict_update_cycle_3D(self): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/filters/test_kalman_filter.py b/pyrecest/tests/filters/test_kalman_filter.py index c17b4df3..1d075222 100644 --- a/pyrecest/tests/filters/test_kalman_filter.py +++ b/pyrecest/tests/filters/test_kalman_filter.py @@ -61,4 +61,4 @@ def test_predict_linear_2d(self): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/filters/test_random_matrix_tracker.py b/pyrecest/tests/filters/test_random_matrix_tracker.py index 40cc30da..76ac0786 100644 --- a/pyrecest/tests/filters/test_random_matrix_tracker.py +++ b/pyrecest/tests/filters/test_random_matrix_tracker.py @@ -140,4 +140,4 @@ def test_draw_extent_3d(self, mock_show): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/filters/test_toroidal_particle_filter.py b/pyrecest/tests/filters/test_toroidal_particle_filter.py index c5ed5a66..3a05e601 100644 --- a/pyrecest/tests/filters/test_toroidal_particle_filter.py +++ b/pyrecest/tests/filters/test_toroidal_particle_filter.py @@ -37,4 +37,4 @@ def test_toroidal_particle_filter(self): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/filters/test_toroidal_wrapped_normal_filter.py b/pyrecest/tests/filters/test_toroidal_wrapped_normal_filter.py index 5c843d0e..51db8ea3 100644 --- a/pyrecest/tests/filters/test_toroidal_wrapped_normal_filter.py +++ b/pyrecest/tests/filters/test_toroidal_wrapped_normal_filter.py @@ -35,4 +35,4 @@ def test_predict_identity(self): np.testing.assert_array_almost_equal( dist_result.mu, mod(self.twn.mu + self.twn.mu, 2 * np.pi) ) - np.testing.assert_array_almost_equal(dist_result.C, self.twn.C + self.twn.C) + np.testing.assert_array_almost_equal(dist_result.C, self.twn.C + self.twn.C) \ No newline at end of file diff --git a/pyrecest/tests/filters/test_von_mises_filter.py b/pyrecest/tests/filters/test_von_mises_filter.py index 7970c29d..38c4229d 100644 --- a/pyrecest/tests/filters/test_von_mises_filter.py +++ b/pyrecest/tests/filters/test_von_mises_filter.py @@ -41,4 +41,4 @@ def test_update(self): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/filters/test_von_mises_fisher_filter.py b/pyrecest/tests/filters/test_von_mises_fisher_filter.py index 21fe2667..2d2ab614 100644 --- a/pyrecest/tests/filters/test_von_mises_fisher_filter.py +++ b/pyrecest/tests/filters/test_von_mises_fisher_filter.py @@ -46,4 +46,4 @@ def test_update_identity(self): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/filters/test_wrapped_normal_filter.py b/pyrecest/tests/filters/test_wrapped_normal_filter.py index 87a1d309..a8042661 100644 --- a/pyrecest/tests/filters/test_wrapped_normal_filter.py +++ b/pyrecest/tests/filters/test_wrapped_normal_filter.py @@ -51,4 +51,4 @@ def test_update(self): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/test_eot_shape_database.py b/pyrecest/tests/test_eot_shape_database.py index c5a6c15d..2c4d8ad1 100644 --- a/pyrecest/tests/test_eot_shape_database.py +++ b/pyrecest/tests/test_eot_shape_database.py @@ -80,4 +80,4 @@ def test_plotting(self): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/test_euclidean_sampler.py b/pyrecest/tests/test_euclidean_sampler.py index 5f09a433..fc05389a 100644 --- a/pyrecest/tests/test_euclidean_sampler.py +++ b/pyrecest/tests/test_euclidean_sampler.py @@ -33,4 +33,4 @@ def test_gaussian_properties(self): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/test_evaluation_basic.py b/pyrecest/tests/test_evaluation_basic.py index b5e1ab69..6515b667 100644 --- a/pyrecest/tests/test_evaluation_basic.py +++ b/pyrecest/tests/test_evaluation_basic.py @@ -539,4 +539,4 @@ def test_summarize_filter_results(self): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/test_hyperspherical_sampler.py b/pyrecest/tests/test_hyperspherical_sampler.py index b5e759cd..baff99ca 100644 --- a/pyrecest/tests/test_hyperspherical_sampler.py +++ b/pyrecest/tests/test_hyperspherical_sampler.py @@ -138,4 +138,4 @@ def test_conversion(self): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/test_hypertoroidal_sampler.py b/pyrecest/tests/test_hypertoroidal_sampler.py index 84acfd8e..81ffa6d6 100644 --- a/pyrecest/tests/test_hypertoroidal_sampler.py +++ b/pyrecest/tests/test_hypertoroidal_sampler.py @@ -38,4 +38,4 @@ def test_get_grid(self): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/tests/test_metrics.py b/pyrecest/tests/test_metrics.py index 0c9c9127..ac81e972 100644 --- a/pyrecest/tests/test_metrics.py +++ b/pyrecest/tests/test_metrics.py @@ -38,4 +38,4 @@ def test_ANEES_is_close_to_one(self): if __name__ == "__main__": - unittest.main() + unittest.main() \ No newline at end of file diff --git a/pyrecest/utils/metrics.py b/pyrecest/utils/metrics.py index 5dacdea3..c07f63ce 100644 --- a/pyrecest/utils/metrics.py +++ b/pyrecest/utils/metrics.py @@ -16,4 +16,4 @@ def anees(estimates, uncertainties, groundtruths): error = estimates[i] - groundtruths[i] NEES[i] = error.T @ np.linalg.solve(uncertainties[i], error) - return mean(NEES) + return mean(NEES) \ No newline at end of file diff --git a/pyrecest/utils/plotting.py b/pyrecest/utils/plotting.py index 711c1966..eda0e697 100644 --- a/pyrecest/utils/plotting.py +++ b/pyrecest/utils/plotting.py @@ -52,4 +52,4 @@ def plot_ellipsoid_3d(center, shape_matrix, scaling_factor=1, color="blue"): linewidth=0, antialiased=False, ) - plt.show() + plt.show() \ No newline at end of file diff --git a/requirements-dev.txt b/requirements-dev.txt index 13540459..a5dc8137 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -49,5 +49,5 @@ torch==2.1.0 ; python_version >= "3.10" and python_version < "3.13" tqdm==4.66.1 ; python_version >= "3.10" and python_version < "3.13" typing-extensions==4.8.0 ; python_version >= "3.10" and python_version < "3.13" tzdata==2023.3 ; python_version >= "3.10" and python_version < "3.13" -urllib3==2.0.6 ; python_version >= "3.10" and python_version < "3.13" +urllib3==2.0.7 ; python_version >= "3.10" and python_version < "3.13" xarray==2023.9.0 ; python_version >= "3.10" and python_version < "3.13" diff --git a/requirements.txt b/requirements.txt index 6fea30d8..9e5faa06 100644 --- a/requirements.txt +++ b/requirements.txt @@ -34,5 +34,5 @@ tomli==2.0.1 ; python_version >= "3.10" and python_version < "3.11" tqdm==4.66.1 ; python_version >= "3.10" and python_version < "3.13" typing-extensions==4.8.0 ; python_version >= "3.10" and python_version < "3.13" tzdata==2023.3 ; python_version >= "3.10" and python_version < "3.13" -urllib3==2.0.6 ; python_version >= "3.10" and python_version < "3.13" +urllib3==2.0.7 ; python_version >= "3.10" and python_version < "3.13" xarray==2023.9.0 ; python_version >= "3.10" and python_version < "3.13" From 0adc0909600f7a9ce904ae6cdc34fe34d6754aae Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 17 Oct 2023 20:04:12 +0100 Subject: [PATCH 012/232] Replaced np.random --- .../abstract_dirac_distribution.py | 3 ++- ...abstract_manifold_specific_distribution.py | 4 ++-- pyrecest/distributions/abstract_mixture.py | 3 ++- .../partially_wrapped_normal_distribution.py | 3 ++- .../circle/wrapped_normal_distribution.py | 3 ++- .../ellipsoidal_ball_uniform_distribution.py | 5 +++-- ...bstract_hyperhemispherical_distribution.py | 3 ++- .../abstract_hyperspherical_distribution.py | 3 ++- .../hyperspherical_uniform_distribution.py | 7 ++++--- .../abstract_hypertoroidal_distribution.py | 3 ++- .../hypertoroidal_uniform_distribution.py | 3 ++- ...pertoroidal_wrapped_normal_distribution.py | 3 ++- .../abstract_linear_distribution.py | 3 ++- .../nonperiodic/gaussian_distribution.py | 3 ++- pyrecest/evaluation/eot_shape_database.py | 9 ++++---- pyrecest/evaluation/generate_measurements.py | 3 ++- .../generate_simulated_scenarios.py | 3 ++- pyrecest/filters/abstract_particle_filter.py | 3 ++- .../filters/hypertoroidal_particle_filter.py | 3 ++- .../test_custom_hemispherical_distribution.py | 5 +++-- ...st_custom_hypercylindrical_distribution.py | 3 ++- ...test_custom_hyperspherical_distribution.py | 5 +++-- ...est_hypercylindrical_dirac_distribution.py | 5 +++-- ...hyperhemispherical_uniform_distribution.py | 5 +++-- .../test_hyperspherical_dirac_distribution.py | 3 ++- ...est_hyperspherical_uniform_distribution.py | 5 +++-- .../test_hypertoroidal_dirac_distribution.py | 7 ++++--- .../test_linear_dirac_distribution.py | 5 +++-- ...pherical_harmonics_distribution_complex.py | 15 ++++++------- ...t_spherical_harmonics_distribution_real.py | 21 ++++++++++--------- .../filters/test_circular_particle_filter.py | 7 ++++--- .../filters/test_euclidean_particle_filter.py | 5 +++-- .../test_hypertoroidal_particle_filter.py | 3 ++- .../filters/test_toroidal_particle_filter.py | 3 ++- pyrecest/tests/test_euclidean_sampler.py | 3 ++- pyrecest/tests/test_evaluation_basic.py | 3 ++- pyrecest/tests/test_hyperspherical_sampler.py | 3 ++- pyrecest/tests/test_metrics.py | 3 ++- 38 files changed, 108 insertions(+), 71 deletions(-) diff --git a/pyrecest/distributions/abstract_dirac_distribution.py b/pyrecest/distributions/abstract_dirac_distribution.py index 90a43dd3..64776e61 100644 --- a/pyrecest/distributions/abstract_dirac_distribution.py +++ b/pyrecest/distributions/abstract_dirac_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import random from typing import Union from pyrecest.backend import sum from pyrecest.backend import ones @@ -80,7 +81,7 @@ def reweigh(self, f: Callable) -> "AbstractDiracDistribution": return dist def sample(self, n: Union[int, int32, int64]) -> np.ndarray: - ids = np.random.choice(np.size(self.w), size=n, p=self.w) + ids = random.choice(np.size(self.w), size=n, p=self.w) return self.d[ids] def entropy(self) -> float: diff --git a/pyrecest/distributions/abstract_manifold_specific_distribution.py b/pyrecest/distributions/abstract_manifold_specific_distribution.py index 089c17dc..03dfd474 100644 --- a/pyrecest/distributions/abstract_manifold_specific_distribution.py +++ b/pyrecest/distributions/abstract_manifold_specific_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import random from pyrecest.backend import squeeze from pyrecest.backend import int64 from pyrecest.backend import int32 @@ -90,7 +91,6 @@ def sample_metropolis_hastings( self.input_dim, ), ) - s.fill(np.nan) x = start_point i = 0 pdfx = self.pdf(x) @@ -99,7 +99,7 @@ def sample_metropolis_hastings( x_new = proposal(x) pdfx_new = self.pdf(x_new) a = pdfx_new / pdfx - if a.item() > 1 or a.item() > np.random.rand(): + if a.item() > 1 or a.item() > random.rand(1): s[i, :] = x_new.squeeze() x = x_new pdfx = pdfx_new diff --git a/pyrecest/distributions/abstract_mixture.py b/pyrecest/distributions/abstract_mixture.py index ffb466d4..e513012f 100644 --- a/pyrecest/distributions/abstract_mixture.py +++ b/pyrecest/distributions/abstract_mixture.py @@ -1,3 +1,4 @@ +from pyrecest.backend import random from typing import Union from pyrecest.backend import sum from pyrecest.backend import ones @@ -65,7 +66,7 @@ def input_dim(self) -> int: return self.dists[0].input_dim def sample(self, n: Union[int, int32, int64]) -> np.ndarray: - d = np.random.choice(len(self.w), size=n, p=self.w) + d = random.choice(len(self.w), size=n, p=self.w) occurrences = np.bincount(d, minlength=len(self.dists)) count = 0 diff --git a/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py b/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py index 0c13b2dd..4d306b58 100644 --- a/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py +++ b/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import random from typing import Union from pyrecest.backend import tile from pyrecest.backend import sum @@ -129,7 +130,7 @@ def sample(self, n: int): n (int): number of points to sample """ assert n > 0, "n must be positive" - s = np.random.multivariate_normal(self.mu, self.C, n) + s = random.multivariate_normal(self.mu, self.C, n) s[:, : self.bound_dim] = mod(s[:, : self.bound_dim], 2 * np.pi) # noqa: E203 return s diff --git a/pyrecest/distributions/circle/wrapped_normal_distribution.py b/pyrecest/distributions/circle/wrapped_normal_distribution.py index 1f403352..6bd7ef40 100644 --- a/pyrecest/distributions/circle/wrapped_normal_distribution.py +++ b/pyrecest/distributions/circle/wrapped_normal_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import random from typing import Union from pyrecest.backend import where from pyrecest.backend import squeeze @@ -139,7 +140,7 @@ def multiply_vm(self, other): return wn def sample(self, n: Union[int, int32, int64]) -> np.ndarray: - return mod(self.mu + self.sigma * np.random.randn(1, n), 2 * np.pi) + return mod(self.mu + self.sigma * random.randn(1, n), 2 * np.pi) def shift(self, shift_by): assert np.isscalar(shift_by) diff --git a/pyrecest/distributions/ellipsoidal_ball_uniform_distribution.py b/pyrecest/distributions/ellipsoidal_ball_uniform_distribution.py index 5bb69d44..5df52733 100644 --- a/pyrecest/distributions/ellipsoidal_ball_uniform_distribution.py +++ b/pyrecest/distributions/ellipsoidal_ball_uniform_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import random from typing import Union from pyrecest.backend import sqrt from pyrecest.backend import power @@ -71,10 +72,10 @@ def sample(self, n: Union[int, int32, int64]) -> np.ndarray: :param n: Number of samples to generate. :returns: Generated samples. """ - random_points = np.random.randn(n, self.dim) + random_points = random.randn(n, self.dim) random_points /= np.linalg.norm(random_points, axis=1, keepdims=True) - random_radii = np.random.rand(n, 1) + random_radii = random.rand(n, 1) random_radii = random_radii ** ( 1 / self.dim ) # Consider that the ellipsoid surfaces with higher radii are larger diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py index 507bdf30..a8c38b2e 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import random from typing import Union from pyrecest.backend import vstack from pyrecest.backend import ones @@ -146,7 +147,7 @@ def objective_function_2d(s): assert self.dim == 2, "Currently only implemented for 2D hemispheres." - s0 = np.random.rand(self.dim) * np.pi + s0 = random.rand(self.dim) * np.pi result = minimize( objective_function_2d, s0, diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py index 2391095f..52b41e22 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import random from typing import Union from pyrecest.backend import vstack from pyrecest.backend import sin @@ -188,7 +189,7 @@ def mode_numerical(self) -> np.ndarray: def fun(s): return -self.pdf(AbstractHypersphereSubsetDistribution.polar_to_cart(s)) - s0 = np.random.rand(self.dim) * np.pi + s0 = random.rand(self.dim) * np.pi res = minimize( fun, s0, diff --git a/pyrecest/distributions/hypersphere_subset/hyperspherical_uniform_distribution.py b/pyrecest/distributions/hypersphere_subset/hyperspherical_uniform_distribution.py index 3969ca50..97e718b3 100644 --- a/pyrecest/distributions/hypersphere_subset/hyperspherical_uniform_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/hyperspherical_uniform_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import random from typing import Union from pyrecest.backend import sqrt from pyrecest.backend import sin @@ -33,13 +34,13 @@ def sample(self, n: Union[int, int32, int64]): self.dim + 1, ) ) - phi = 2 * np.pi * np.random.rand(n) - s[:, 2] = np.random.rand(n) * 2 - 1 + phi = 2 * np.pi * random.rand(n) + s[:, 2] = random.rand(n) * 2 - 1 r = sqrt(1 - s[:, 2] ** 2) s[:, 0] = r * cos(phi) s[:, 1] = r * sin(phi) else: - samples_unnorm = np.random.randn(n, self.dim + 1) + samples_unnorm = random.randn(n, self.dim + 1) s = samples_unnorm / np.linalg.norm(samples_unnorm, axis=1, keepdims=True) return s diff --git a/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py b/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py index b1b576eb..3af02686 100644 --- a/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py +++ b/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import random from typing import Union from pyrecest.backend import vstack from pyrecest.backend import sqrt @@ -260,7 +261,7 @@ def sample_metropolis_hastings( if proposal is None: def proposal(x): - return mod(x + np.random.randn(self.dim), 2 * np.pi) + return mod(x + random.randn(self.dim), 2 * np.pi) if start_point is None: start_point = self.mean_direction() diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_uniform_distribution.py b/pyrecest/distributions/hypertorus/hypertoroidal_uniform_distribution.py index 32e6f6e3..95a6752a 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_uniform_distribution.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_uniform_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import random from typing import Union from pyrecest.backend import prod from pyrecest.backend import ones @@ -62,7 +63,7 @@ def sample(self, n: Union[int, int32, int64]) -> np.ndarray: :param n: Sample size :returns: Sample of size n """ - return 2 * np.pi * np.random.rand(n, self.dim) + return 2 * np.pi * random.rand(n, self.dim) def shift(self, shift_by) -> "HypertoroidalUniformDistribution": """ diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py b/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py index b8f8a046..04d5c48f 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import random from typing import Union from pyrecest.backend import reshape from pyrecest.backend import mod @@ -86,7 +87,7 @@ def sample(self, n): ): raise ValueError("n must be a positive integer") - s = np.random.multivariate_normal(self.mu, self.C, n) + s = random.multivariate_normal(self.mu, self.C, n) s = mod(s, 2 * np.pi) # wrap the samples return s diff --git a/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py b/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py index 011710d1..5eab2589 100644 --- a/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py +++ b/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import random from typing import Union from pyrecest.backend import squeeze from pyrecest.backend import sqrt @@ -68,7 +69,7 @@ def sample_metropolis_hastings( if proposal is None: def proposal(x): - return x + np.random.randn(self.dim) + return x + random.randn(self.dim) if start_point is None: start_point = ( diff --git a/pyrecest/distributions/nonperiodic/gaussian_distribution.py b/pyrecest/distributions/nonperiodic/gaussian_distribution.py index 09cfc013..13752175 100644 --- a/pyrecest/distributions/nonperiodic/gaussian_distribution.py +++ b/pyrecest/distributions/nonperiodic/gaussian_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import random from pyrecest.backend import ndim from pyrecest.backend import dot import copy @@ -85,7 +86,7 @@ def marginalize_out(self, dimensions): return GaussianDistribution(new_mu, new_C, check_validity=False) def sample(self, n): - return np.random.multivariate_normal(self.mu, self.C, n) + return random.multivariate_normal(self.mu, self.C, n) @staticmethod def from_distribution(distribution): diff --git a/pyrecest/evaluation/eot_shape_database.py b/pyrecest/evaluation/eot_shape_database.py index 1b73b077..5e328c2f 100644 --- a/pyrecest/evaluation/eot_shape_database.py +++ b/pyrecest/evaluation/eot_shape_database.py @@ -1,3 +1,4 @@ +from pyrecest.backend import random from pyrecest.backend import sin from pyrecest.backend import linspace from pyrecest.backend import cos @@ -29,7 +30,7 @@ def sample_on_boundary(self, num_points: int) -> np.ndarray: perimeter = self.length # Generate a random distance along the perimeter - distance = np.random.uniform(0, perimeter) + distance = random.uniform(0, perimeter) # Traverse the edges to place the point for line in lines: @@ -46,13 +47,13 @@ def sample_within(self, num_points: int) -> np.ndarray: for i in range(num_points): random_point = Point( - [np.random.uniform(min_x, max_x), np.random.uniform(min_y, max_y)] + [random.uniform(min_x, max_x), random.uniform(min_y, max_y)] ) while not random_point.within(self): random_point = Point( [ - np.random.uniform(min_x, max_x), - np.random.uniform(min_y, max_y), + random.uniform(min_x, max_x), + random.uniform(min_y, max_y), ] ) diff --git a/pyrecest/evaluation/generate_measurements.py b/pyrecest/evaluation/generate_measurements.py index 33fe310c..dd623642 100644 --- a/pyrecest/evaluation/generate_measurements.py +++ b/pyrecest/evaluation/generate_measurements.py @@ -1,3 +1,4 @@ +from pyrecest.backend import random from pyrecest.backend import tile from pyrecest.backend import sum from pyrecest.backend import squeeze @@ -116,7 +117,7 @@ def generate_measurements(groundtruth, simulation_config): simulation_config["clutter_rate"] == 0 ), "Clutter currently not supported." - n_observations = np.random.binomial( + n_observations = random.binomial( 1, simulation_config["detection_probability"], (simulation_config["n_timesteps"], simulation_config["n_targets"]), diff --git a/pyrecest/evaluation/generate_simulated_scenarios.py b/pyrecest/evaluation/generate_simulated_scenarios.py index ca68b66c..c1150c63 100644 --- a/pyrecest/evaluation/generate_simulated_scenarios.py +++ b/pyrecest/evaluation/generate_simulated_scenarios.py @@ -1,3 +1,4 @@ +from pyrecest.backend import random from pyrecest.backend import empty import numpy as np @@ -32,7 +33,7 @@ def generate_simulated_scenarios( ) for run, seed in enumerate(simulation_params["all_seeds"]): - np.random.seed(seed) + random.seed(seed) groundtruths[run, :] = generate_groundtruth(simulation_params) measurements[run, :] = generate_measurements( groundtruths[run, :], simulation_params diff --git a/pyrecest/filters/abstract_particle_filter.py b/pyrecest/filters/abstract_particle_filter.py index 0ccc86c1..e3211285 100644 --- a/pyrecest/filters/abstract_particle_filter.py +++ b/pyrecest/filters/abstract_particle_filter.py @@ -1,3 +1,4 @@ +from pyrecest.backend import random from pyrecest.backend import sum from pyrecest.backend import ones_like from pyrecest.backend import ones @@ -54,7 +55,7 @@ def predict_nonlinear_nonadditive(self, f, samples, weights): weights = weights / sum(weights) n = self.filter_state.w.size - noise_ids = np.random.choice(weights.size, n, p=weights) + noise_ids = random.choice(weights.size, n, p=weights) d = zeros((n, self.filter_state.dim)) for i in range(n): d[i, :] = f(self.filter_state.d[i, :], samples[noise_ids[i]]) diff --git a/pyrecest/filters/hypertoroidal_particle_filter.py b/pyrecest/filters/hypertoroidal_particle_filter.py index 439a984b..79db1ed4 100644 --- a/pyrecest/filters/hypertoroidal_particle_filter.py +++ b/pyrecest/filters/hypertoroidal_particle_filter.py @@ -1,3 +1,4 @@ +from pyrecest.backend import random from typing import Union from pyrecest.backend import tile from pyrecest.backend import sum @@ -83,7 +84,7 @@ def predict_nonlinear_nonadditive( weights /= sum(weights) n = self.filter_state.shape[0] - noise_ids = np.random.choice(arange(weights.size), size=n, p=weights) + noise_ids = random.choice(arange(weights.size), size=n, p=weights) d = zeros_like(self.filter_state) for i in range(n): d[i, :] = f(self.filter_state[i, :], samples[noise_ids[i, :]]) diff --git a/pyrecest/tests/distributions/test_custom_hemispherical_distribution.py b/pyrecest/tests/distributions/test_custom_hemispherical_distribution.py index f51bf8b7..001b778a 100644 --- a/pyrecest/tests/distributions/test_custom_hemispherical_distribution.py +++ b/pyrecest/tests/distributions/test_custom_hemispherical_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import random from pyrecest.backend import eye from pyrecest.backend import array from pyrecest.backend import allclose @@ -27,8 +28,8 @@ def test_simple_distribution_2D(self): p = self.custom_hemispherical_distribution.pdf(np.asarray([1, 0, 0])) self.assertEqual(p.size, 1, "PDF size mismatch.") - np.random.seed(10) - points = np.random.randn(100, 3) + random.seed(10) + points = random.randn(100, 3) points = points[points[:, 2] >= 0, :] points /= np.linalg.norm(points, axis=1, keepdims=True) diff --git a/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py b/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py index 0b20c220..512040b5 100644 --- a/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py +++ b/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import random from pyrecest.backend import linspace from pyrecest.backend import eye from pyrecest.backend import array @@ -16,7 +17,7 @@ class CustomHypercylindricalDistributionTest(unittest.TestCase): def setUp(self) -> None: - mat = np.random.rand(6, 6) + mat = random.rand(6, 6) mat = mat @ mat.T self.pwn = PartiallyWrappedNormalDistribution( array([2, 3, 4, 5, 6, 7]), mat, 3 diff --git a/pyrecest/tests/distributions/test_custom_hyperspherical_distribution.py b/pyrecest/tests/distributions/test_custom_hyperspherical_distribution.py index 2bdc9858..342d00cb 100644 --- a/pyrecest/tests/distributions/test_custom_hyperspherical_distribution.py +++ b/pyrecest/tests/distributions/test_custom_hyperspherical_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import random from pyrecest.backend import array from pyrecest.backend import allclose from pyrecest.backend import all @@ -22,8 +23,8 @@ def test_simple_distribution(self): p = self.custom_hyperspherical_distribution.pdf(np.asarray([1, 0, 0])) self.assertEqual(p.size, 1, "PDF size mismatch.") - np.random.seed(10) - points = np.random.randn(100, 3) + random.seed(10) + points = random.randn(100, 3) points /= np.linalg.norm(points, axis=1, keepdims=True) self.assertTrue( diff --git a/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py b/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py index e9998cde..9caa9628 100644 --- a/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import random from pyrecest.backend import sum from pyrecest.backend import ones_like from pyrecest.backend import ones @@ -90,7 +91,7 @@ def f3(x): np.testing.assert_array_equal(pwd_rew3.w, w_new / sum(w_new)) def test_sampling(self): - np.random.seed(0) + random.seed(0) n = 10 s = self.pwd.sample(n) assert s.shape == (n, 3) @@ -99,7 +100,7 @@ def test_sampling(self): self.assertTrue(all(s < 2 * np.pi * ones_like(s))) def test_from_distribution(self): - random_gen = np.random.default_rng(0) # Could fail randomly otherwise + random_gen = random.default_rng(0) # Could fail randomly otherwise df = 4 scale = eye(4) C = wishart.rvs(df, scale, random_state=random_gen) diff --git a/pyrecest/tests/distributions/test_hyperhemispherical_uniform_distribution.py b/pyrecest/tests/distributions/test_hyperhemispherical_uniform_distribution.py index 476159e3..98d2340f 100644 --- a/pyrecest/tests/distributions/test_hyperhemispherical_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_hyperhemispherical_uniform_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import random from pyrecest.backend import reshape from pyrecest.backend import ones from pyrecest.backend import allclose @@ -10,8 +11,8 @@ def get_random_points(n, d): - np.random.seed(10) - points = np.random.randn(n, d + 1) + random.seed(10) + points = random.randn(n, d + 1) points = points[points[:, -1] >= 0, :] points /= reshape(np.linalg.norm(points, axis=1), (-1, 1)) return points diff --git a/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py b/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py index f63a142a..b7faa11d 100644 --- a/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import random from pyrecest.backend import sum from pyrecest.backend import sqrt from pyrecest.backend import ones @@ -63,7 +64,7 @@ def f(x): np.testing.assert_array_almost_equal(twdNew.w, wNew / sum(wNew)) def test_from_distribution(self): - np.random.seed(0) + random.seed(0) vmf = VonMisesFisherDistribution(array([1, 1, 1]) / sqrt(3), 1) dirac_dist = HypersphericalDiracDistribution.from_distribution(vmf, 100000) np.testing.assert_almost_equal( diff --git a/pyrecest/tests/distributions/test_hyperspherical_uniform_distribution.py b/pyrecest/tests/distributions/test_hyperspherical_uniform_distribution.py index c556219c..c3ffc9b4 100644 --- a/pyrecest/tests/distributions/test_hyperspherical_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_hyperspherical_uniform_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import random from pyrecest.backend import ones from pyrecest.backend import allclose from pyrecest.backend import all @@ -21,10 +22,10 @@ def test_integrate_3d(self): self.assertAlmostEqual(hud.integrate(), 1, delta=1e-6) def test_pdf(self): - np.random.seed(0) + random.seed(0) for dim in range(2, 5): hud = HypersphericalUniformDistribution(dim) - x = np.random.rand(dim + 1) + x = random.rand(dim + 1) x = x / np.linalg.norm(x) self.assertAlmostEqual( hud.pdf(x), diff --git a/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py b/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py index ef09acfd..c229727d 100644 --- a/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import random from pyrecest.backend import sum from pyrecest.backend import squeeze from pyrecest.backend import outer @@ -97,10 +98,10 @@ def test_shift(self): @staticmethod def get_pseudorandom_hypertoroidal_wd(dim=2): - np.random.seed(0) + random.seed(0) n = 20 - d = 2 * np.pi * np.random.rand(n, dim) - w = np.random.rand(n) + d = 2 * np.pi * random.rand(n, dim) + w = random.rand(n) w = w / sum(w) hwd = HypertoroidalDiracDistribution(d, w) return hwd diff --git a/pyrecest/tests/distributions/test_linear_dirac_distribution.py b/pyrecest/tests/distributions/test_linear_dirac_distribution.py index 4e05d3f5..27e06278 100644 --- a/pyrecest/tests/distributions/test_linear_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_linear_dirac_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import random from pyrecest.backend import eye from pyrecest.backend import array from pyrecest.backend import allclose @@ -14,7 +15,7 @@ class LinearDiracDistributionTest(unittest.TestCase): def test_from_distribution(self): - np.random.seed(0) + random.seed(0) C = wishart.rvs(3, eye(3)) hwn = GaussianDistribution(array([1, 2, 3]), C) hwd = LinearDiracDistribution.from_distribution(hwn, 100000) @@ -22,7 +23,7 @@ def test_from_distribution(self): self.assertTrue(allclose(hwd.covariance(), hwn.covariance(), rtol=0.01)) def test_mean_and_cov(self): - np.random.seed(0) + random.seed(0) gd = GaussianDistribution(array([1, 2]), array([[2, -0.3], [-0.3, 1]])) ddist = LinearDiracDistribution(gd.sample(10000)) self.assertTrue(allclose(ddist.mean(), gd.mean(), atol=0.05)) diff --git a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py index 3350f6b1..8a01b074 100644 --- a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py +++ b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py @@ -1,3 +1,4 @@ +from pyrecest.backend import random from pyrecest.backend import sqrt from pyrecest.backend import sin from pyrecest.backend import ones_like @@ -29,8 +30,8 @@ class SphericalHarmonicsDistributionComplexTest(unittest.TestCase): def setUp(self): - np.random.seed(1) - coeff_rand = np.random.rand(9) + random.seed(1) + coeff_rand = random.rand(9) self.unnormalized_coeffs = array( [ [coeff_rand[0], np.nan, np.nan, np.nan, np.nan], @@ -62,8 +63,8 @@ def test_normalization(self): # Enforce unnormalized coefficients and compare ratio phi, theta = ( - np.random.rand(1, 10) * 2 * np.pi, - np.random.rand(1, 10) * np.pi - np.pi / 2, + random.rand(1, 10) * 2 * np.pi, + random.rand(1, 10) * np.pi - np.pi / 2, ) x, y, z = array( [cos(theta) * cos(phi), cos(theta) * sin(phi), sin(theta)] @@ -82,8 +83,8 @@ def test_normalization(self): @parameterized.expand([("identity",), ("sqrt",)]) def test_integral_analytical(self, transformation): """Test if the analytical integral is equal to the numerical integral""" - np.random.seed(10) - coeff_rand = np.random.rand(1, 9) + random.seed(10) + coeff_rand = random.rand(1, 9) unnormalized_coeffs = array( [ [coeff_rand[0, 0], np.nan, np.nan, np.nan, np.nan], @@ -135,7 +136,7 @@ def test_truncation(self): shd5 = shd3.truncate(3) self.assertEqual(shd5.coeff_mat.shape, (4, 7)) - phi, theta = np.random.rand(10) * 2 * np.pi, np.random.rand(10) * np.pi + phi, theta = random.rand(10) * 2 * np.pi, random.rand(10) * np.pi x, y, z = AbstractSphericalDistribution.sph_to_cart(phi, theta) self.assertTrue( allclose( diff --git a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py index 20306cce..525bf41f 100644 --- a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py +++ b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py @@ -1,3 +1,4 @@ +from pyrecest.backend import random from pyrecest.backend import sqrt from pyrecest.backend import ones_like from pyrecest.backend import ones @@ -24,12 +25,12 @@ def testNormalizationError(self): def testNormalizationWarning(self): with warnings.catch_warnings(record=True) as w: - SphericalHarmonicsDistributionReal(np.random.rand(3, 5)) + SphericalHarmonicsDistributionReal(random.rand(3, 5)) self.assertEqual(len(w), 1) self.assertTrue(issubclass(w[-1].category, UserWarning)) def testNormalization(self): - unnormalized_coeffs = np.random.rand(3, 5) + unnormalized_coeffs = random.rand(3, 5) shd = SphericalHarmonicsDistributionReal(unnormalized_coeffs) self.assertAlmostEqual(shd.integrate(), 1, delta=1e-6) x, y, z = SphericalHarmonicsDistributionRealTest._gen_naive_grid(10) @@ -134,7 +135,7 @@ def testNormalization(self): ] # jscpd:ignore-end ) def test_basis_function(self, name, coeff_mat, result_func): - np.random.seed(10) + random.seed(10) shd = SphericalHarmonicsDistributionReal(1 / sqrt(4 * np.pi)) shd.coeff_mat = array(coeff_mat) x, y, z = SphericalHarmonicsDistributionRealTest._gen_naive_grid(10) @@ -147,8 +148,8 @@ def test_basis_function(self, name, coeff_mat, result_func): @staticmethod def _gen_naive_grid(n_per_dim): - phi = np.random.rand(n_per_dim) * 2 * np.pi - theta = np.random.rand(n_per_dim) * np.pi - np.pi / 2 + phi = random.rand(n_per_dim) * 2 * np.pi + theta = random.rand(n_per_dim) * np.pi - np.pi / 2 return AbstractSphericalDistribution.sph_to_cart(phi, theta) @parameterized.expand( @@ -320,15 +321,15 @@ def _gen_naive_grid(n_per_dim): ] ), ), - ("random", np.random.rand(4, 7)), + ("random", random.rand(4, 7)), ] # jscpd:ignore-end ) def test_conversion(self, _, coeff_mat): rshd = SphericalHarmonicsDistributionReal(coeff_mat) cshd = rshd.to_spherical_harmonics_distribution_complex() phi_to_test, theta_to_test = ( - np.random.rand(10) * 2 * np.pi, - np.random.rand(10) * np.pi - np.pi / 2, + random.rand(10) * 2 * np.pi, + random.rand(10) * np.pi - np.pi / 2, ) x, y, z = AbstractSphericalDistribution.sph_to_cart(phi_to_test, theta_to_test) np.testing.assert_allclose( @@ -341,7 +342,7 @@ def test_conversion_to_complex_and_back(self): # Suppress warnings related to normalization with warnings.catch_warnings(): warnings.simplefilter("ignore") - rshd = SphericalHarmonicsDistributionReal(np.random.rand(4, 7)) + rshd = SphericalHarmonicsDistributionReal(random.rand(4, 7)) cshd = rshd.to_spherical_harmonics_distribution_complex() rshd2 = cshd.to_spherical_harmonics_distribution_real() @@ -351,7 +352,7 @@ def test_conversion_to_complex_and_back(self): def test_integral_analytical(self): # Suppress warnings related to normalization - unnormalized_coeffs = np.random.rand(3, 5) + unnormalized_coeffs = random.rand(3, 5) with warnings.catch_warnings(): warnings.simplefilter("ignore") shd = SphericalHarmonicsDistributionReal(unnormalized_coeffs) diff --git a/pyrecest/tests/filters/test_circular_particle_filter.py b/pyrecest/tests/filters/test_circular_particle_filter.py index 753c2d22..dbdf9de1 100644 --- a/pyrecest/tests/filters/test_circular_particle_filter.py +++ b/pyrecest/tests/filters/test_circular_particle_filter.py @@ -1,3 +1,4 @@ +from pyrecest.backend import random from pyrecest.backend import array from pyrecest.backend import arange from pyrecest.backend import allclose @@ -41,7 +42,7 @@ def test_set_state(self): def test_sampling(self): positions = arange(0, 1.1, 0.1) dist3 = CircularDiracDistribution(positions) - np.random.seed(0) + random.seed(0) num_samples = 20 samples = dist3.sample(num_samples) self.assertEqual(samples.shape, (num_samples,)) @@ -84,7 +85,7 @@ def f(x): def test_update(self): # test update - np.random.seed(0) + random.seed(0) self.filter.set_state(self.dist) def h(x): @@ -131,7 +132,7 @@ def likelihood1(_, x): self.assertEqual(estimation.d[i], 0.5) # test update with single parameter likelihood - np.random.seed(0) + random.seed(0) self.filter.filter_state = self.dist wn = WrappedNormalDistribution(1.3, 0.8) diff --git a/pyrecest/tests/filters/test_euclidean_particle_filter.py b/pyrecest/tests/filters/test_euclidean_particle_filter.py index b003aef7..be9903dc 100644 --- a/pyrecest/tests/filters/test_euclidean_particle_filter.py +++ b/pyrecest/tests/filters/test_euclidean_particle_filter.py @@ -1,3 +1,4 @@ +from pyrecest.backend import random from pyrecest.backend import ones from pyrecest.backend import mean from pyrecest.backend import array @@ -12,7 +13,7 @@ class EuclideanParticleFilterTest(unittest.TestCase): def setUp(self): - np.random.seed(42) + random.seed(42) self.C_prior = array([[0.7, 0.4, 0.2], [0.4, 0.6, 0.1], [0.2, 0.1, 1]]) self.mu = array([5, 6, 7]) self.prior = GaussianDistribution(self.mu, self.C_prior) @@ -39,7 +40,7 @@ def test_predict_update_cycle_3d(self): def test_predict_nonlinear_nonadditive(self): n = 5 - samples = np.random.rand(n, 3) + samples = random.rand(n, 3) weights = ones(n) / n def f(x, w): diff --git a/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py b/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py index dda61fc6..9987a70a 100644 --- a/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py +++ b/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py @@ -1,3 +1,4 @@ +from pyrecest.backend import random from pyrecest.backend import array from pyrecest.backend import zeros import unittest @@ -17,7 +18,7 @@ def setUp(self): self.hwnd = HypertoroidalWNDistribution(self.mu, self.covariance_matrix) self.hpf = HypertoroidalParticleFilter(500, 3) self.forced_mean = array([1, 2, 3]) - np.random.seed(self.seed) + random.seed(self.seed) def test_set_state(self): self.hpf.set_state(self.hwnd) diff --git a/pyrecest/tests/filters/test_toroidal_particle_filter.py b/pyrecest/tests/filters/test_toroidal_particle_filter.py index 3a05e601..12a785db 100644 --- a/pyrecest/tests/filters/test_toroidal_particle_filter.py +++ b/pyrecest/tests/filters/test_toroidal_particle_filter.py @@ -1,3 +1,4 @@ +from pyrecest.backend import random from pyrecest.backend import array from pyrecest.backend import allclose from pyrecest.backend import all @@ -15,7 +16,7 @@ class ToroidalParticleFilterTest(unittest.TestCase): def test_toroidal_particle_filter(self): - np.random.seed(0) + random.seed(0) C = array([[0.7, 0.4], [0.4, 0.6]]) mu = array([1, 1]) + np.pi / 2 hwnd = ToroidalWrappedNormalDistribution(mu, C) diff --git a/pyrecest/tests/test_euclidean_sampler.py b/pyrecest/tests/test_euclidean_sampler.py index fc05389a..088e115c 100644 --- a/pyrecest/tests/test_euclidean_sampler.py +++ b/pyrecest/tests/test_euclidean_sampler.py @@ -1,3 +1,4 @@ +from pyrecest.backend import random from pyrecest.backend import std from pyrecest.backend import ones from pyrecest.backend import mean @@ -12,7 +13,7 @@ class TestGaussianSampler(unittest.TestCase): def setUp(self): - np.random.seed(0) + random.seed(0) self.sampler = GaussianSampler() self.n_samples = 200 self.dim = 2 diff --git a/pyrecest/tests/test_evaluation_basic.py b/pyrecest/tests/test_evaluation_basic.py index 6515b667..8bf9e86a 100644 --- a/pyrecest/tests/test_evaluation_basic.py +++ b/pyrecest/tests/test_evaluation_basic.py @@ -1,3 +1,4 @@ +from pyrecest.backend import random from pyrecest.backend import sqrt from pyrecest.backend import shape from pyrecest.backend import ones @@ -120,7 +121,7 @@ def test_generate_measurements(self, n_meas): @parameterized.expand([("boundary",), ("within",)]) def test_generate_measurements_eot(self, eot_sampling_style: str): - np.random.seed(0) + random.seed(0) simulation_param = { "eot": True, "intensity_lambda": 0.2, diff --git a/pyrecest/tests/test_hyperspherical_sampler.py b/pyrecest/tests/test_hyperspherical_sampler.py index baff99ca..6ce9212e 100644 --- a/pyrecest/tests/test_hyperspherical_sampler.py +++ b/pyrecest/tests/test_hyperspherical_sampler.py @@ -1,3 +1,4 @@ +from pyrecest.backend import random from pyrecest.backend import prod from pyrecest.backend import allclose from pyrecest.backend import all @@ -122,7 +123,7 @@ class TestHopfConversion(unittest.TestCase): def test_conversion(self): # Generate a sample matrix of size (n, 4) containing unit vectors. n = 100 # sample size - random_vectors = np.random.randn(n, 4) + random_vectors = random.randn(n, 4) unit_vectors = ( random_vectors / np.linalg.norm(random_vectors, axis=1)[:, np.newaxis] ) diff --git a/pyrecest/tests/test_metrics.py b/pyrecest/tests/test_metrics.py index ac81e972..47d701bd 100644 --- a/pyrecest/tests/test_metrics.py +++ b/pyrecest/tests/test_metrics.py @@ -1,3 +1,4 @@ +from pyrecest.backend import random from pyrecest.backend import repeat from pyrecest.backend import array import unittest @@ -18,7 +19,7 @@ def test_ANEES_is_close_to_one(self): samples = [] for i in range(len(self.groundtruths)): - samples_for_i = np.random.multivariate_normal( + samples_for_i = random.multivariate_normal( mean=self.groundtruths[i], cov=self.uncertainties[i], size=self.num_samples, From 22c1fe3c02fab6c981cf9dc45701a0ef6d1aaa57 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 17 Oct 2023 20:10:55 +0100 Subject: [PATCH 013/232] Adjusted calls to np.pi --- .../abstract_ellipsoidal_ball_distribution.py | 9 +- .../abstract_hypercylindrical_distribution.py | 25 +++-- .../partially_wrapped_normal_distribution.py | 11 +- .../circle/abstract_circular_distribution.py | 7 +- .../circle/circular_fourier_distribution.py | 15 +-- .../circle/circular_uniform_distribution.py | 3 +- .../circle/custom_circular_distribution.py | 7 +- .../circle/von_mises_distribution.py | 13 ++- .../circle/wrapped_cauchy_distribution.py | 9 +- .../circle/wrapped_laplace_distribution.py | 7 +- .../circle/wrapped_normal_distribution.py | 25 +++-- .../ellipsoidal_ball_uniform_distribution.py | 3 +- ...bstract_hyperhemispherical_distribution.py | 11 +- ...bstract_hypersphere_subset_distribution.py | 9 +- .../abstract_hyperspherical_distribution.py | 17 +-- .../abstract_sphere_subset_distribution.py | 9 +- ...stract_spherical_harmonics_distribution.py | 3 +- .../bingham_distribution.py | 3 +- .../hyperspherical_uniform_distribution.py | 3 +- ...pherical_harmonics_distribution_complex.py | 5 +- .../von_mises_fisher_distribution.py | 5 +- .../abstract_hypertoroidal_distribution.py | 33 +++--- .../abstract_toroidal_distribution.py | 9 +- .../custom_hypertoroidal_distribution.py | 3 +- .../hypertoroidal_dirac_distribution.py | 9 +- .../hypertoroidal_uniform_distribution.py | 9 +- ...pertoroidal_wrapped_normal_distribution.py | 11 +- .../toroidal_von_mises_sine_distribution.py | 5 +- pyrecest/evaluation/eot_shape_database.py | 5 +- pyrecest/evaluation/generate_measurements.py | 3 +- .../filters/hypertoroidal_particle_filter.py | 7 +- pyrecest/filters/von_mises_filter.py | 3 +- pyrecest/filters/wrapped_normal_filter.py | 3 +- pyrecest/sampling/hyperspherical_sampler.py | 3 +- pyrecest/sampling/hypertoroidal_sampler.py | 5 +- .../test_abstract_circular_distribution.py | 9 +- ..._abstract_hypercylindrical_distribution.py | 5 +- ...bstract_hyperhemispherical_distribution.py | 3 +- ...st_abstract_hyperspherical_distribution.py | 7 +- ...est_abstract_hypertoroidal_distribution.py | 9 +- .../test_circular_fourier_distribution.py | 7 +- .../test_circular_uniform_distribution.py | 7 +- ...st_custom_hypercylindrical_distribution.py | 3 +- .../test_custom_linear_distribution.py | 3 +- .../test_disk_uniform_distribution.py | 3 +- ...test_hemispherical_uniform_distribution.py | 3 +- ...est_hypercylindrical_dirac_distribution.py | 3 +- ...hyperhemispherical_uniform_distribution.py | 5 +- .../test_hyperspherical_dirac_distribution.py | 3 +- .../test_hyperspherical_mixture.py | 3 +- .../test_hypertoroidal_dirac_distribution.py | 9 +- .../test_sphere_subset_distribution.py | 5 +- ...pherical_harmonics_distribution_complex.py | 105 +++++++++--------- ...t_spherical_harmonics_distribution_real.py | 29 ++--- .../test_toroidal_uniform_distribution.py | 7 +- ...st_toroidal_von_mises_sine_distribution.py | 3 +- ...st_toroidal_wrapped_normal_distribution.py | 3 +- .../test_wrapped_cauchy_distribution.py | 3 +- .../test_wrapped_laplace_distribution.py | 9 +- .../test_wrapped_normal_distribution.py | 7 +- .../filters/test_circular_particle_filter.py | 5 +- .../filters/test_euclidean_particle_filter.py | 3 +- .../test_hypertoroidal_particle_filter.py | 3 +- .../filters/test_toroidal_particle_filter.py | 3 +- .../test_toroidal_wrapped_normal_filter.py | 3 +- pyrecest/tests/test_hypertoroidal_sampler.py | 5 +- pyrecest/utils/plotting.py | 7 +- 67 files changed, 328 insertions(+), 261 deletions(-) diff --git a/pyrecest/distributions/abstract_ellipsoidal_ball_distribution.py b/pyrecest/distributions/abstract_ellipsoidal_ball_distribution.py index b07f5e89..54fc5910 100644 --- a/pyrecest/distributions/abstract_ellipsoidal_ball_distribution.py +++ b/pyrecest/distributions/abstract_ellipsoidal_ball_distribution.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import sqrt import numbers @@ -41,12 +42,12 @@ def get_manifold_size(self) -> np.number | numbers.Real: if self.dim == 1: c = 2 elif self.dim == 2: - c = np.pi + c = pi elif self.dim == 3: - c = 4 / 3 * np.pi + c = 4 / 3 * pi elif self.dim == 4: - c = 0.5 * np.pi**2 + c = 0.5 * pi**2 else: - c = (np.pi ** (self.dim / 2)) / gamma((self.dim / 2) + 1) + c = (pi ** (self.dim / 2)) / gamma((self.dim / 2) + 1) return c * sqrt(np.linalg.det(self.shape_matrix)) \ No newline at end of file diff --git a/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py b/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py index 38a50d94..681ceb0d 100644 --- a/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py +++ b/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py @@ -1,3 +1,4 @@ +from math import pi from typing import Union from pyrecest.backend import vstack from pyrecest.backend import tile @@ -118,29 +119,29 @@ def linear_covariance_numerical(self, approximate_mean=None): if self.bound_dim == 1 and self.lin_dim == 1: C, _ = nquad( lambda x, y: (y - approximate_mean) ** 2 * self.pdf([x, y]), - [[0, 2 * np.pi], [-np.inf, np.inf]], + [[0, 2 * pi], [-np.inf, np.inf]], ) elif self.bound_dim == 2 and self.lin_dim == 1: C, _ = nquad( lambda x, y, z: (z - approximate_mean) ** 2 * self.pdf([x, y, z]), - [[0, 2 * np.pi], [0, 2 * np.pi], [-np.inf, np.inf]], + [[0, 2 * pi], [0, 2 * pi], [-np.inf, np.inf]], ) elif self.bound_dim == 1 and self.lin_dim == 2: C = empty((2, 2)) C[0, 0], _ = nquad( lambda x, y, z: (y - approximate_mean[0]) ** 2 * self.pdf([x, y, z]), - [[0, 2 * np.pi], [-np.inf, np.inf], [-np.inf, np.inf]], + [[0, 2 * pi], [-np.inf, np.inf], [-np.inf, np.inf]], ) C[0, 1], _ = nquad( lambda x, y, z: (y - approximate_mean[0]) * (z - approximate_mean[1]) * self.pdf([x, y, z]), - [[0, 2 * np.pi], [-np.inf, np.inf], [-np.inf, np.inf]], + [[0, 2 * pi], [-np.inf, np.inf], [-np.inf, np.inf]], ) C[1, 0] = C[0, 1] C[1, 1], _ = nquad( lambda x, y, z: (z - approximate_mean[1]) ** 2 * self.pdf([x, y, z]), - [[0, 2 * np.pi], [-np.inf, np.inf], [-np.inf, np.inf]], + [[0, 2 * pi], [-np.inf, np.inf], [-np.inf, np.inf]], ) else: raise ValueError("Cannot determine linear covariance for this dimension.") @@ -195,7 +196,7 @@ def condition_on_periodic(self, input_periodic, normalize=True): np.size(input_periodic) == self.bound_dim and ndim(input_periodic) <= 1 ), "Input should be of size (lin_dim,)." - input_periodic = mod(input_periodic, 2 * np.pi) + input_periodic = mod(input_periodic, 2 * pi) def f_cond_unnorm(x, input_periodic=input_periodic): n_inputs = np.size(x) // x.shape[-1] if ndim(x) > 1 else np.size(x) @@ -214,22 +215,22 @@ def linear_mean_numerical(self): if self.lin_dim == 1 and self.bound_dim == 1: mu = scipy.integrate.nquad( lambda x, y: (y * self.pdf([x, y]))[0], - [[0, 2 * np.pi], [-np.inf, np.inf]], + [[0, 2 * pi], [-np.inf, np.inf]], )[0] elif self.bound_dim == 2 and self.lin_dim == 1: mu = scipy.integrate.nquad( lambda x, y, z: (z * self.pdf([x, y, z]))[0], - [[0, 2 * np.pi], [0, 2 * np.pi], [-np.inf, np.inf]], + [[0, 2 * pi], [0, 2 * pi], [-np.inf, np.inf]], )[0] elif self.bound_dim == 1 and self.lin_dim == 2: mu = empty(2) mu[0] = scipy.integrate.nquad( lambda x, y, z: (y * self.pdf([x, y, z]))[0], - [[0, 2 * np.pi], [-np.inf, np.inf], [-np.inf, np.inf]], + [[0, 2 * pi], [-np.inf, np.inf], [-np.inf, np.inf]], )[0] mu[1] = scipy.integrate.nquad( lambda x, y, z: (z * self.pdf([x, y, z]))[0], - [[0, 2 * np.pi], [-np.inf, np.inf], [-np.inf, np.inf]], + [[0, 2 * pi], [-np.inf, np.inf], [-np.inf, np.inf]], )[0] else: raise ValueError("Cannot determine linear mean for this dimension.") @@ -251,12 +252,12 @@ def mode_numerical(self, starting_point=None): """ if starting_point is None: starting_point = concatenate( - [np.pi * ones(self.bound_dim), zeros(self.lin_dim)] + [pi * ones(self.bound_dim), zeros(self.lin_dim)] ) # Define bounds for the optimization bounds = [ - (0, 2 * np.pi) if i < self.bound_dim else (-np.inf, np.inf) + (0, 2 * pi) if i < self.bound_dim else (-np.inf, np.inf) for i in range(self.bound_dim + self.lin_dim) ] diff --git a/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py b/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py index 4d306b58..27539678 100644 --- a/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py +++ b/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import random from typing import Union from pyrecest.backend import tile @@ -42,25 +43,25 @@ def __init__( assert bound_dim <= np.size(mu) assert ndim(mu) == 1 if bound_dim > 0: # This decreases the need for many wrappings - mu[:bound_dim] = mod(mu[:bound_dim], 2 * np.pi) + mu[:bound_dim] = mod(mu[:bound_dim], 2 * pi) AbstractHypercylindricalDistribution.__init__( self, bound_dim=bound_dim, lin_dim=np.size(mu) - bound_dim ) self.mu = mu - self.mu[:bound_dim] = mod(self.mu[:bound_dim], 2 * np.pi) + self.mu[:bound_dim] = mod(self.mu[:bound_dim], 2 * pi) self.C = C def pdf(self, xs: np.ndarray, m: Union[int, int32, int64] = 3): xs = np.atleast_2d(xs) if self.bound_dim > 0: - xs[:, : self.bound_dim] = mod(xs[:, : self.bound_dim], 2 * np.pi) + xs[:, : self.bound_dim] = mod(xs[:, : self.bound_dim], 2 * pi) assert xs.shape[-1] == self.input_dim # generate multiples for wrapping - multiples = array(range(-m, m + 1)) * 2 * np.pi + multiples = array(range(-m, m + 1)) * 2 * pi # create meshgrid for all combinations of multiples mesh = array(meshgrid(*[multiples] * self.bound_dim)).reshape( @@ -131,7 +132,7 @@ def sample(self, n: int): """ assert n > 0, "n must be positive" s = random.multivariate_normal(self.mu, self.C, n) - s[:, : self.bound_dim] = mod(s[:, : self.bound_dim], 2 * np.pi) # noqa: E203 + s[:, : self.bound_dim] = mod(s[:, : self.bound_dim], 2 * pi) # noqa: E203 return s def to_gaussian(self): diff --git a/pyrecest/distributions/circle/abstract_circular_distribution.py b/pyrecest/distributions/circle/abstract_circular_distribution.py index 60284918..87a4f947 100644 --- a/pyrecest/distributions/circle/abstract_circular_distribution.py +++ b/pyrecest/distributions/circle/abstract_circular_distribution.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import sin from pyrecest.backend import mod from pyrecest.backend import linspace @@ -39,8 +40,8 @@ def _cdf_numerical_single( starting_point: np.number | numbers.Real, ) -> np.number | numbers.Real: """Helper method for cdf_numerical""" - starting_point_mod = mod(starting_point, 2 * np.pi) - x_mod = mod(x, 2 * np.pi) + starting_point_mod = mod(starting_point, 2 * pi) + x_mod = mod(x, 2 * pi) if x_mod < starting_point_mod: return 1 - self.integrate_numerically([x_mod, starting_point_mod]) @@ -73,6 +74,6 @@ def to_wn(self): @staticmethod def plot_circle(*args, **kwargs): - theta = np.append(linspace(0, 2 * np.pi, 320), 0) + theta = np.append(linspace(0, 2 * pi, 320), 0) p = plt.plot(cos(theta), sin(theta), *args, **kwargs) return p \ No newline at end of file diff --git a/pyrecest/distributions/circle/circular_fourier_distribution.py b/pyrecest/distributions/circle/circular_fourier_distribution.py index 5e66a824..d7471323 100644 --- a/pyrecest/distributions/circle/circular_fourier_distribution.py +++ b/pyrecest/distributions/circle/circular_fourier_distribution.py @@ -1,3 +1,4 @@ +from math import pi from typing import Union from pyrecest.backend import sum from pyrecest.backend import sqrt @@ -185,14 +186,14 @@ def integrate(self, integration_boundaries=None) -> float: a0_non_rooted = from_a0 + from_a1_to_end_and_b else: raise NotImplementedError("Transformation not supported.") - integral = a0_non_rooted * np.pi + integral = a0_non_rooted * pi elif self.c is not None: if self.transformation == "identity": if self.multiplied_by_n: c0 = real(self.c[0]) * (1 / self.n) else: c0 = real(self.c[0]) - integral = 2 * np.pi * c0 + integral = 2 * pi * c0 elif self.transformation == "sqrt": if self.multiplied_by_n: c = self.c * (1 / self.n) @@ -204,7 +205,7 @@ def integrate(self, integration_boundaries=None) -> float: ) a0_non_rooted = 2 * from_c0 + 4 * from_c1_to_end - integral = a0_non_rooted * np.pi + integral = a0_non_rooted * pi else: raise NotImplementedError("Transformation not supported.") else: @@ -213,7 +214,7 @@ def integrate(self, integration_boundaries=None) -> float: def plot_grid(self): grid_values = irfft(self.get_c(), self.n) - xs = linspace(0, 2 * np.pi, grid_values.shape[0], endpoint=False) + xs = linspace(0, 2 * pi, grid_values.shape[0], endpoint=False) vals = grid_values.squeeze() if self.transformation == "sqrt": @@ -229,7 +230,7 @@ def plot_grid(self): plt.show() def plot(self, resolution=128, **kwargs): - xs = linspace(0, 2 * np.pi, resolution) + xs = linspace(0, 2 * pi, resolution) if self.a is not None: xs = xs.astype(self.a.dtype) @@ -296,7 +297,7 @@ def from_distribution( if isinstance(distribution, CircularDiracDistribution): fd = CircularFourierDistribution( np.conj(distribution.trigonometric_moment(n, whole_range=True)) - / (2 * np.pi), + / (2 * pi), transformation, multiplied_by_n=False, ) @@ -304,7 +305,7 @@ def from_distribution( warnings.warn("Scaling up for WD (this is not recommended).") fd.c = fd.c * fd.n else: - xs = linspace(0, 2 * np.pi, n, endpoint=False) + xs = linspace(0, 2 * pi, n, endpoint=False) fvals = distribution.pdf(xs) if transformation == "identity": pass diff --git a/pyrecest/distributions/circle/circular_uniform_distribution.py b/pyrecest/distributions/circle/circular_uniform_distribution.py index 44668204..0fa1622d 100644 --- a/pyrecest/distributions/circle/circular_uniform_distribution.py +++ b/pyrecest/distributions/circle/circular_uniform_distribution.py @@ -1,3 +1,4 @@ +from math import pi import numpy as np from ..hypertorus.hypertoroidal_uniform_distribution import ( @@ -41,7 +42,7 @@ def cdf(self, xa, starting_point=0): cdf evaluated at columns of xa """ - val = (xa - starting_point) / (2 * np.pi) + val = (xa - starting_point) / (2 * pi) val[val < 0] = val[val < 0] + 1 return val \ No newline at end of file diff --git a/pyrecest/distributions/circle/custom_circular_distribution.py b/pyrecest/distributions/circle/custom_circular_distribution.py index c6ee5c06..97433dae 100644 --- a/pyrecest/distributions/circle/custom_circular_distribution.py +++ b/pyrecest/distributions/circle/custom_circular_distribution.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import mod from pyrecest.backend import array from collections.abc import Callable @@ -40,7 +41,7 @@ def pdf(self, xs: np.ndarray): np.ndarray: The value of the pdf at xs. """ return AbstractCustomDistribution.pdf( - self, mod(xs + self.shift_by, 2 * np.pi) + self, mod(xs + self.shift_by, 2 * pi) ) def integrate(self, integration_boundaries: np.ndarray | None = None) -> float: @@ -49,11 +50,11 @@ def integrate(self, integration_boundaries: np.ndarray | None = None) -> float: Args: integration_boundaries (np.ndarray, optional): The boundaries of the integral. - Defaults to [0, 2 * np.pi]. + Defaults to [0, 2 * pi]. Returns: float: The value of the integral. """ if integration_boundaries is None: - integration_boundaries = array([0, 2 * np.pi]) + integration_boundaries = array([0, 2 * pi]) return AbstractCircularDistribution.integrate(self, integration_boundaries) \ No newline at end of file diff --git a/pyrecest/distributions/circle/von_mises_distribution.py b/pyrecest/distributions/circle/von_mises_distribution.py index 95ad7996..2580fecf 100644 --- a/pyrecest/distributions/circle/von_mises_distribution.py +++ b/pyrecest/distributions/circle/von_mises_distribution.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import where from pyrecest.backend import sqrt from pyrecest.backend import sin @@ -40,7 +41,7 @@ def get_params(self): @property def norm_const(self) -> np.number: if self._norm_const is None: - self._norm_const = 2 * np.pi * iv(0, self.kappa) + self._norm_const = 2 * pi * iv(0, self.kappa) return self._norm_const def pdf(self, xs: np.ndarray) -> np.ndarray | np.number: @@ -75,7 +76,7 @@ def cdf(self, xs, starting_point=0): def to_minus_pi_to_pi_range( angle: np.number | numbers.Real | np.ndarray, ) -> np.number | numbers.Real | np.ndarray: - return mod(angle + np.pi, 2 * np.pi) - np.pi + return mod(angle + pi, 2 * pi) - pi r = vonmises.cdf( to_minus_pi_to_pi_range(xs), @@ -108,12 +109,12 @@ def f(t: float) -> float: def multiply(self, vm2: "VonMisesDistribution") -> "VonMisesDistribution": C = self.kappa * cos(self.mu) + vm2.kappa * cos(vm2.mu) S = self.kappa * sin(self.mu) + vm2.kappa * sin(vm2.mu) - mu_ = mod(arctan2(S, C), 2 * np.pi) + mu_ = mod(arctan2(S, C), 2 * pi) kappa_ = sqrt(C**2 + S**2) return VonMisesDistribution(mu_, kappa_) def convolve(self, vm2: "VonMisesDistribution") -> "VonMisesDistribution": - mu_ = mod(self.mu + vm2.mu, 2 * np.pi) + mu_ = mod(self.mu + vm2.mu, 2 * pi) t = VonMisesDistribution.besselratio( 0, self.kappa ) * VonMisesDistribution.besselratio(0, vm2.kappa) @@ -122,7 +123,7 @@ def convolve(self, vm2: "VonMisesDistribution") -> "VonMisesDistribution": def entropy(self): result = -self.kappa * VonMisesDistribution.besselratio(0, self.kappa) + log( - 2 * np.pi * iv(0, self.kappa) + 2 * pi * iv(0, self.kappa) ) return result @@ -137,7 +138,7 @@ def from_moment(m): Returns: vm (VMDistribution): VM distribution obtained by moment matching. """ - mu_ = mod(arctan2(imag(m), real(m)), 2 * np.pi) + mu_ = mod(arctan2(imag(m), real(m)), 2 * pi) kappa_ = VonMisesDistribution.besselratio_inverse(0, abs(m)) vm = VonMisesDistribution(mu_, kappa_) return vm diff --git a/pyrecest/distributions/circle/wrapped_cauchy_distribution.py b/pyrecest/distributions/circle/wrapped_cauchy_distribution.py index 3ea26fbf..2ab8c10c 100644 --- a/pyrecest/distributions/circle/wrapped_cauchy_distribution.py +++ b/pyrecest/distributions/circle/wrapped_cauchy_distribution.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import tanh from pyrecest.backend import tan from pyrecest.backend import sinh @@ -14,16 +15,16 @@ class WrappedCauchyDistribution(AbstractCircularDistribution): def __init__(self, mu, gamma): AbstractCircularDistribution.__init__(self) - self.mu = mod(mu, 2 * np.pi) + self.mu = mod(mu, 2 * pi) assert gamma > 0 self.gamma = gamma def pdf(self, xs): assert xs.ndim == 1 - xs = mod(xs - self.mu, 2 * np.pi) + xs = mod(xs - self.mu, 2 * pi) return ( 1 - / (2 * np.pi) + / (2 * pi) * sinh(self.gamma) / (cosh(self.gamma) - cos(xs - self.mu)) ) @@ -33,7 +34,7 @@ def coth(x): return 1 / tanh(x) assert xs.ndim == 1 - return np.arctan(coth(self.gamma / 2) * tan((xs - self.mu) / 2)) / np.pi + return np.arctan(coth(self.gamma / 2) * tan((xs - self.mu) / 2)) / pi def trigonometric_moment(self, n): m = exp(1j * n * self.mu - abs(n) * self.gamma) diff --git a/pyrecest/distributions/circle/wrapped_laplace_distribution.py b/pyrecest/distributions/circle/wrapped_laplace_distribution.py index 27e567f6..bc01453a 100644 --- a/pyrecest/distributions/circle/wrapped_laplace_distribution.py +++ b/pyrecest/distributions/circle/wrapped_laplace_distribution.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import ndim from pyrecest.backend import mod from pyrecest.backend import exp @@ -25,16 +26,16 @@ def trigonometric_moment(self, n): def pdf(self, xs): assert ndim(xs) <= 1 - xs = mod(xs, 2 * np.pi) + xs = mod(xs, 2 * pi) p = ( self.lambda_ * self.kappa / (1 + self.kappa**2) * ( exp(-self.lambda_ * self.kappa * xs) - / (1 - exp(-2 * np.pi * self.lambda_ * self.kappa)) + / (1 - exp(-2 * pi * self.lambda_ * self.kappa)) + exp(self.lambda_ / self.kappa * xs) - / (exp(2 * np.pi * self.lambda_ / self.kappa) - 1) + / (exp(2 * pi * self.lambda_ / self.kappa) - 1) ) ) return p \ No newline at end of file diff --git a/pyrecest/distributions/circle/wrapped_normal_distribution.py b/pyrecest/distributions/circle/wrapped_normal_distribution.py index 6bd7ef40..e2c84d29 100644 --- a/pyrecest/distributions/circle/wrapped_normal_distribution.py +++ b/pyrecest/distributions/circle/wrapped_normal_distribution.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import random from typing import Union from pyrecest.backend import where @@ -61,25 +62,25 @@ def pdf(self, xs: np.ndarray | np.number | numbers.Real): # check if sigma is large and return uniform distribution in this case if self.sigma > self.MAX_SIGMA_BEFORE_UNIFORM: - result[:] = 1.0 / (2 * np.pi) + result[:] = 1.0 / (2 * pi) return result - x = mod(xs, 2 * np.pi) - x[x < 0] += 2 * np.pi + x = mod(xs, 2 * pi) + x[x < 0] += 2 * pi x -= self.mu max_iterations = 1000 tmp = -1.0 / (2 * self.sigma**2) - nc = 1 / sqrt(2 * np.pi) / self.sigma + nc = 1 / sqrt(2 * pi) / self.sigma for i in range(n_inputs): old_result = 0 result[i] = exp(x[i] * x[i] * tmp) for k in range(1, max_iterations + 1): - xp = x[i] + 2 * np.pi * k - xm = x[i] - 2 * np.pi * k + xp = x[i] + 2 * pi * k + xm = x[i] - 2 * pi * k tp = xp * xp * tmp tm = xm * xm * tmp old_result = result[i] @@ -98,8 +99,8 @@ def cdf( startingPoint: float = 0, n_wraps: Union[int, int32, int64] = 10, ) -> np.ndarray: - startingPoint = mod(startingPoint, 2 * np.pi) - xs = mod(xs, 2 * np.pi) + startingPoint = mod(startingPoint, 2 * pi) + xs = mod(xs, 2 * pi) def ncdf(from_, to): return ( @@ -115,8 +116,8 @@ def ncdf(from_, to): for i in range(1, n_wraps + 1): val = ( val - + ncdf(startingPoint + 2 * np.pi * i, xs + 2 * np.pi * i) - + ncdf(startingPoint - 2 * np.pi * i, xs - 2 * np.pi * i) + + ncdf(startingPoint + 2 * pi * i, xs + 2 * pi * i) + + ncdf(startingPoint - 2 * pi * i, xs - 2 * pi * i) ) # Val should be negative when x < startingPoint val = where(xs < startingPoint, 1 + val, val) @@ -140,7 +141,7 @@ def multiply_vm(self, other): return wn def sample(self, n: Union[int, int32, int64]) -> np.ndarray: - return mod(self.mu + self.sigma * random.randn(1, n), 2 * np.pi) + return mod(self.mu + self.sigma * random.randn(1, n), 2 * pi) def shift(self, shift_by): assert np.isscalar(shift_by) @@ -153,7 +154,7 @@ def to_vm(self) -> VonMisesDistribution: @staticmethod def from_moment(m: complex) -> "WrappedNormalDistribution": - mu = mod(np.angle(m), 2 * np.pi) + mu = mod(np.angle(m), 2 * pi) sigma = sqrt(-2 * log(abs(m))) return WrappedNormalDistribution(mu, sigma) diff --git a/pyrecest/distributions/ellipsoidal_ball_uniform_distribution.py b/pyrecest/distributions/ellipsoidal_ball_uniform_distribution.py index 5df52733..7409c909 100644 --- a/pyrecest/distributions/ellipsoidal_ball_uniform_distribution.py +++ b/pyrecest/distributions/ellipsoidal_ball_uniform_distribution.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import random from typing import Union from pyrecest.backend import sqrt @@ -45,7 +46,7 @@ def pdf(self, xs: np.ndarray): """ assert xs.shape[-1] == self.dim # Calculate the reciprocal of the volume of the ellipsoid - # reciprocal_volume = 1 / (power(np.pi, self.dim / 2) * sqrt(np.linalg.det(self.shape_matrix)) / gamma(self.dim / 2 + 1)) + # reciprocal_volume = 1 / (power(pi, self.dim / 2) * sqrt(np.linalg.det(self.shape_matrix)) / gamma(self.dim / 2 + 1)) reciprocal_volume = 1 / self.get_manifold_size() if xs.ndim == 1: return reciprocal_volume diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py index a8c38b2e..47a94b4b 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import random from typing import Union from pyrecest.backend import vstack @@ -68,12 +69,12 @@ def mean_direction_numerical(self) -> np.ndarray: warnings.warn(warning_msg) if self.dim == 1: - mu = super().mean_direction_numerical([0, np.pi]) + mu = super().mean_direction_numerical([0, pi]) elif self.dim <= 3: mu = super().mean_direction_numerical( [ zeros(self.dim), - [2 * np.pi, *np.pi * ones(self.dim - 2), np.pi / 2], + [2 * pi, *pi * ones(self.dim - 2), pi / 2], ] ) else: @@ -98,13 +99,13 @@ def mean_direction_numerical(self) -> np.ndarray: @staticmethod def get_full_integration_boundaries(dim: Union[int, int32, int64]) -> np.ndarray: if dim == 1: - integration_boundaries = [0, np.pi] + integration_boundaries = [0, pi] else: integration_boundaries = vstack( ( zeros(dim), concatenate( - ([2 * np.pi], np.pi * ones(dim - 2), [np.pi / 2]) + ([2 * pi], pi * ones(dim - 2), [pi / 2]) ), ) ).T @@ -147,7 +148,7 @@ def objective_function_2d(s): assert self.dim == 2, "Currently only implemented for 2D hemispheres." - s0 = random.rand(self.dim) * np.pi + s0 = random.rand(self.dim) * pi result = minimize( objective_function_2d, s0, diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py index 29ec50d2..9f89e508 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py @@ -1,3 +1,4 @@ +from math import pi from typing import Union from pyrecest.backend import sort from pyrecest.backend import squeeze @@ -359,11 +360,11 @@ def polar_to_cart(polar_coords: np.ndarray) -> np.ndarray: @staticmethod def compute_unit_hypersphere_surface(dim: Union[int, int32, int64]) -> float: if dim == 1: - surface_area = 2 * np.pi + surface_area = 2 * pi elif dim == 2: - surface_area = 4 * np.pi + surface_area = 4 * pi elif dim == 3: - surface_area = 2 * np.pi**2 + surface_area = 2 * pi**2 else: - surface_area = 2 * np.pi ** ((dim + 1) / 2) / gamma((dim + 1) / 2) + surface_area = 2 * pi ** ((dim + 1) / 2) / gamma((dim + 1) / 2) return surface_area \ No newline at end of file diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py index 52b41e22..769562bd 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import random from typing import Union from pyrecest.backend import vstack @@ -88,7 +89,7 @@ def plot( grid_faces: Union[int, int32, int64] = 20, ) -> None: if self.dim == 1: - phi = linspace(0, 2 * np.pi, 320) + phi = linspace(0, 2 * pi, 320) x = array([sin(phi), cos(phi)]) p = self.pdf(x) plt.plot(phi, p) @@ -157,12 +158,12 @@ def moment(self) -> np.ndarray: @staticmethod def get_full_integration_boundaries(dim): if dim == 1: - return [0, 2 * np.pi] + return [0, 2 * pi] return vstack( ( zeros(dim), - concatenate(([2 * np.pi], np.pi * ones(dim - 1))), + concatenate(([2 * pi], pi * ones(dim - 1))), ) ).T @@ -189,7 +190,7 @@ def mode_numerical(self) -> np.ndarray: def fun(s): return -self.pdf(AbstractHypersphereSubsetDistribution.polar_to_cart(s)) - s0 = random.rand(self.dim) * np.pi + s0 = random.rand(self.dim) * pi res = minimize( fun, s0, @@ -208,8 +209,8 @@ def total_variation_distance(self, other: "AbstractHypersphericalDistribution"): @staticmethod def create_sphere(faces): phi, theta = np.mgrid[ - 0.0 : np.pi : complex(0, faces), # noqa: E203 - 0.0 : 2.0 * np.pi : complex(0, faces), # noqa: E203 + 0.0 : pi : complex(0, faces), # noqa: E203 + 0.0 : 2.0 * pi : complex(0, faces), # noqa: E203 ] x = sin(phi) * cos(theta) y = sin(phi) * sin(theta) @@ -231,8 +232,8 @@ def plot_unit_sphere(): num_points = 1000 # Generate theta and phi angles (in radians) - theta = linspace(0, 2 * np.pi, num_points) - phi = linspace(0, np.pi, num_points) + theta = linspace(0, 2 * pi, num_points) + phi = linspace(0, pi, num_points) # Create a meshgrid for theta and phi angles theta, phi = meshgrid(theta, phi) diff --git a/pyrecest/distributions/hypersphere_subset/abstract_sphere_subset_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_sphere_subset_distribution.py index f27b8d7c..ad113bda 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_sphere_subset_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_sphere_subset_distribution.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import where from pyrecest.backend import sin from pyrecest.backend import ndim @@ -108,7 +109,7 @@ def _sph_to_cart_elevation(azimuth: np.ndarray, elevation: np.ndarray) -> tuple: ndim(azimuth) == 1 and ndim(elevation) == 1 ), "Inputs must be 1-dimensional" # elevation is π/2 - colatitude, so we calculate colatitude from elevation - colatitude = np.pi / 2 - elevation + colatitude = pi / 2 - elevation x = sin(colatitude) * cos(azimuth) y = sin(colatitude) * sin(azimuth) z = cos(colatitude) @@ -119,7 +120,7 @@ def _cart_to_sph_colatitude(x: np.ndarray, y: np.ndarray, z: np.ndarray) -> tupl assert ndim(x) == 1 and ndim(y) == 1 and ndim(z) radius = 1 azimuth = arctan2(y, x) - azimuth = where(azimuth < 0, azimuth + 2 * np.pi, azimuth) + azimuth = where(azimuth < 0, azimuth + 2 * pi, azimuth) colatitude = arccos(z / radius) return azimuth, colatitude @@ -128,6 +129,6 @@ def _cart_to_sph_elevation(x: np.ndarray, y: np.ndarray, z: np.ndarray) -> tuple assert ndim(x) == 1 and ndim(y) == 1 and ndim(z) == 1 radius = 1 azimuth = arctan2(y, x) - azimuth = where(azimuth < 0, azimuth + 2 * np.pi, azimuth) - elevation = np.pi / 2 - arccos(z / radius) # elevation is π/2 - colatitude + azimuth = where(azimuth < 0, azimuth + 2 * pi, azimuth) + elevation = pi / 2 - arccos(z / radius) # elevation is π/2 - colatitude return azimuth, elevation \ No newline at end of file diff --git a/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py index 0aa4b4f0..1c9f6b4e 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import sqrt from pyrecest.backend import real from pyrecest.backend import isnan @@ -73,7 +74,7 @@ def normalize_in_place(self): def integrate(self): if self.transformation == "identity": - int_val = self.coeff_mat[0, 0] * sqrt(4 * np.pi) + int_val = self.coeff_mat[0, 0] * sqrt(4 * pi) elif self.transformation == "sqrt": int_val = norm(self.coeff_mat[~isnan(self.coeff_mat)]) ** 2 else: diff --git a/pyrecest/distributions/hypersphere_subset/bingham_distribution.py b/pyrecest/distributions/hypersphere_subset/bingham_distribution.py index 53239842..68058785 100644 --- a/pyrecest/distributions/hypersphere_subset/bingham_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/bingham_distribution.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import sum from pyrecest.backend import eye from pyrecest.backend import exp @@ -59,7 +60,7 @@ def ifun(u): 0.5 * (Z[0] + Z[1]) * u + 0.5 * (Z[2] + Z[3]) * (1 - u) ) - return 2 * np.pi**2 * quad(ifun, 0, 1)[0] + return 2 * pi**2 * quad(ifun, 0, 1)[0] def pdf(self, xs): assert xs.shape[-1] == self.dim + 1 diff --git a/pyrecest/distributions/hypersphere_subset/hyperspherical_uniform_distribution.py b/pyrecest/distributions/hypersphere_subset/hyperspherical_uniform_distribution.py index 97e718b3..ec188d4f 100644 --- a/pyrecest/distributions/hypersphere_subset/hyperspherical_uniform_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/hyperspherical_uniform_distribution.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import random from typing import Union from pyrecest.backend import sqrt @@ -34,7 +35,7 @@ def sample(self, n: Union[int, int32, int64]): self.dim + 1, ) ) - phi = 2 * np.pi * random.rand(n) + phi = 2 * pi * random.rand(n) s[:, 2] = random.rand(n) * 2 - 1 r = sqrt(1 - s[:, 2] ** 2) s[:, 0] = r * cos(phi) diff --git a/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py b/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py index 6fd36c84..425ba524 100644 --- a/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py +++ b/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import sqrt from pyrecest.backend import sin from pyrecest.backend import shape @@ -169,10 +170,10 @@ def imag_part(phi, theta, n, m): for n in range(degree + 1): # Use n instead of l to comply with PEP 8 for m in range(-n, n + 1): real_integral, _ = scipy.integrate.nquad( - real_part, [[0, 2 * np.pi], [0, np.pi]], args=(n, m) + real_part, [[0, 2 * pi], [0, pi]], args=(n, m) ) imag_integral, _ = scipy.integrate.nquad( - imag_part, [[0, 2 * np.pi], [0, np.pi]], args=(n, m) + imag_part, [[0, 2 * pi], [0, pi]], args=(n, m) ) if isnan(real_integral) or isnan(imag_integral): diff --git a/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py b/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py index b0842162..13148391 100644 --- a/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py @@ -1,3 +1,4 @@ +from math import pi from typing import Union from pyrecest.backend import sinh from pyrecest.backend import sin @@ -33,10 +34,10 @@ def __init__(self, mu: np.ndarray, kappa: np.number | numbers.Real): self.kappa = kappa if self.dim == 2: - self.C = kappa / (4 * np.pi * sinh(kappa)) + self.C = kappa / (4 * pi * sinh(kappa)) else: self.C = kappa ** ((self.dim + 1) / 2 - 1) / ( - (2 * np.pi) ** ((self.dim + 1) / 2) * iv((self.dim + 1) / 2 - 1, kappa) + (2 * pi) ** ((self.dim + 1) / 2) * iv((self.dim + 1) / 2 - 1, kappa) ) def pdf(self, xs: np.ndarray | np.number) -> np.ndarray | np.number: diff --git a/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py b/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py index 3af02686..1bb07943 100644 --- a/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py +++ b/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import random from typing import Union from pyrecest.backend import vstack @@ -40,7 +41,7 @@ def input_dim(self) -> int: @staticmethod def integrate_fun_over_domain(f: Callable, dim: Union[int, int32, int64]) -> float: - integration_boundaries = [(0, 2 * np.pi)] * dim + integration_boundaries = [(0, 2 * pi)] * dim return AbstractHypertoroidalDistribution.integrate_fun_over_domain_part( f, dim, integration_boundaries ) @@ -65,7 +66,7 @@ def shift(self, shift_by): # Define the shifted PDF def shifted_pdf(xs): - return self.pdf(mod(xs + shift_by, 2 * np.pi)) + return self.pdf(mod(xs + shift_by, 2 * pi)) # Create the shifted distribution shifted_distribution = CustomHypertoroidalDistribution(shifted_pdf, self.dim) @@ -88,7 +89,7 @@ def integrate_numerically( ) -> np.number | numbers.Real: if integration_boundaries is None: integration_boundaries = vstack( - (zeros(self.dim), 2 * np.pi * ones(self.dim)) + (zeros(self.dim), 2 * pi * ones(self.dim)) ) integration_boundaries = reshape(integration_boundaries, (2, -1)) @@ -137,7 +138,7 @@ def entropy_fun(*args): return -self.integrate_fun_over_domain(entropy_fun, self.dim) def get_manifold_size(self): - return (2 * np.pi) ** self.dim + return (2 * pi) ** self.dim @staticmethod def angular_error(alpha, beta): @@ -153,14 +154,14 @@ def angular_error(alpha, beta): """ assert not isnan(alpha).any() and not isnan(beta).any() # Ensure the angles are between 0 and 2*pi - alpha = mod(alpha, 2 * np.pi) - beta = mod(beta, 2 * np.pi) + alpha = mod(alpha, 2 * pi) + beta = mod(beta, 2 * pi) # Calculate the absolute difference diff = abs(alpha - beta) # Calculate the angular error - e = np.minimum(diff, 2 * np.pi - diff) + e = np.minimum(diff, 2 * pi - diff) return e @@ -192,14 +193,14 @@ def total_variation_dist_fun(*args): def plot(self, resolution=128, **kwargs): if self.dim == 1: - theta = linspace(0, 2 * np.pi, resolution) + theta = linspace(0, 2 * pi, resolution) f_theta = self.pdf(theta) p = plt.plot(theta, f_theta, **kwargs) AbstractHypertoroidalDistribution.setup_axis_circular("x") elif self.dim == 2: - step = 2 * np.pi / resolution + step = 2 * pi / resolution alpha, beta = meshgrid( - arange(0, 2 * np.pi, step), arange(0, 2 * np.pi, step) + arange(0, 2 * pi, step), arange(0, 2 * pi, step) ) f = self.pdf(vstack((alpha.ravel(), beta.ravel()))) f = f.reshape(alpha.shape) @@ -227,7 +228,7 @@ def mean(self) -> np.ndarray: def mean_direction(self) -> np.ndarray: a = self.trigonometric_moment(1) - m = mod(np.angle(a), 2 * np.pi) + m = mod(np.angle(a), 2 * pi) return m def mode(self) -> np.ndarray: @@ -261,7 +262,7 @@ def sample_metropolis_hastings( if proposal is None: def proposal(x): - return mod(x + random.randn(self.dim), 2 * np.pi) + return mod(x + random.randn(self.dim), 2 * pi) if start_point is None: start_point = self.mean_direction() @@ -274,18 +275,18 @@ def proposal(x): @staticmethod def setup_axis_circular(axis_name: str = "x", ax=plt.gca()) -> None: - ticks = [0, np.pi, 2 * np.pi] + ticks = [0, pi, 2 * pi] tick_labels = ["0", r"$\pi$", r"$2\pi$"] if axis_name == "x": - ax.set_xlim(left=0, right=2 * np.pi) + ax.set_xlim(left=0, right=2 * pi) ax.set_xticks(ticks) ax.set_xticklabels(tick_labels) elif axis_name == "y": - ax.set_ylim(left=0, right=2 * np.pi) + ax.set_ylim(left=0, right=2 * pi) ax.set_yticks(ticks) ax.set_yticklabels(tick_labels) elif axis_name == "z": - ax.set_zlim(left=0, right=2 * np.pi) + ax.set_zlim(left=0, right=2 * pi) ax.set_zticks(ticks) ax.set_zticklabels(tick_labels) else: diff --git a/pyrecest/distributions/hypertorus/abstract_toroidal_distribution.py b/pyrecest/distributions/hypertorus/abstract_toroidal_distribution.py index 8c33e158..900f3190 100644 --- a/pyrecest/distributions/hypertorus/abstract_toroidal_distribution.py +++ b/pyrecest/distributions/hypertorus/abstract_toroidal_distribution.py @@ -1,3 +1,4 @@ +from math import pi from typing import Union from pyrecest.backend import sqrt from pyrecest.backend import sin @@ -36,7 +37,7 @@ def f( C = zeros((4, 4)) for i in range(4): for j in range(i, 4): - C[i, j], _ = dblquad(f, 0, 2 * np.pi, 0, 2 * np.pi, args=(i, j)) + C[i, j], _ = dblquad(f, 0, 2 * pi, 0, 2 * pi, args=(i, j)) if i != j: C[j, i] = C[i, j] @@ -58,9 +59,9 @@ def fsinAsquared(x, y): def fsinBsquared(x, y): return self.pdf(array([x, y])) * sin(y - m[1]) ** 2 - EsinAsinB, _ = dblquad(fsinAsinB, 0, 2 * np.pi, 0, 2 * np.pi) - EsinAsquared, _ = dblquad(fsinAsquared, 0, 2 * np.pi, 0, 2 * np.pi) - EsinBsquared, _ = dblquad(fsinBsquared, 0, 2 * np.pi, 0, 2 * np.pi) + EsinAsinB, _ = dblquad(fsinAsinB, 0, 2 * pi, 0, 2 * pi) + EsinAsquared, _ = dblquad(fsinAsquared, 0, 2 * pi, 0, 2 * pi) + EsinBsquared, _ = dblquad(fsinBsquared, 0, 2 * pi, 0, 2 * pi) rhoc = EsinAsinB / sqrt(EsinAsquared * EsinBsquared) return rhoc diff --git a/pyrecest/distributions/hypertorus/custom_hypertoroidal_distribution.py b/pyrecest/distributions/hypertorus/custom_hypertoroidal_distribution.py index e01c5cdb..1b6fbd42 100644 --- a/pyrecest/distributions/hypertorus/custom_hypertoroidal_distribution.py +++ b/pyrecest/distributions/hypertorus/custom_hypertoroidal_distribution.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import mod from pyrecest.backend import zeros import numpy as np @@ -29,7 +30,7 @@ def __init__(self, f, dim, shift_by=None): def pdf(self, xs): return AbstractCustomDistribution.pdf( - self, mod(xs + self.shift_by, 2 * np.pi) + self, mod(xs + self.shift_by, 2 * pi) ) def to_custom_circular(self): diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py b/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py index 88993f15..6b6bf489 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py @@ -1,3 +1,4 @@ +from math import pi from typing import Union from pyrecest.backend import tile from pyrecest.backend import sum @@ -36,7 +37,7 @@ def __init__( AbstractHypertoroidalDistribution.__init__(self, dim) AbstractDiracDistribution.__init__( - self, np.atleast_1d(mod(d, 2 * np.pi)), w=w + self, np.atleast_1d(mod(d, 2 * pi)), w=w ) def plot(self, *args, **kwargs): @@ -50,7 +51,7 @@ def mean_direction(self) -> np.ndarray: :return: Mean direction """ a = self.trigonometric_moment(1) - m = mod(arctan2(imag(a), real(a)), 2 * np.pi) + m = mod(arctan2(imag(a), real(a)), 2 * pi) return m def trigonometric_moment(self, n: Union[int, int32, int64]) -> np.ndarray: @@ -67,7 +68,7 @@ def trigonometric_moment(self, n: Union[int, int32, int64]) -> np.ndarray: def apply_function(self, f: Callable) -> "HypertoroidalDiracDistribution": dist = super().apply_function(f) - dist.d = mod(dist.d, 2 * np.pi) + dist.d = mod(dist.d, 2 * pi) return dist def to_toroidal_wd(self): @@ -92,7 +93,7 @@ def marginalize_out(self, dimensions: int | list[int]): def shift(self, shift_by) -> "HypertoroidalDiracDistribution": assert shift_by.shape[-1] == self.dim hd = copy.copy(self) - hd.d = mod(self.d + reshape(shift_by, (1, -1)), 2 * np.pi) + hd.d = mod(self.d + reshape(shift_by, (1, -1)), 2 * pi) return hd def entropy(self): diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_uniform_distribution.py b/pyrecest/distributions/hypertorus/hypertoroidal_uniform_distribution.py index 95a6752a..7b0f2990 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_uniform_distribution.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_uniform_distribution.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import random from typing import Union from pyrecest.backend import prod @@ -43,7 +44,7 @@ def entropy(self) -> float: :returns: Entropy """ - return self.dim * log(2 * np.pi) + return self.dim * log(2 * pi) def mean_direction(self): """ @@ -63,7 +64,7 @@ def sample(self, n: Union[int, int32, int64]) -> np.ndarray: :param n: Sample size :returns: Sample of size n """ - return 2 * np.pi * random.rand(n, self.dim) + return 2 * pi * random.rand(n, self.dim) def shift(self, shift_by) -> "HypertoroidalUniformDistribution": """ @@ -88,11 +89,11 @@ def integrate( """ if integration_boundaries is None: left = zeros((self.dim,)) - right = 2 * np.pi * ones((self.dim,)) + right = 2 * pi * ones((self.dim,)) else: left, right = integration_boundaries assert ndim(left) == 0 and self.dim == 1 or left.shape == (self.dim,) assert ndim(right) == 0 and self.dim == 1 or right.shape == (self.dim,) volume = prod(right - left) - return 1 / (2 * np.pi) ** self.dim * volume \ No newline at end of file + return 1 / (2 * pi) ** self.dim * volume \ No newline at end of file diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py b/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py index 04d5c48f..3c067a60 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import random from typing import Union from pyrecest.backend import reshape @@ -39,7 +40,7 @@ def __init__(self, mu: np.ndarray, C: np.ndarray): np.size(C) == np.size(mu) or np.size(mu) == C.shape[1] ), "mu must be dim x 1" - self.mu = mod(mu, 2 * np.pi) + self.mu = mod(mu, 2 * pi) self.C = C def pdf(self, xs: np.ndarray, m: Union[int, int32, int64] = 3) -> np.ndarray: @@ -53,7 +54,7 @@ def pdf(self, xs: np.ndarray, m: Union[int, int32, int64] = 3) -> np.ndarray: xs = reshape(xs, (-1, self.dim)) # Generate all combinations of offsets for each dimension - offsets = [arange(-m, m + 1) * 2 * np.pi for _ in range(self.dim)] + offsets = [arange(-m, m + 1) * 2 * pi for _ in range(self.dim)] offset_combinations = array(meshgrid(*offsets)).T.reshape(-1, self.dim) # Calculate the PDF values by considering all combinations of offsets @@ -77,7 +78,7 @@ def shift(self, shift_by) -> "HypertoroidalWrappedNormalDistribution": assert shift_by.shape == (self.dim,) hd = self - hd.mu = mod(self.mu + shift_by, 2 * np.pi) + hd.mu = mod(self.mu + shift_by, 2 * pi) return hd def sample(self, n): @@ -88,12 +89,12 @@ def sample(self, n): raise ValueError("n must be a positive integer") s = random.multivariate_normal(self.mu, self.C, n) - s = mod(s, 2 * np.pi) # wrap the samples + s = mod(s, 2 * pi) # wrap the samples return s def convolve(self, other: "HypertoroidalWrappedNormalDistribution"): assert self.dim == other.dim, "Dimensions of the two distributions must match" - mu_ = (self.mu + other.mu) % (2 * np.pi) + mu_ = (self.mu + other.mu) % (2 * pi) C_ = self.C + other.C dist_result = self.__class__(mu_, C_) return dist_result diff --git a/pyrecest/distributions/hypertorus/toroidal_von_mises_sine_distribution.py b/pyrecest/distributions/hypertorus/toroidal_von_mises_sine_distribution.py index e667f2ea..7ac03f6f 100644 --- a/pyrecest/distributions/hypertorus/toroidal_von_mises_sine_distribution.py +++ b/pyrecest/distributions/hypertorus/toroidal_von_mises_sine_distribution.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import sum from pyrecest.backend import sin from pyrecest.backend import mod @@ -18,7 +19,7 @@ def __init__(self, mu, kappa, lambda_): assert np.isscalar(lambda_) assert all(kappa >= 0) - self.mu = mod(mu, 2 * np.pi) + self.mu = mod(mu, 2 * pi) self.kappa = kappa self.lambda_ = lambda_ @@ -34,7 +35,7 @@ def s(m): * iv(m, self.kappa[1]) ) - Cinv = 4 * np.pi**2 * sum([s(m) for m in range(11)]) + Cinv = 4 * pi**2 * sum([s(m) for m in range(11)]) return Cinv def pdf(self, xs): diff --git a/pyrecest/evaluation/eot_shape_database.py b/pyrecest/evaluation/eot_shape_database.py index 5e328c2f..9d84841c 100644 --- a/pyrecest/evaluation/eot_shape_database.py +++ b/pyrecest/evaluation/eot_shape_database.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import random from pyrecest.backend import sin from pyrecest.backend import linspace @@ -133,7 +134,7 @@ class Star(StarShapedPolygon): # pylint: disable=abstract-method __slots__ = Polygon.__slots__ def __new__(cls, radius=1, arms=5, arm_width=0.3, center=(0, 0)): - arm_angle = 2 * np.pi / arms + arm_angle = 2 * pi / arms points = [] for i in range(arms): base_angle = i * arm_angle @@ -212,7 +213,7 @@ class StarFish(StarShapedPolygon): # pylint: disable=abstract-method # pylint: disable=signature-differs def __new__(cls, scaling_factor=1): - theta = linspace(0, 2 * np.pi, 1000) + theta = linspace(0, 2 * pi, 1000) r = 5 + 1.5 * sin(6 * theta) x = r * cos(theta) * scaling_factor diff --git a/pyrecest/evaluation/generate_measurements.py b/pyrecest/evaluation/generate_measurements.py index dd623642..b1968a1e 100644 --- a/pyrecest/evaluation/generate_measurements.py +++ b/pyrecest/evaluation/generate_measurements.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import random from pyrecest.backend import tile from pyrecest.backend import sum @@ -166,7 +167,7 @@ def generate_measurements(groundtruth, simulation_config): ) + noise_samples ), - 2 * np.pi, + 2 * pi, ) elif isinstance( diff --git a/pyrecest/filters/hypertoroidal_particle_filter.py b/pyrecest/filters/hypertoroidal_particle_filter.py index 79db1ed4..33a7e1bc 100644 --- a/pyrecest/filters/hypertoroidal_particle_filter.py +++ b/pyrecest/filters/hypertoroidal_particle_filter.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import random from typing import Union from pyrecest.backend import tile @@ -38,12 +39,12 @@ def __init__( if dim == 1: # Prevents ambiguities if a vector is of size (dim,) or (n,) (for dim=1) filter_state = CircularDiracDistribution( - linspace(0, 2 * np.pi, n_particles, endpoint=False) + linspace(0, 2 * pi, n_particles, endpoint=False) ) else: filter_state = HypertoroidalDiracDistribution( tile( - linspace(0, 2 * np.pi, n_particles, endpoint=False), (dim, 1) + linspace(0, 2 * pi, n_particles, endpoint=False), (dim, 1) ).T.squeeze(), dim=dim, ) @@ -73,7 +74,7 @@ def predict_nonlinear( if noise_distribution is not None: noise = noise_distribution.sample(self.filter_state.w.size) self.filter_state.d += squeeze(noise) - self.filter_state.d = mod(self.filter_state.d, 2 * np.pi) + self.filter_state.d = mod(self.filter_state.d, 2 * pi) def predict_nonlinear_nonadditive( self, f: Callable, samples: np.ndarray, weights: np.ndarray diff --git a/pyrecest/filters/von_mises_filter.py b/pyrecest/filters/von_mises_filter.py index 8ec91630..5c142f59 100644 --- a/pyrecest/filters/von_mises_filter.py +++ b/pyrecest/filters/von_mises_filter.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import mod import copy import warnings @@ -68,6 +69,6 @@ def update_identity(self, vmMeas: VonMisesDistribution, z=0.0): ) warnings.warn(warning_message) - muWnew = mod(z - vmMeas.mu, 2 * np.pi) + muWnew = mod(z - vmMeas.mu, 2 * pi) vmMeasShifted = VonMisesDistribution(muWnew, vmMeas.kappa) self.filter_state = self.filter_state.multiply(vmMeasShifted) \ No newline at end of file diff --git a/pyrecest/filters/wrapped_normal_filter.py b/pyrecest/filters/wrapped_normal_filter.py index c970d67e..750c15c4 100644 --- a/pyrecest/filters/wrapped_normal_filter.py +++ b/pyrecest/filters/wrapped_normal_filter.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import mod from pyrecest.backend import log from pyrecest.backend import array @@ -21,7 +22,7 @@ def predict_identity(self, wn_sys): self.filter_state = self.filter_state.convolve(wn_sys) def update_identity(self, wn_meas, z): - mu_w_new = mod(z - wn_meas.mu, 2 * np.pi) + mu_w_new = mod(z - wn_meas.mu, 2 * pi) wn_meas_shifted = WrappedNormalDistribution(mu_w_new, wn_meas.sigma) self.filter_state = self.filter_state.multiply_vm(wn_meas_shifted) diff --git a/pyrecest/sampling/hyperspherical_sampler.py b/pyrecest/sampling/hyperspherical_sampler.py index 617f80c1..bccd6a25 100644 --- a/pyrecest/sampling/hyperspherical_sampler.py +++ b/pyrecest/sampling/hyperspherical_sampler.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import vstack from pyrecest.backend import sqrt from pyrecest.backend import sin @@ -133,7 +134,7 @@ def get_grid_spherical_coordinates( self, grid_density_parameter: int ) -> tuple[np.ndarray, np.ndarray, dict]: indices = arange(0, grid_density_parameter, dtype=float) + 0.5 - phi = np.pi * (1 + 5**0.5) * indices + phi = pi * (1 + 5**0.5) * indices theta = arccos(1 - 2 * indices / grid_density_parameter) grid_specific_description = { "scheme": "spherical_fibonacci", diff --git a/pyrecest/sampling/hypertoroidal_sampler.py b/pyrecest/sampling/hypertoroidal_sampler.py index 4ae72546..a32e04e7 100644 --- a/pyrecest/sampling/hypertoroidal_sampler.py +++ b/pyrecest/sampling/hypertoroidal_sampler.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import linspace import numpy as np from beartype import beartype @@ -22,7 +23,7 @@ def get_grid(self, grid_density_parameter: int) -> np.ndarray: """ Returns an equidistant grid of points on the circle [0,2*pi). """ - points = linspace(0, 2 * np.pi, grid_density_parameter, endpoint=False) + points = linspace(0, 2 * pi, grid_density_parameter, endpoint=False) # Set it to the middle of the interval instead of the start - points += (2 * np.pi / grid_density_parameter) / 2 + points += (2 * pi / grid_density_parameter) / 2 return points \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_abstract_circular_distribution.py b/pyrecest/tests/distributions/test_abstract_circular_distribution.py index 54741e31..0208332b 100644 --- a/pyrecest/tests/distributions/test_abstract_circular_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_circular_distribution.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import arange from pyrecest.backend import allclose from pyrecest.backend import all @@ -53,10 +54,10 @@ def test_integral_numerical(self): (2, 2), (2, 3), (5, 4), - (0, 4 * np.pi), - (-np.pi, np.pi), - (0, 4 * np.pi), - (-3 * np.pi, 3 * np.pi), + (0, 4 * pi), + (-pi, pi), + (0, 4 * pi), + (-3 * pi, 3 * pi), (-1, 20), (12, -3), ] diff --git a/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py b/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py index 130ad295..888af027 100644 --- a/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import ones from pyrecest.backend import array from pyrecest.backend import arange @@ -39,7 +40,7 @@ def test_condition_on_periodic(self): zeros(10), atol=1e-10, ) - dist_cond2 = hwn.condition_on_periodic(array(1.5) + 2 * np.pi) + dist_cond2 = hwn.condition_on_periodic(array(1.5) + 2 * pi) np.testing.assert_allclose( np.diff( hwn.pdf(np.column_stack([1.5 * ones(11), arange(-5, 6)])) @@ -62,7 +63,7 @@ def test_condition_on_linear(self): zeros(10), atol=1e-10, ) - dist_cond2 = hwn.condition_on_linear(array(1.5 + 2 * np.pi)) + dist_cond2 = hwn.condition_on_linear(array(1.5 + 2 * pi)) self.assertFalse( ( allclose( diff --git a/pyrecest/tests/distributions/test_abstract_hyperhemispherical_distribution.py b/pyrecest/tests/distributions/test_abstract_hyperhemispherical_distribution.py index 2b3806b3..54e6cdf8 100644 --- a/pyrecest/tests/distributions/test_abstract_hyperhemispherical_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hyperhemispherical_distribution.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import sum from pyrecest.backend import ones from pyrecest.backend import array @@ -23,7 +24,7 @@ def setUp(self): def test_get_manifold_size(self): """Tests get_manifold_size function with different dimensions.""" - dimensions = [(1, np.pi), (2, 2 * np.pi)] + dimensions = [(1, pi), (2, 2 * pi)] for dim, expected in dimensions: with self.subTest(dim=dim): hud = HyperhemisphericalUniformDistribution(dim) diff --git a/pyrecest/tests/distributions/test_abstract_hyperspherical_distribution.py b/pyrecest/tests/distributions/test_abstract_hyperspherical_distribution.py index 6ed406f1..224b52ab 100644 --- a/pyrecest/tests/distributions/test_abstract_hyperspherical_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hyperspherical_distribution.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import sqrt from pyrecest.backend import array import unittest @@ -33,17 +34,17 @@ def testUnitSphereSurface(self): """Tests the unit sphere surface computation.""" self.assertAlmostEqual( AbstractHypersphericalDistribution.compute_unit_hypersphere_surface(1), - 2 * np.pi, + 2 * pi, delta=1e-10, ) self.assertAlmostEqual( AbstractHypersphericalDistribution.compute_unit_hypersphere_surface(2), - 4 * np.pi, + 4 * pi, delta=1e-10, ) self.assertAlmostEqual( AbstractHypersphericalDistribution.compute_unit_hypersphere_surface(3), - 2 * np.pi**2, + 2 * pi**2, delta=1e-10, ) diff --git a/pyrecest/tests/distributions/test_abstract_hypertoroidal_distribution.py b/pyrecest/tests/distributions/test_abstract_hypertoroidal_distribution.py index 5d6e699c..22f9f975 100644 --- a/pyrecest/tests/distributions/test_abstract_hypertoroidal_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hypertoroidal_distribution.py @@ -1,3 +1,4 @@ +from math import pi import unittest import numpy as np @@ -7,12 +8,12 @@ class TestAbstractHypertoroidalDistribution(unittest.TestCase): def test_angular_error(self): np.testing.assert_allclose( - AbstractHypertoroidalDistribution.angular_error(np.pi, 0), np.pi + AbstractHypertoroidalDistribution.angular_error(pi, 0), pi ) np.testing.assert_allclose( - AbstractHypertoroidalDistribution.angular_error(0, 2 * np.pi), 0 + AbstractHypertoroidalDistribution.angular_error(0, 2 * pi), 0 ) np.testing.assert_allclose( - AbstractHypertoroidalDistribution.angular_error(np.pi / 4, 7 * np.pi / 4), - np.pi / 2, + AbstractHypertoroidalDistribution.angular_error(pi / 4, 7 * pi / 4), + pi / 2, ) \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_circular_fourier_distribution.py b/pyrecest/tests/distributions/test_circular_fourier_distribution.py index db39b61a..1e3fcf85 100644 --- a/pyrecest/tests/distributions/test_circular_fourier_distribution.py +++ b/pyrecest/tests/distributions/test_circular_fourier_distribution.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import sqrt from pyrecest.backend import linspace from pyrecest.backend import ceil @@ -57,7 +58,7 @@ def test_fourier_conversion( """ for param in param_range: dist = dist_class(mu, param) - xvals = arange(-2 * np.pi, 3 * np.pi, 0.01) + xvals = arange(-2 * pi, 3 * pi, 0.01) fd = CircularFourierDistribution.from_distribution( dist, coeffs, transformation ) @@ -80,7 +81,7 @@ def test_fourier_conversion( ] ) def test_vm_to_fourier(self, mult_by_n, transformation): - xs = linspace(0, 2 * np.pi, 100) + xs = linspace(0, 2 * pi, 100) dist = VonMisesDistribution(2.5, 1.5) fd = CircularFourierDistribution.from_distribution( dist, @@ -195,7 +196,7 @@ def test_distance(self, mult_by_n): ) ** 2, 0, - 2 * np.pi, + 2 * pi, ) fd_diff = fd1 - fd2 np.testing.assert_array_almost_equal(fd_diff.integrate(), hel_like_distance) diff --git a/pyrecest/tests/distributions/test_circular_uniform_distribution.py b/pyrecest/tests/distributions/test_circular_uniform_distribution.py index 3ff665ed..09b80237 100644 --- a/pyrecest/tests/distributions/test_circular_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_circular_uniform_distribution.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import ones from pyrecest.backend import array import unittest @@ -14,13 +15,13 @@ def test_pdf(self): x = array([1, 2, 3, 4, 5, 6]) # Test pdf - np.testing.assert_allclose(cu.pdf(x), 1 / (2 * np.pi) * ones(x.shape)) + np.testing.assert_allclose(cu.pdf(x), 1 / (2 * pi) * ones(x.shape)) def test_shift(self): cu = CircularUniformDistribution() cu2 = cu.shift(3) x = array([1, 2, 3, 4, 5, 6]) - np.testing.assert_allclose(cu2.pdf(x), 1 / (2 * np.pi) * ones(x.shape)) + np.testing.assert_allclose(cu2.pdf(x), 1 / (2 * pi) * ones(x.shape)) def test_cdf(self): cu = CircularUniformDistribution() @@ -61,7 +62,7 @@ def test_integral_with_range(self): cu.integrate([-4, 11]), cu.integrate_numerically([-4, 11]) ) np.testing.assert_allclose( - cu.integrate([2 * np.pi, -1]), cu.integrate_numerically([2 * np.pi, -1]) + cu.integrate([2 * pi, -1]), cu.integrate_numerically([2 * pi, -1]) ) def test_mean(self): diff --git a/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py b/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py index 512040b5..60a1f050 100644 --- a/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py +++ b/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import random from pyrecest.backend import linspace from pyrecest.backend import eye @@ -48,7 +49,7 @@ def test_from_distribution(self): def test_condition_on_linear(self): dist = self.chcd_vm_gauss_stacked.condition_on_linear([2, 1]) - x = linspace(0, 2 * np.pi, 100) + x = linspace(0, 2 * pi, 100) np.testing.assert_allclose(dist.pdf(x), self.vm.pdf(x)) def test_condition_on_periodic(self): diff --git a/pyrecest/tests/distributions/test_custom_linear_distribution.py b/pyrecest/tests/distributions/test_custom_linear_distribution.py index 8300a9b4..856a5369 100644 --- a/pyrecest/tests/distributions/test_custom_linear_distribution.py +++ b/pyrecest/tests/distributions/test_custom_linear_distribution.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import meshgrid from pyrecest.backend import linspace from pyrecest.backend import eye @@ -30,7 +31,7 @@ def test_normalize(self): @staticmethod def verify_pdf_equal(dist1, dist2, tol): - x, y = meshgrid(linspace(0, 2 * np.pi, 10), linspace(0, 2 * np.pi, 10)) + x, y = meshgrid(linspace(0, 2 * pi, 10), linspace(0, 2 * pi, 10)) np.testing.assert_allclose( dist1.pdf(np.column_stack((x.ravel(), y.ravel()))), dist2.pdf(np.column_stack((x.ravel(), y.ravel()))), diff --git a/pyrecest/tests/distributions/test_disk_uniform_distribution.py b/pyrecest/tests/distributions/test_disk_uniform_distribution.py index b923701a..99ec71b8 100644 --- a/pyrecest/tests/distributions/test_disk_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_disk_uniform_distribution.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import sqrt from pyrecest.backend import ones from pyrecest.backend import concatenate @@ -27,7 +28,7 @@ def test_pdf(self): np.testing.assert_allclose( pdf_values, 1 - / np.pi + / pi * concatenate( ( ones(4), diff --git a/pyrecest/tests/distributions/test_hemispherical_uniform_distribution.py b/pyrecest/tests/distributions/test_hemispherical_uniform_distribution.py index 5823360b..55b7d1f9 100644 --- a/pyrecest/tests/distributions/test_hemispherical_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_hemispherical_uniform_distribution.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import ones from pyrecest.backend import allclose from pyrecest.backend import all @@ -23,7 +24,7 @@ def test_pdf_2d(self): # jscpd:ignore-start self.assertTrue( allclose( - hhud.pdf(points), ones(points.shape[0]) / (2 * np.pi), atol=1e-6 + hhud.pdf(points), ones(points.shape[0]) / (2 * pi), atol=1e-6 ) ) # jscpd:ignore-end \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py b/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py index 9caa9628..8666ada7 100644 --- a/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import random from pyrecest.backend import sum from pyrecest.backend import ones_like @@ -97,7 +98,7 @@ def test_sampling(self): assert s.shape == (n, 3) s = s[:, 0] self.assertTrue(all(s >= zeros_like(s))) - self.assertTrue(all(s < 2 * np.pi * ones_like(s))) + self.assertTrue(all(s < 2 * pi * ones_like(s))) def test_from_distribution(self): random_gen = random.default_rng(0) # Could fail randomly otherwise diff --git a/pyrecest/tests/distributions/test_hyperhemispherical_uniform_distribution.py b/pyrecest/tests/distributions/test_hyperhemispherical_uniform_distribution.py index 98d2340f..72339209 100644 --- a/pyrecest/tests/distributions/test_hyperhemispherical_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_hyperhemispherical_uniform_distribution.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import random from pyrecest.backend import reshape from pyrecest.backend import ones @@ -28,7 +29,7 @@ def test_pdf_2d(self): self.assertTrue( allclose( - hhud.pdf(points), ones(points.shape[0]) / (2 * np.pi), atol=1e-6 + hhud.pdf(points), ones(points.shape[0]) / (2 * pi), atol=1e-6 ) ) @@ -39,7 +40,7 @@ def test_pdf_3d(self): # jscpd:ignore-start self.assertTrue( allclose( - hhud.pdf(points), ones(points.shape[0]) / (np.pi**2), atol=1e-6 + hhud.pdf(points), ones(points.shape[0]) / (pi**2), atol=1e-6 ) ) # jscpd:ignore-end diff --git a/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py b/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py index b7faa11d..c82c266b 100644 --- a/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import random from pyrecest.backend import sum from pyrecest.backend import sqrt @@ -29,7 +30,7 @@ def test_sampling(self): nSamples = 5 s = self.hdd.sample(nSamples) self.assertEqual(s.shape, (nSamples, self.d.shape[-1])) - np.testing.assert_array_almost_equal(s, mod(s, 2 * np.pi)) + np.testing.assert_array_almost_equal(s, mod(s, 2 * pi)) np.testing.assert_array_almost_equal( np.linalg.norm(s, axis=-1), ones(nSamples) ) diff --git a/pyrecest/tests/distributions/test_hyperspherical_mixture.py b/pyrecest/tests/distributions/test_hyperspherical_mixture.py index 29524c5e..061efc6e 100644 --- a/pyrecest/tests/distributions/test_hyperspherical_mixture.py +++ b/pyrecest/tests/distributions/test_hyperspherical_mixture.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import sum from pyrecest.backend import stack from pyrecest.backend import sqrt @@ -24,7 +25,7 @@ def test_pdf_3d(self): smix = HypersphericalMixture([wad, vmf], w) phi, theta = meshgrid( - linspace(0, 2 * np.pi, 10), linspace(-np.pi / 2, np.pi / 2, 10) + linspace(0, 2 * pi, 10), linspace(-pi / 2, pi / 2, 10) ) points = AbstractHypersphereSubsetDistribution.polar_to_cart( stack([phi.ravel(), theta.ravel()], axis=-1) diff --git a/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py b/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py index c229727d..e63549cd 100644 --- a/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import random from pyrecest.backend import sum from pyrecest.backend import squeeze @@ -47,7 +48,7 @@ def test_sample(self): n_samples = 5 s = self.twd.sample(n_samples) self.assertEqual(s.shape, (n_samples, self.d.shape[-1])) - np.testing.assert_array_almost_equal(s, mod(s, 2 * np.pi)) + np.testing.assert_array_almost_equal(s, mod(s, 2 * pi)) def test_marginalize_to_1D(self): for i in range(self.d.shape[-1]): @@ -60,7 +61,7 @@ def test_apply_function(self): np.testing.assert_array_almost_equal( same.trigonometric_moment(1), self.twd.trigonometric_moment(1) ) - shift_offset = array([1.4, -0.3, np.pi]) + shift_offset = array([1.4, -0.3, pi]) shifted = self.twd.apply_function(lambda x: x + shift_offset) np.testing.assert_almost_equal( shifted.trigonometric_moment(1)[0], @@ -92,7 +93,7 @@ def test_shift(self): np.testing.assert_array_almost_equal(twd.w, twd_shifted.w) np.testing.assert_array_almost_equal( twd.d, - mod(twd_shifted.d - outer(ones_like(w), s), 2 * np.pi), + mod(twd_shifted.d - outer(ones_like(w), s), 2 * pi), decimal=10, ) @@ -100,7 +101,7 @@ def test_shift(self): def get_pseudorandom_hypertoroidal_wd(dim=2): random.seed(0) n = 20 - d = 2 * np.pi * random.rand(n, dim) + d = 2 * pi * random.rand(n, dim) w = random.rand(n) w = w / sum(w) hwd = HypertoroidalDiracDistribution(d, w) diff --git a/pyrecest/tests/distributions/test_sphere_subset_distribution.py b/pyrecest/tests/distributions/test_sphere_subset_distribution.py index 9c96bf88..44a0e8c6 100644 --- a/pyrecest/tests/distributions/test_sphere_subset_distribution.py +++ b/pyrecest/tests/distributions/test_sphere_subset_distribution.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import array import unittest @@ -44,8 +45,8 @@ def test_sph_to_cart_to_sph(self, mode): # Create some spherical coordinates. Do *not* use 0 as theta because # the transformation from spherical to Cartesian coordinates is not # uniquely invertible in this case. - azimuth = array([0.0, np.pi / 4, np.pi / 2]) - theta = array([np.pi / 2, np.pi / 4, 0.1]) + azimuth = array([0.0, pi / 4, pi / 2]) + theta = array([pi / 2, pi / 4, 0.1]) # Convert to Cartesian coordinates and back x, y, z = AbstractSphereSubsetDistribution.sph_to_cart( diff --git a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py index 8a01b074..c72221d4 100644 --- a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py +++ b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import random from pyrecest.backend import sqrt from pyrecest.backend import sin @@ -63,8 +64,8 @@ def test_normalization(self): # Enforce unnormalized coefficients and compare ratio phi, theta = ( - random.rand(1, 10) * 2 * np.pi, - random.rand(1, 10) * np.pi - np.pi / 2, + random.rand(1, 10) * 2 * pi, + random.rand(1, 10) * pi - pi / 2, ) x, y, z = array( [cos(theta) * cos(phi), cos(theta) * sin(phi), sin(theta)] @@ -136,7 +137,7 @@ def test_truncation(self): shd5 = shd3.truncate(3) self.assertEqual(shd5.coeff_mat.shape, (4, 7)) - phi, theta = random.rand(10) * 2 * np.pi, random.rand(10) * np.pi + phi, theta = random.rand(10) * 2 * pi, random.rand(10) * pi x, y, z = AbstractSphericalDistribution.sph_to_cart(phi, theta) self.assertTrue( allclose( @@ -179,7 +180,7 @@ def test_truncation(self): [0, 0, 0, 0, 0], ] ), - lambda _, _1, z: ones_like(z) * sqrt(1 / (4 * np.pi)), + lambda _, _1, z: ones_like(z) * sqrt(1 / (4 * pi)), ), ( "testl1m0", @@ -190,7 +191,7 @@ def test_truncation(self): [0, 0, 0, 0, 0], ] ), - lambda _, _1, z: sqrt(3 / (4 * np.pi)) * z, + lambda _, _1, z: sqrt(3 / (4 * pi)) * z, ), ( "testl2m0", @@ -203,7 +204,7 @@ def test_truncation(self): ), lambda x, y, z: 1 / 4 - * sqrt(5 / np.pi) + * sqrt(5 / pi) * (2 * z**2 - x**2 - y**2), ), ( @@ -218,7 +219,7 @@ def test_truncation(self): ), lambda x, y, z: 1 / 4 - * sqrt(7 / np.pi) + * sqrt(7 / pi) * (z * (2 * z**2 - 3 * x**2 - 3 * y**2)), ), # For the other basis functions, complex values would be obtained. @@ -233,7 +234,7 @@ def test_truncation(self): [0, 0, 0, 0, 0], ] ), - lambda _, y, _1: sqrt(3 / (4 * np.pi)) * y, + lambda _, y, _1: sqrt(3 / (4 * pi)) * y, ), ( "test_l1m1real", @@ -244,7 +245,7 @@ def test_truncation(self): [0, 0, 0, 0, 0], ] ), - lambda x, _, _1: sqrt(3 / (4 * np.pi)) * x, + lambda x, _, _1: sqrt(3 / (4 * pi)) * x, ), ( "test_l2mneg2real", @@ -255,7 +256,7 @@ def test_truncation(self): [1j * sqrt(1 / 2), 0, 0, 0, -1j * sqrt(1 / 2)], ] ), - lambda x, y, _: 1 / 2 * sqrt(15 / np.pi) * x * y, + lambda x, y, _: 1 / 2 * sqrt(15 / pi) * x * y, ), ( "test_l2mneg1real", @@ -266,7 +267,7 @@ def test_truncation(self): [0, 1j * sqrt(1 / 2), 0, 1j * sqrt(1 / 2), 0], ] ), - lambda _, y, z: 1 / 2 * sqrt(15 / np.pi) * y * z, + lambda _, y, z: 1 / 2 * sqrt(15 / pi) * y * z, ), ( "test_l2m1real", @@ -277,7 +278,7 @@ def test_truncation(self): [0, sqrt(1 / 2), 0, -sqrt(1 / 2), 0], ] ), - lambda x, _, z: 1 / 2 * sqrt(15 / np.pi) * x * z, + lambda x, _, z: 1 / 2 * sqrt(15 / pi) * x * z, ), ( "test_l2m2real", @@ -288,7 +289,7 @@ def test_truncation(self): [sqrt(1 / 2), 0, 0, 0, sqrt(1 / 2)], ] ), - lambda x, y, _: 1 / 4 * sqrt(15 / np.pi) * (x**2 - y**2), + lambda x, y, _: 1 / 4 * sqrt(15 / pi) * (x**2 - y**2), ), ( "test_l3mneg3real", @@ -302,7 +303,7 @@ def test_truncation(self): ), lambda x, y, z: 1 / 4 - * sqrt(35 / (2 * np.pi)) + * sqrt(35 / (2 * pi)) * y * (3 * x**2 - y**2), ), @@ -316,7 +317,7 @@ def test_truncation(self): [0, 1j / sqrt(2), 0, 0, 0, -1j / sqrt(2), 0], ] ), - lambda x, y, z: 1 / 2 * sqrt(105 / np.pi) * x * y * z, + lambda x, y, z: 1 / 2 * sqrt(105 / pi) * x * y * z, ), ( "test_l3mneg1real", @@ -330,7 +331,7 @@ def test_truncation(self): ), lambda x, y, z: 1 / 4 - * sqrt(21 / (2 * np.pi)) + * sqrt(21 / (2 * pi)) * y * (4 * z**2 - x**2 - y**2), ), @@ -346,7 +347,7 @@ def test_truncation(self): ), lambda x, y, z: 1 / 4 - * sqrt(21 / (2 * np.pi)) + * sqrt(21 / (2 * pi)) * x * (4 * z**2 - x**2 - y**2), ), @@ -360,7 +361,7 @@ def test_truncation(self): [0, 1 / sqrt(2), 0, 0, 0, 1 / sqrt(2), 0], ] ), - lambda x, y, z: 1 / 4 * sqrt(105 / np.pi) * z * (x**2 - y**2), + lambda x, y, z: 1 / 4 * sqrt(105 / pi) * z * (x**2 - y**2), ), ( "test_l3m3real", @@ -374,17 +375,17 @@ def test_truncation(self): ), lambda x, y, z: 1 / 4 - * sqrt(35 / (2 * np.pi)) + * sqrt(35 / (2 * pi)) * x * (x**2 - 3 * y**2), ), ] ) def test_basis_function(self, _, coeff_mat, expected_func): - shd = SphericalHarmonicsDistributionComplex(1 / sqrt(4 * np.pi)) + shd = SphericalHarmonicsDistributionComplex(1 / sqrt(4 * pi)) shd.coeff_mat = coeff_mat phi, theta = meshgrid( - linspace(0, 2 * np.pi, 10), linspace(0, np.pi, 10) + linspace(0, 2 * pi, 10), linspace(0, pi, 10) ) x, y, z = AbstractSphericalDistribution.sph_to_cart(phi.ravel(), theta.ravel()) np.testing.assert_allclose( @@ -403,7 +404,7 @@ def test_basis_function(self, _, coeff_mat, expected_func): [0, 0, 0, 0, 0], ] ), - lambda x, y, _: 0.5 * sqrt(3 / (2 * np.pi)) * (x - 1j * y), + lambda x, y, _: 0.5 * sqrt(3 / (2 * pi)) * (x - 1j * y), ), ( "testl1m1_cart", @@ -414,7 +415,7 @@ def test_basis_function(self, _, coeff_mat, expected_func): [0, 0, 0, 0, 0], ] ), - lambda x, y, _: -0.5 * sqrt(3 / (2 * np.pi)) * (x + 1j * y), + lambda x, y, _: -0.5 * sqrt(3 / (2 * pi)) * (x + 1j * y), ), ( "testl2mneg2_cart", @@ -425,7 +426,7 @@ def test_basis_function(self, _, coeff_mat, expected_func): [1, 0, 0, 0, 0], ] ), - lambda x, y, _: 0.25 * sqrt(15 / (2 * np.pi)) * (x - 1j * y) ** 2, + lambda x, y, _: 0.25 * sqrt(15 / (2 * pi)) * (x - 1j * y) ** 2, ), ( "testl2mneg1_cart", @@ -436,7 +437,7 @@ def test_basis_function(self, _, coeff_mat, expected_func): [0, 1, 0, 0, 0], ] ), - lambda x, y, z: 0.5 * sqrt(15 / (2 * np.pi)) * (x - 1j * y) * z, + lambda x, y, z: 0.5 * sqrt(15 / (2 * pi)) * (x - 1j * y) * z, ), ( "testl2m1_cart", @@ -447,7 +448,7 @@ def test_basis_function(self, _, coeff_mat, expected_func): [0, 0, 0, 1, 0], ] ), - lambda x, y, z: -0.5 * sqrt(15 / (2 * np.pi)) * (x + 1j * y) * z, + lambda x, y, z: -0.5 * sqrt(15 / (2 * pi)) * (x + 1j * y) * z, ), ( "testl2m2_cart", @@ -458,7 +459,7 @@ def test_basis_function(self, _, coeff_mat, expected_func): [0, 0, 0, 0, 1], ] ), - lambda x, y, _: 0.25 * sqrt(15 / (2 * np.pi)) * (x + 1j * y) ** 2, + lambda x, y, _: 0.25 * sqrt(15 / (2 * pi)) * (x + 1j * y) ** 2, ), # For spherical coordinates ( @@ -471,7 +472,7 @@ def test_basis_function(self, _, coeff_mat, expected_func): ] ), lambda phi, theta: 0.5 - * sqrt(3 / (2 * np.pi)) + * sqrt(3 / (2 * pi)) * sin(theta) * exp(-1j * phi), ), @@ -485,7 +486,7 @@ def test_basis_function(self, _, coeff_mat, expected_func): ] ), lambda phi, theta: -0.5 - * sqrt(3 / (2 * np.pi)) + * sqrt(3 / (2 * pi)) * sin(theta) * exp(1j * phi), ), @@ -499,7 +500,7 @@ def test_basis_function(self, _, coeff_mat, expected_func): ] ), lambda phi, theta: 0.25 - * sqrt(15 / (2 * np.pi)) + * sqrt(15 / (2 * pi)) * sin(theta) ** 2 * exp(-2j * phi), ), @@ -513,7 +514,7 @@ def test_basis_function(self, _, coeff_mat, expected_func): ] ), lambda phi, theta: 0.5 - * sqrt(15 / (2 * np.pi)) + * sqrt(15 / (2 * pi)) * sin(theta) * cos(theta) * exp(-1j * phi), @@ -528,7 +529,7 @@ def test_basis_function(self, _, coeff_mat, expected_func): ] ), lambda phi, theta: -0.5 - * sqrt(15 / (2 * np.pi)) + * sqrt(15 / (2 * pi)) * sin(theta) * cos(theta) * exp(1j * phi), @@ -543,7 +544,7 @@ def test_basis_function(self, _, coeff_mat, expected_func): ] ), lambda phi, theta: 0.25 - * sqrt(15 / (2 * np.pi)) + * sqrt(15 / (2 * pi)) * sin(theta) ** 2 * exp(2j * phi), ), @@ -557,7 +558,7 @@ def test_basis_function(self, _, coeff_mat, expected_func): ] ), lambda phi, theta: 0.5 - * sqrt(3 / (2 * np.pi)) + * sqrt(3 / (2 * pi)) * sin(theta) * exp(-1j * phi), ), @@ -571,7 +572,7 @@ def test_basis_function(self, _, coeff_mat, expected_func): ] ), lambda phi, theta: -0.5 - * sqrt(3 / (2 * np.pi)) + * sqrt(3 / (2 * pi)) * sin(theta) * exp(1j * phi), ), @@ -585,7 +586,7 @@ def test_basis_function(self, _, coeff_mat, expected_func): ] ), lambda phi, theta: 0.25 - * sqrt(15 / (2 * np.pi)) + * sqrt(15 / (2 * pi)) * sin(theta) ** 2 * exp(-2j * phi), ), @@ -599,7 +600,7 @@ def test_basis_function(self, _, coeff_mat, expected_func): ] ), lambda phi, theta: 0.5 - * sqrt(15 / (2 * np.pi)) + * sqrt(15 / (2 * pi)) * sin(theta) * cos(theta) * exp(-1j * phi), @@ -614,7 +615,7 @@ def test_basis_function(self, _, coeff_mat, expected_func): ] ), lambda phi, theta: -0.5 - * sqrt(15 / (2 * np.pi)) + * sqrt(15 / (2 * pi)) * sin(theta) * cos(theta) * exp(1j * phi), @@ -629,7 +630,7 @@ def test_basis_function(self, _, coeff_mat, expected_func): ] ), lambda phi, theta: 0.25 - * sqrt(15 / (2 * np.pi)) + * sqrt(15 / (2 * pi)) * sin(theta) ** 2 * exp(2j * phi), ), @@ -637,11 +638,11 @@ def test_basis_function(self, _, coeff_mat, expected_func): ) def test_basis_function_complex(self, name, coeff_mat, expected_func): shd = SphericalHarmonicsDistributionComplex( - 1 / sqrt(4 * np.pi), assert_real=False + 1 / sqrt(4 * pi), assert_real=False ) shd.coeff_mat = coeff_mat phi, theta = meshgrid( - linspace(0, 2 * np.pi, 10), linspace(-np.pi / 2, np.pi / 2, 10) + linspace(0, 2 * pi, 10), linspace(-pi / 2, pi / 2, 10) ) x, y, z = AbstractSphericalDistribution.sph_to_cart(phi.ravel(), theta.ravel()) @@ -833,7 +834,7 @@ def test_conversion(self, _, coeff_mat): shd = SphericalHarmonicsDistributionComplex(coeff_mat) rshd = shd.to_spherical_harmonics_distribution_real() phi, theta = meshgrid( - linspace(0, 2 * np.pi, 10), linspace(-np.pi / 2, np.pi / 2, 10) + linspace(0, 2 * pi, 10), linspace(-pi / 2, pi / 2, 10) ) x, y, z = AbstractSphericalDistribution.sph_to_cart(phi.ravel(), theta.ravel()) np.testing.assert_allclose( @@ -926,7 +927,7 @@ def test_from_distribution_via_integral_vmf(self): dist, 3 ) phi, theta = meshgrid( - linspace(0, 2 * np.pi, 10), linspace(-np.pi / 2, np.pi / 2, 10) + linspace(0, 2 * pi, 10), linspace(-pi / 2, pi / 2, 10) ) x, y, z = AbstractSphericalDistribution.sph_to_cart(phi.ravel(), theta.ravel()) np.testing.assert_allclose( @@ -948,7 +949,7 @@ def test_from_distribution_via_integral_uniform(self): shd = SphericalHarmonicsDistributionComplex.from_distribution_via_integral( HypersphericalUniformDistribution(2), degree=0 ) - np.testing.assert_allclose(shd.coeff_mat, array([[1 / sqrt(4 * np.pi)]])) + np.testing.assert_allclose(shd.coeff_mat, array([[1 / sqrt(4 * pi)]])) def test_transformation_via_integral_shd(self): # Test approximating a spherical harmonic distribution @@ -977,16 +978,16 @@ def test_convergence(self): @parameterized.expand( [ - ("zplus", [[1 / sqrt(4 * np.pi), np.nan, np.nan], [0, 1, 0]], [0, 0, 1]), + ("zplus", [[1 / sqrt(4 * pi), np.nan, np.nan], [0, 1, 0]], [0, 0, 1]), ( "zminus", - [[1 / sqrt(4 * np.pi), np.nan, np.nan], [0, -1, 0]], + [[1 / sqrt(4 * pi), np.nan, np.nan], [0, -1, 0]], [0, 0, -1], ), ( "yplus", [ - [1 / sqrt(4 * np.pi), np.nan, np.nan], + [1 / sqrt(4 * pi), np.nan, np.nan], [1j * sqrt(1 / 2), 0, 1j * sqrt(1 / 2)], ], [0, 1, 0], @@ -994,7 +995,7 @@ def test_convergence(self): ( "yminus", [ - [1 / sqrt(4 * np.pi), np.nan, np.nan], + [1 / sqrt(4 * pi), np.nan, np.nan], [-1j * sqrt(1 / 2), 0, -1j * sqrt(1 / 2)], ], [0, -1, 0], @@ -1002,7 +1003,7 @@ def test_convergence(self): ( "xplus", [ - [1 / sqrt(4 * np.pi), np.nan, np.nan], + [1 / sqrt(4 * pi), np.nan, np.nan], [sqrt(1 / 2), 0, -sqrt(1 / 2)], ], [1, 0, 0], @@ -1010,7 +1011,7 @@ def test_convergence(self): ( "xminus", [ - [1 / sqrt(4 * np.pi), np.nan, np.nan], + [1 / sqrt(4 * pi), np.nan, np.nan], [-sqrt(1 / 2), 0, sqrt(1 / 2)], ], [-1, 0, 0], @@ -1018,7 +1019,7 @@ def test_convergence(self): ( "xyplus", [ - [1 / sqrt(4 * np.pi), np.nan, np.nan], + [1 / sqrt(4 * pi), np.nan, np.nan], [ 1j * sqrt(1 / 2) + sqrt(1 / 2), 1, @@ -1030,7 +1031,7 @@ def test_convergence(self): ( "xyminus", [ - [1 / sqrt(4 * np.pi), np.nan, np.nan], + [1 / sqrt(4 * pi), np.nan, np.nan], [ -1j * sqrt(1 / 2) - sqrt(1 / 2), 0, diff --git a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py index 525bf41f..4e1fb9ed 100644 --- a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py +++ b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import random from pyrecest.backend import sqrt from pyrecest.backend import ones_like @@ -55,7 +56,7 @@ def testNormalization(self): [0, 0, 0, np.nan, np.nan], [0, 0, 0, 0, 0], ], - lambda x, _, __: ones_like(x) * sqrt(1 / (4 * np.pi)), + lambda x, _, __: ones_like(x) * sqrt(1 / (4 * pi)), ), ( "l1mneg1", @@ -64,7 +65,7 @@ def testNormalization(self): [1, 0, 0, np.nan, np.nan], [0, 0, 0, 0, 0], ], - lambda _, y, __: sqrt(3 / (4 * np.pi)) * y, + lambda _, y, __: sqrt(3 / (4 * pi)) * y, ), ( "l1_m0", @@ -73,7 +74,7 @@ def testNormalization(self): [0, 1, 0, np.nan, np.nan], [0, 0, 0, 0, 0], ], - lambda _, __, z: sqrt(3 / (4 * np.pi)) * z, + lambda _, __, z: sqrt(3 / (4 * pi)) * z, ), ( "l1_m1", @@ -82,7 +83,7 @@ def testNormalization(self): [0, 0, 1, np.nan, np.nan], [0, 0, 0, 0, 0], ], - lambda x, _, __: sqrt(3 / (4 * np.pi)) * x, + lambda x, _, __: sqrt(3 / (4 * pi)) * x, ), ( "l2_mneg2", @@ -91,7 +92,7 @@ def testNormalization(self): [0, 0, 0, np.nan, np.nan], [1, 0, 0, 0, 0], ], - lambda x, y, __: 1 / 2 * sqrt(15 / np.pi) * x * y, + lambda x, y, __: 1 / 2 * sqrt(15 / pi) * x * y, ), ( "l2_mneg1", @@ -100,7 +101,7 @@ def testNormalization(self): [0, 0, 0, np.nan, np.nan], [0, 1, 0, 0, 0], ], - lambda _, y, z: 1 / 2 * sqrt(15 / np.pi) * y * z, + lambda _, y, z: 1 / 2 * sqrt(15 / pi) * y * z, ), ( "l2_m0", @@ -111,7 +112,7 @@ def testNormalization(self): ], lambda x, y, z: 1 / 4 - * sqrt(5 / np.pi) + * sqrt(5 / pi) * (2 * z**2 - x**2 - y**2), ), ( @@ -121,7 +122,7 @@ def testNormalization(self): [0, 0, 0, np.nan, np.nan], [0, 0, 0, 1, 0], ], - lambda x, _, z: 1 / 2 * sqrt(15 / np.pi) * x * z, + lambda x, _, z: 1 / 2 * sqrt(15 / pi) * x * z, ), ( "l2_m2", @@ -130,13 +131,13 @@ def testNormalization(self): [0, 0, 0, np.nan, np.nan], [0, 0, 0, 0, 1], ], - lambda x, y, _: 1 / 4 * sqrt(15 / np.pi) * (x**2 - y**2), + lambda x, y, _: 1 / 4 * sqrt(15 / pi) * (x**2 - y**2), ), ] # jscpd:ignore-end ) def test_basis_function(self, name, coeff_mat, result_func): random.seed(10) - shd = SphericalHarmonicsDistributionReal(1 / sqrt(4 * np.pi)) + shd = SphericalHarmonicsDistributionReal(1 / sqrt(4 * pi)) shd.coeff_mat = array(coeff_mat) x, y, z = SphericalHarmonicsDistributionRealTest._gen_naive_grid(10) np.testing.assert_allclose( @@ -148,8 +149,8 @@ def test_basis_function(self, name, coeff_mat, result_func): @staticmethod def _gen_naive_grid(n_per_dim): - phi = random.rand(n_per_dim) * 2 * np.pi - theta = random.rand(n_per_dim) * np.pi - np.pi / 2 + phi = random.rand(n_per_dim) * 2 * pi + theta = random.rand(n_per_dim) * pi - pi / 2 return AbstractSphericalDistribution.sph_to_cart(phi, theta) @parameterized.expand( @@ -328,8 +329,8 @@ def test_conversion(self, _, coeff_mat): rshd = SphericalHarmonicsDistributionReal(coeff_mat) cshd = rshd.to_spherical_harmonics_distribution_complex() phi_to_test, theta_to_test = ( - random.rand(10) * 2 * np.pi, - random.rand(10) * np.pi - np.pi / 2, + random.rand(10) * 2 * pi, + random.rand(10) * pi - pi / 2, ) x, y, z = AbstractSphericalDistribution.sph_to_cart(phi_to_test, theta_to_test) np.testing.assert_allclose( diff --git a/pyrecest/tests/distributions/test_toroidal_uniform_distribution.py b/pyrecest/tests/distributions/test_toroidal_uniform_distribution.py index ac9e7ea0..5dd369a7 100644 --- a/pyrecest/tests/distributions/test_toroidal_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_toroidal_uniform_distribution.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import tile from pyrecest.backend import ones from pyrecest.backend import array @@ -20,7 +21,7 @@ def setUp(self): def test_pdf(self): self.assertTrue( allclose( - self.tud.pdf(self.x), (1 / (2 * np.pi) ** 2) * ones(self.x.shape[1]) + self.tud.pdf(self.x), (1 / (2 * pi) ** 2) * ones(self.x.shape[1]) ) ) @@ -29,7 +30,7 @@ def test_shift(self): self.assertTrue( allclose( tud_shifted.pdf(self.x), - (1 / (2 * np.pi) ** 2) * ones(self.x.shape[1]), + (1 / (2 * pi) ** 2) * ones(self.x.shape[1]), ) ) @@ -74,7 +75,7 @@ def test_sampling(self): s = self.tud.sample(n) self.assertEqual(s.shape, (n, 2)) self.assertTrue(all(s >= 0)) - self.assertTrue(all(s < 2 * np.pi)) + self.assertTrue(all(s < 2 * pi)) if __name__ == "__main__": diff --git a/pyrecest/tests/distributions/test_toroidal_von_mises_sine_distribution.py b/pyrecest/tests/distributions/test_toroidal_von_mises_sine_distribution.py index a2ef2f33..85aabc20 100644 --- a/pyrecest/tests/distributions/test_toroidal_von_mises_sine_distribution.py +++ b/pyrecest/tests/distributions/test_toroidal_von_mises_sine_distribution.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import sin from pyrecest.backend import exp from pyrecest.backend import cos @@ -59,7 +60,7 @@ def _unnormalized_pdf(self, xs): (array([[5, 1], [6, 3]]),), ( np.column_stack( - (arange(0, 2 * np.pi, 0.1), arange(1 * np.pi, 3 * np.pi, 0.1)) + (arange(0, 2 * pi, 0.1), arange(1 * pi, 3 * pi, 0.1)) ), ), ] diff --git a/pyrecest/tests/distributions/test_toroidal_wrapped_normal_distribution.py b/pyrecest/tests/distributions/test_toroidal_wrapped_normal_distribution.py index 66bb23ec..4cc20f14 100644 --- a/pyrecest/tests/distributions/test_toroidal_wrapped_normal_distribution.py +++ b/pyrecest/tests/distributions/test_toroidal_wrapped_normal_distribution.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import mod from pyrecest.backend import array from pyrecest.backend import allclose @@ -31,7 +32,7 @@ def test_sampling(self): n_samples = 5 s = self.twn.sample(n_samples) self.assertEqual(s.shape, (n_samples, 2)) - self.assertTrue(allclose(s, mod(s, 2 * np.pi))) + self.assertTrue(allclose(s, mod(s, 2 * pi))) if __name__ == "__main__": diff --git a/pyrecest/tests/distributions/test_wrapped_cauchy_distribution.py b/pyrecest/tests/distributions/test_wrapped_cauchy_distribution.py index ca6bb41b..ef815ffa 100644 --- a/pyrecest/tests/distributions/test_wrapped_cauchy_distribution.py +++ b/pyrecest/tests/distributions/test_wrapped_cauchy_distribution.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import array from pyrecest.backend import arange import unittest @@ -24,7 +25,7 @@ def pdf_wrapped(x, mu, gamma, terms=2000): summation = 0 for k in range(-terms, terms + 1): summation += gamma / ( - np.pi * (gamma**2 + (x - mu + 2 * np.pi * k) ** 2) + pi * (gamma**2 + (x - mu + 2 * pi * k) ** 2) ) return summation diff --git a/pyrecest/tests/distributions/test_wrapped_laplace_distribution.py b/pyrecest/tests/distributions/test_wrapped_laplace_distribution.py index 55d0287e..4f0f9df4 100644 --- a/pyrecest/tests/distributions/test_wrapped_laplace_distribution.py +++ b/pyrecest/tests/distributions/test_wrapped_laplace_distribution.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import linspace from pyrecest.backend import exp from pyrecest.backend import arange @@ -30,7 +31,7 @@ def laplace(x): ) def pdftemp(x): - return sum(laplace(z) for z in x + 2 * np.pi * arange(-20, 21)) + return sum(laplace(z) for z in x + 2 * pi * arange(-20, 21)) for x in [0, 1, 2, 3, 4]: np.testing.assert_allclose(self.wl.pdf(x), pdftemp(x), rtol=1e-10) @@ -39,7 +40,7 @@ def test_integral(self): np.testing.assert_allclose(self.wl.integrate(), 1, rtol=1e-10) np.testing.assert_allclose(self.wl.integrate_numerically(), 1, rtol=1e-10) np.testing.assert_allclose( - self.wl.integrate([0, np.pi]) + self.wl.integrate([np.pi, 2 * np.pi]), + self.wl.integrate([0, pi]) + self.wl.integrate([pi, 2 * pi]), 1, rtol=1e-10, ) @@ -54,8 +55,8 @@ def test_angular_moments(self): def test_periodicity(self): np.testing.assert_allclose( - self.wl.pdf(linspace(-2 * np.pi, 0, 100)), - self.wl.pdf(linspace(0, 2 * np.pi, 100)), + self.wl.pdf(linspace(-2 * pi, 0, 100)), + self.wl.pdf(linspace(0, 2 * pi, 100)), rtol=1e-10, ) diff --git a/pyrecest/tests/distributions/test_wrapped_normal_distribution.py b/pyrecest/tests/distributions/test_wrapped_normal_distribution.py index b36e4e8c..a076c988 100644 --- a/pyrecest/tests/distributions/test_wrapped_normal_distribution.py +++ b/pyrecest/tests/distributions/test_wrapped_normal_distribution.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import sum from pyrecest.backend import sqrt from pyrecest.backend import ones_like @@ -28,9 +29,9 @@ def test_pdf_values_are_as_expected(self): def approx_with_wrapping(x): k = arange(-20, 21) total = sum( - exp(-((x - self.mu + 2 * np.pi * k) ** 2) / (2 * self.sigma**2)) + exp(-((x - self.mu + 2 * pi * k) ** 2) / (2 * self.sigma**2)) ) - return 1 / sqrt(2 * np.pi) / self.sigma * total + return 1 / sqrt(2 * pi) / self.sigma * total test_points = [self.mu, self.mu - 1, self.mu + 2] for point in test_points: @@ -54,7 +55,7 @@ def test_pdf_with_large_sigma_is_uniform(self): """ wn_large_sigma = WrappedNormalDistribution(0, 100) x = arange(0, 7) - fx = ones_like(x) / (2 * np.pi) + fx = ones_like(x) / (2 * pi) self.assertTrue(allclose(wn_large_sigma.pdf(x), fx, rtol=1e-10)) diff --git a/pyrecest/tests/filters/test_circular_particle_filter.py b/pyrecest/tests/filters/test_circular_particle_filter.py index dbdf9de1..6c7b35e9 100644 --- a/pyrecest/tests/filters/test_circular_particle_filter.py +++ b/pyrecest/tests/filters/test_circular_particle_filter.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import random from pyrecest.backend import array from pyrecest.backend import arange @@ -113,11 +114,11 @@ def test_association_likelihood(self): self.assertAlmostEqual( pf.association_likelihood(CircularUniformDistribution()), - 1 / (2 * np.pi), + 1 / (2 * pi), places=10, ) self.assertGreater( - pf.association_likelihood(VonMisesDistribution(2, 1)), 1 / (2 * np.pi) + pf.association_likelihood(VonMisesDistribution(2, 1)), 1 / (2 * pi) ) self.filter.set_state(CircularDiracDistribution(arange(0, 1.1, 0.1))) diff --git a/pyrecest/tests/filters/test_euclidean_particle_filter.py b/pyrecest/tests/filters/test_euclidean_particle_filter.py index be9903dc..a1b4527d 100644 --- a/pyrecest/tests/filters/test_euclidean_particle_filter.py +++ b/pyrecest/tests/filters/test_euclidean_particle_filter.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import random from pyrecest.backend import ones from pyrecest.backend import mean @@ -54,7 +55,7 @@ def f(x, w): ) def test_predict_update_cycle_3d_forced_particle_pos_no_pred(self): - self.pf.filter_state = self.prior.set_mean(ones(3) + np.pi / 2) + self.pf.filter_state = self.prior.set_mean(ones(3) + pi / 2) force_first_particle_pos = array([1.1, 2, 3]) self.pf.filter_state.d[0, :] = force_first_particle_pos diff --git a/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py b/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py index 9987a70a..c1482f1c 100644 --- a/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py +++ b/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import random from pyrecest.backend import array from pyrecest.backend import zeros @@ -14,7 +15,7 @@ def setUp(self): self.covariance_matrix = array( [[0.7, 0.4, 0.2], [0.4, 0.6, 0.1], [0.2, 0.1, 1]] ) - self.mu = array([1, 1, 1]) + np.pi / 2 + self.mu = array([1, 1, 1]) + pi / 2 self.hwnd = HypertoroidalWNDistribution(self.mu, self.covariance_matrix) self.hpf = HypertoroidalParticleFilter(500, 3) self.forced_mean = array([1, 2, 3]) diff --git a/pyrecest/tests/filters/test_toroidal_particle_filter.py b/pyrecest/tests/filters/test_toroidal_particle_filter.py index 12a785db..d77faddf 100644 --- a/pyrecest/tests/filters/test_toroidal_particle_filter.py +++ b/pyrecest/tests/filters/test_toroidal_particle_filter.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import random from pyrecest.backend import array from pyrecest.backend import allclose @@ -18,7 +19,7 @@ class ToroidalParticleFilterTest(unittest.TestCase): def test_toroidal_particle_filter(self): random.seed(0) C = array([[0.7, 0.4], [0.4, 0.6]]) - mu = array([1, 1]) + np.pi / 2 + mu = array([1, 1]) + pi / 2 hwnd = ToroidalWrappedNormalDistribution(mu, C) tpf = ToroidalParticleFilter(200) tpf.set_state(hwnd) diff --git a/pyrecest/tests/filters/test_toroidal_wrapped_normal_filter.py b/pyrecest/tests/filters/test_toroidal_wrapped_normal_filter.py index 51db8ea3..dc50cfd2 100644 --- a/pyrecest/tests/filters/test_toroidal_wrapped_normal_filter.py +++ b/pyrecest/tests/filters/test_toroidal_wrapped_normal_filter.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import mod from pyrecest.backend import array import unittest @@ -33,6 +34,6 @@ def test_predict_identity(self): dist_result = curr_filter.filter_state self.assertIsInstance(dist_result, ToroidalWrappedNormalDistribution) np.testing.assert_array_almost_equal( - dist_result.mu, mod(self.twn.mu + self.twn.mu, 2 * np.pi) + dist_result.mu, mod(self.twn.mu + self.twn.mu, 2 * pi) ) np.testing.assert_array_almost_equal(dist_result.C, self.twn.C + self.twn.C) \ No newline at end of file diff --git a/pyrecest/tests/test_hypertoroidal_sampler.py b/pyrecest/tests/test_hypertoroidal_sampler.py index 81ffa6d6..c43efe27 100644 --- a/pyrecest/tests/test_hypertoroidal_sampler.py +++ b/pyrecest/tests/test_hypertoroidal_sampler.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import std from pyrecest.backend import all import unittest @@ -19,7 +20,7 @@ def test_sample_stochastic(self): # Check that all samples are within the range [0, 2*pi) self.assertTrue(all(samples >= 0)) - self.assertTrue(all(samples < 2 * np.pi)) + self.assertTrue(all(samples < 2 * pi)) def test_get_grid(self): grid_density_parameter = 100 @@ -30,7 +31,7 @@ def test_get_grid(self): # Check that all grid points are within the range [0, 2*pi) self.assertTrue(all(grid_points >= 0)) - self.assertTrue(all(grid_points < 2 * np.pi)) + self.assertTrue(all(grid_points < 2 * pi)) # Check that the grid points are equidistant diff = np.diff(grid_points) diff --git a/pyrecest/utils/plotting.py b/pyrecest/utils/plotting.py index eda0e697..ef602438 100644 --- a/pyrecest/utils/plotting.py +++ b/pyrecest/utils/plotting.py @@ -1,3 +1,4 @@ +from math import pi from pyrecest.backend import sqrt from pyrecest.backend import sin from pyrecest.backend import reshape @@ -20,7 +21,7 @@ def plot_ellipsoid(center, shape_matrix, scaling_factor=1, color="blue"): def plot_ellipsoid_2d(center, shape_matrix, scaling_factor=1, color="blue"): - xs = linspace(0, 2 * np.pi, 100) + xs = linspace(0, 2 * pi, 100) ps = scaling_factor * shape_matrix @ np.column_stack((cos(xs), sin(xs))) plt.plot(ps[0] + center[0], ps[1] + center[1], color=color) plt.show() @@ -29,8 +30,8 @@ def plot_ellipsoid_2d(center, shape_matrix, scaling_factor=1, color="blue"): def plot_ellipsoid_3d(center, shape_matrix, scaling_factor=1, color="blue"): fig = plt.figure() ax = fig.add_subplot(111, projection="3d") - u = linspace(0, 2 * np.pi, 100) - v = linspace(0, np.pi, 100) + u = linspace(0, 2 * pi, 100) + v = linspace(0, pi, 100) x = outer(cos(u), sin(v)) y = outer(sin(u), sin(v)) z = outer(ones(np.size(u)), cos(v)) From 04abd41b4be2d46e53e1245051114e3f5ab754a4 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 17 Oct 2023 20:18:28 +0100 Subject: [PATCH 014/232] Minor adjustment for backend --- .../hypersphere_subset/abstract_hyperspherical_distribution.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py index 769562bd..055f67c6 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py @@ -163,7 +163,7 @@ def get_full_integration_boundaries(dim): return vstack( ( zeros(dim), - concatenate(([2 * pi], pi * ones(dim - 1))), + concatenate((array([2 * pi]), pi * ones(dim - 1))), ) ).T From 9978b8857a6fdc70ff3e7bcf5a013521fe52a4cb Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 17 Oct 2023 20:20:55 +0100 Subject: [PATCH 015/232] Now using linalg of backend --- .../abstract_ellipsoidal_ball_distribution.py | 3 ++- ...ypersphere_cart_prod_dirac_distribution.py | 3 ++- .../partially_wrapped_normal_distribution.py | 3 ++- .../ellipsoidal_ball_uniform_distribution.py | 9 ++++---- ...bstract_hyperhemispherical_distribution.py | 5 +++-- ...bstract_hypersphere_subset_distribution.py | 7 ++++--- .../bingham_distribution.py | 3 ++- .../hyperspherical_dirac_distribution.py | 3 ++- .../hyperspherical_uniform_distribution.py | 3 ++- ...pherical_harmonics_distribution_complex.py | 5 +++-- .../von_mises_fisher_distribution.py | 9 ++++---- .../hypersphere_subset/watson_distribution.py | 3 ++- ...pertoroidal_wrapped_normal_distribution.py | 3 ++- .../nonperiodic/gaussian_distribution.py | 5 +++-- pyrecest/filters/random_matrix_tracker.py | 13 ++++++------ ...bstract_hyperhemispherical_distribution.py | 3 ++- ...bstract_hypersphere_subset_distribution.py | 7 ++++--- ...st_abstract_hyperspherical_distribution.py | 9 ++++---- .../distributions/test_abstract_mixture.py | 5 +++-- .../test_custom_hemispherical_distribution.py | 3 ++- ...test_custom_hyperspherical_distribution.py | 3 ++- ...hyperhemispherical_uniform_distribution.py | 3 ++- .../test_hyperspherical_dirac_distribution.py | 5 +++-- ...est_hyperspherical_uniform_distribution.py | 5 +++-- .../test_se3_dirac_distribution.py | 3 ++- .../test_von_mises_fisher_distribution.py | 21 ++++++++++--------- .../distributions/test_watson_distribution.py | 9 ++++---- .../filters/test_random_matrix_tracker.py | 5 +++-- pyrecest/tests/test_evaluation_basic.py | 3 ++- pyrecest/tests/test_hyperspherical_sampler.py | 3 ++- pyrecest/utils/metrics.py | 3 ++- pyrecest/utils/plotting.py | 3 ++- 32 files changed, 101 insertions(+), 69 deletions(-) diff --git a/pyrecest/distributions/abstract_ellipsoidal_ball_distribution.py b/pyrecest/distributions/abstract_ellipsoidal_ball_distribution.py index 54fc5910..7ca52330 100644 --- a/pyrecest/distributions/abstract_ellipsoidal_ball_distribution.py +++ b/pyrecest/distributions/abstract_ellipsoidal_ball_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import linalg from math import pi from pyrecest.backend import sqrt import numbers @@ -50,4 +51,4 @@ def get_manifold_size(self) -> np.number | numbers.Real: else: c = (pi ** (self.dim / 2)) / gamma((self.dim / 2) + 1) - return c * sqrt(np.linalg.det(self.shape_matrix)) \ No newline at end of file + return c * sqrt(linalg.det(self.shape_matrix)) \ No newline at end of file diff --git a/pyrecest/distributions/cart_prod/lin_hypersphere_cart_prod_dirac_distribution.py b/pyrecest/distributions/cart_prod/lin_hypersphere_cart_prod_dirac_distribution.py index 48445f65..3b0b9bab 100644 --- a/pyrecest/distributions/cart_prod/lin_hypersphere_cart_prod_dirac_distribution.py +++ b/pyrecest/distributions/cart_prod/lin_hypersphere_cart_prod_dirac_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import linalg from pyrecest.backend import abs import numpy as np @@ -12,7 +13,7 @@ class LinHypersphereCartProdDiracDistribution( ): def __init__(self, bound_dim, d, w=None): assert ( - np.max(abs(np.linalg.norm(d[:, : (bound_dim + 1)], axis=-1) - 1)) < 1e-5 + np.max(abs(linalg.norm(d[:, : (bound_dim + 1)], axis=-1) - 1)) < 1e-5 ), "The hypersphere ssubset part of d must be normalized" AbstractSE3Distribution.__init__(self) LinBoundedCartProdDiracDistribution.__init__(self, d, w) diff --git a/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py b/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py index 27539678..7dac10f8 100644 --- a/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py +++ b/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import linalg from math import pi from pyrecest.backend import random from typing import Union @@ -39,7 +40,7 @@ def __init__( assert ndim(mu) == 1, "mu must be a 1-dimensional array" assert shape(C) == (np.size(mu), np.size(mu)), "C must match size of mu" assert allclose(C, C.T), "C must be symmetric" - assert all(np.linalg.eigvals(C) > 0), "C must be positive definite" + assert all(linalg.eigvals(C) > 0), "C must be positive definite" assert bound_dim <= np.size(mu) assert ndim(mu) == 1 if bound_dim > 0: # This decreases the need for many wrappings diff --git a/pyrecest/distributions/ellipsoidal_ball_uniform_distribution.py b/pyrecest/distributions/ellipsoidal_ball_uniform_distribution.py index 7409c909..ada91911 100644 --- a/pyrecest/distributions/ellipsoidal_ball_uniform_distribution.py +++ b/pyrecest/distributions/ellipsoidal_ball_uniform_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import linalg from math import pi from pyrecest.backend import random from typing import Union @@ -46,7 +47,7 @@ def pdf(self, xs: np.ndarray): """ assert xs.shape[-1] == self.dim # Calculate the reciprocal of the volume of the ellipsoid - # reciprocal_volume = 1 / (power(pi, self.dim / 2) * sqrt(np.linalg.det(self.shape_matrix)) / gamma(self.dim / 2 + 1)) + # reciprocal_volume = 1 / (power(pi, self.dim / 2) * sqrt(linalg.det(self.shape_matrix)) / gamma(self.dim / 2 + 1)) reciprocal_volume = 1 / self.get_manifold_size() if xs.ndim == 1: return reciprocal_volume @@ -58,7 +59,7 @@ def pdf(self, xs: np.ndarray): for i in range(n): point = xs[i, :] diff = point - self.center - result = dot(diff.T, np.linalg.solve(self.shape_matrix, diff)) + result = dot(diff.T, linalg.solve(self.shape_matrix, diff)) # If the point is inside the ellipsoid, store the reciprocal of the volume as the pdf value if result <= 1: @@ -74,7 +75,7 @@ def sample(self, n: Union[int, int32, int64]) -> np.ndarray: :returns: Generated samples. """ random_points = random.randn(n, self.dim) - random_points /= np.linalg.norm(random_points, axis=1, keepdims=True) + random_points /= linalg.norm(random_points, axis=1, keepdims=True) random_radii = random.rand(n, 1) random_radii = random_radii ** ( @@ -85,7 +86,7 @@ def sample(self, n: Union[int, int32, int64]) -> np.ndarray: random_points *= random_radii # Rotate the points according to the shape matrix - L = np.linalg.cholesky(self.shape_matrix) + L = linalg.cholesky(self.shape_matrix) # For points (d, n), this would be L @ random_points transformed_points = random_points @ L.T + self.center.reshape(1, -1) diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py index 47a94b4b..7578af23 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import linalg from math import pi from pyrecest.backend import random from typing import Union @@ -88,12 +89,12 @@ def mean_direction_numerical(self) -> np.ndarray: p = self.pdf(r) mu = r @ p / n * Sd - if np.linalg.norm(mu) < 1e-9: + if linalg.norm(mu) < 1e-9: warnings.warn( "Density may not have actually have a mean direction because integral yields a point very close to the origin." ) - mu = mu / np.linalg.norm(mu) + mu = mu / linalg.norm(mu) return mu @staticmethod diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py index 9f89e508..40da30ce 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import linalg from math import pi from typing import Union from pyrecest.backend import sort @@ -73,12 +74,12 @@ def f(x, i=i): else: raise ValueError("Unsupported") - if np.linalg.norm(mu) < 1e-9: + if linalg.norm(mu) < 1e-9: print( "Warning: Density may not actually have a mean direction because integral yields a point very close to the origin." ) - mu = mu / np.linalg.norm(mu) + mu = mu / linalg.norm(mu) return mu def gen_pdf_hyperspherical_coords(self): @@ -170,7 +171,7 @@ def g_3d(phi1, phi2, phi3): @staticmethod def _compute_mean_axis_from_moment(moment_matrix: np.ndarray) -> np.ndarray: - D, V = np.linalg.eig(moment_matrix) + D, V = linalg.eig(moment_matrix) Dsorted = sort(D) Vsorted = V[:, D.argsort()] if abs(Dsorted[-1] / Dsorted[-2]) < 1.01: diff --git a/pyrecest/distributions/hypersphere_subset/bingham_distribution.py b/pyrecest/distributions/hypersphere_subset/bingham_distribution.py index 68058785..63d4f735 100644 --- a/pyrecest/distributions/hypersphere_subset/bingham_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/bingham_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import linalg from math import pi from pyrecest.backend import sum from pyrecest.backend import eye @@ -85,7 +86,7 @@ def multiply(self, B2): ) # New exponent C = 0.5 * (C + C.T) # Symmetrize - D, V = np.linalg.eig(C) + D, V = linalg.eig(C) order = np.argsort(D) # Sort eigenvalues V = V[:, order] Z_ = D[order] diff --git a/pyrecest/distributions/hypersphere_subset/hyperspherical_dirac_distribution.py b/pyrecest/distributions/hypersphere_subset/hyperspherical_dirac_distribution.py index b335fd4b..dd373b29 100644 --- a/pyrecest/distributions/hypersphere_subset/hyperspherical_dirac_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/hyperspherical_dirac_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import linalg from pyrecest.backend import sum from pyrecest.backend import reshape import matplotlib.pyplot as plt @@ -36,5 +37,5 @@ def to_circular_dirac_distribution(self): def mean_direction(self): vec_sum = sum(self.d * reshape(self.w, (-1, 1)), axis=0) - mu = vec_sum / np.linalg.norm(vec_sum) + mu = vec_sum / linalg.norm(vec_sum) return mu \ No newline at end of file diff --git a/pyrecest/distributions/hypersphere_subset/hyperspherical_uniform_distribution.py b/pyrecest/distributions/hypersphere_subset/hyperspherical_uniform_distribution.py index ec188d4f..913791f1 100644 --- a/pyrecest/distributions/hypersphere_subset/hyperspherical_uniform_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/hyperspherical_uniform_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import linalg from math import pi from pyrecest.backend import random from typing import Union @@ -42,7 +43,7 @@ def sample(self, n: Union[int, int32, int64]): s[:, 1] = r * sin(phi) else: samples_unnorm = random.randn(n, self.dim + 1) - s = samples_unnorm / np.linalg.norm(samples_unnorm, axis=1, keepdims=True) + s = samples_unnorm / linalg.norm(samples_unnorm, axis=1, keepdims=True) return s def get_manifold_size(self): diff --git a/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py b/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py index 425ba524..4d3141f2 100644 --- a/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py +++ b/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py @@ -1,3 +1,4 @@ +from pyrecest.backend import linalg from math import pi from pyrecest.backend import sqrt from pyrecest.backend import sin @@ -102,12 +103,12 @@ def mean_direction(self): x = real(self.coeff_mat[1, 0] - self.coeff_mat[1, 2]) / sqrt(2) z = real(self.coeff_mat[1, 1]) - if np.linalg.norm(array([x, y, z])) < 1e-9: + if linalg.norm(array([x, y, z])) < 1e-9: raise ValueError( "Coefficients of degree 1 are almost zero. Therefore, no meaningful mean is available" ) - mu = array([x, y, z]) / np.linalg.norm(array([x, y, z])) + mu = array([x, y, z]) / linalg.norm(array([x, y, z])) return mu diff --git a/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py b/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py index 13148391..3ef36876 100644 --- a/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import linalg from math import pi from typing import Union from pyrecest.backend import sinh @@ -28,7 +29,7 @@ def __init__(self, mu: np.ndarray, kappa: np.number | numbers.Real): assert ( mu.shape[0] >= 2 ), "mu must be at least two-dimensional for the circular case" - assert abs(np.linalg.norm(mu) - 1) < epsilon, "mu must be a normalized" + assert abs(linalg.norm(mu) - 1) < epsilon, "mu must be a normalized" self.mu = mu self.kappa = kappa @@ -112,8 +113,8 @@ def from_moment(m: np.ndarray): assert ndim(m) == 1, "mu must be a vector" assert len(m) >= 2, "mu must be at least 2 for the circular case" - mu_ = m / np.linalg.norm(m) - Rbar = np.linalg.norm(m) + mu_ = m / linalg.norm(m) + Rbar = linalg.norm(m) kappa_ = VonMisesFisherDistribution.a_d_inverse(np.size(m), Rbar) V = VonMisesFisherDistribution(mu_, kappa_) @@ -132,7 +133,7 @@ def multiply(self, other: "VonMisesFisherDistribution"): assert self.mu.shape == other.mu.shape mu_ = self.kappa * self.mu + other.kappa * other.mu - kappa_ = np.linalg.norm(mu_) + kappa_ = linalg.norm(mu_) mu_ = mu_ / kappa_ return VonMisesFisherDistribution(mu_, kappa_) diff --git a/pyrecest/distributions/hypersphere_subset/watson_distribution.py b/pyrecest/distributions/hypersphere_subset/watson_distribution.py index c99dac36..f5136902 100644 --- a/pyrecest/distributions/hypersphere_subset/watson_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/watson_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import linalg from pyrecest.backend import vstack from pyrecest.backend import tile from pyrecest.backend import hstack @@ -32,7 +33,7 @@ def __init__(self, mu: np.ndarray, kappa: np.number | numbers.Real): """ AbstractHypersphericalDistribution.__init__(self, dim=mu.shape[0] - 1) assert mu.ndim == 1, "mu must be a 1-D vector" - assert abs(np.linalg.norm(mu) - 1) < self.EPSILON, "mu is unnormalized" + assert abs(linalg.norm(mu) - 1) < self.EPSILON, "mu is unnormalized" self.mu = mu self.kappa = kappa diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py b/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py index 3c067a60..aa347695 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import linalg from math import pi from pyrecest.backend import random from typing import Union @@ -34,7 +35,7 @@ def __init__(self, mu: np.ndarray, C: np.ndarray): assert np.size(C) == 1 or C.shape[0] == C.shape[1], "C must be dim x dim" assert np.size(C) == 1 or allclose(C, C.T, atol=1e-8), "C must be symmetric" assert ( - np.size(C) == 1 and C > 0 or all(np.linalg.eigvals(C) > 0) + np.size(C) == 1 and C > 0 or all(linalg.eigvals(C) > 0) ), "C must be positive definite" assert ( np.size(C) == np.size(mu) or np.size(mu) == C.shape[1] diff --git a/pyrecest/distributions/nonperiodic/gaussian_distribution.py b/pyrecest/distributions/nonperiodic/gaussian_distribution.py index 13752175..748f177c 100644 --- a/pyrecest/distributions/nonperiodic/gaussian_distribution.py +++ b/pyrecest/distributions/nonperiodic/gaussian_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import linalg from pyrecest.backend import random from pyrecest.backend import ndim from pyrecest.backend import dot @@ -25,7 +26,7 @@ def __init__(self, mu: np.ndarray, C: np.ndarray, check_validity=True): assert C > 0, "C must be positive definite" elif self.dim == 2: assert ( - C[0, 0] > 0 and np.linalg.det(C) > 0 + C[0, 0] > 0 and linalg.det(C) > 0 ), "C must be positive definite" else: cholesky(C) # Will fail if C is not positive definite @@ -65,7 +66,7 @@ def covariance(self): def multiply(self, other): assert self.dim == other.dim - K = np.linalg.solve(self.C + other.C, self.C) + K = linalg.solve(self.C + other.C, self.C) new_mu = self.mu + dot(K, (other.mu - self.mu)) new_C = self.C - dot(K, self.C) return GaussianDistribution(new_mu, new_C, check_validity=False) diff --git a/pyrecest/filters/random_matrix_tracker.py b/pyrecest/filters/random_matrix_tracker.py index f6381125..36f80280 100644 --- a/pyrecest/filters/random_matrix_tracker.py +++ b/pyrecest/filters/random_matrix_tracker.py @@ -1,3 +1,4 @@ +from pyrecest.backend import linalg from pyrecest.backend import mean from pyrecest.backend import eye from pyrecest.backend import exp @@ -73,17 +74,17 @@ def update(self, measurements, meas_mat, meas_noise_cov): Y = self.extent + Cv S = H @ self.covariance @ H.T + Y / y_cols - K = self.covariance @ np.linalg.solve(S, H).T + K = self.covariance @ linalg.solve(S, H).T self.kinematic_state = self.kinematic_state + K @ (y_.flatten() - Hx) self.covariance = self.covariance - K @ S @ K.T - Xsqrt = np.linalg.cholesky(self.extent) - Ssqrt = np.linalg.cholesky(S) - Ysqrt = np.linalg.cholesky(Y) + Xsqrt = linalg.cholesky(self.extent) + Ssqrt = linalg.cholesky(S) + Ysqrt = linalg.cholesky(Y) - Nsqrt = Xsqrt * np.linalg.inv(Ssqrt) @ (y_ - Hx) + Nsqrt = Xsqrt * linalg.inv(Ssqrt) @ (y_ - Hx) N = Nsqrt @ Nsqrt.T - XYsqrt = Xsqrt * np.linalg.inv(Ysqrt) + XYsqrt = Xsqrt * linalg.inv(Ysqrt) self.extent = (self.alpha * self.extent + N + XYsqrt @ Y_ @ XYsqrt.T) / ( self.alpha + y_cols diff --git a/pyrecest/tests/distributions/test_abstract_hyperhemispherical_distribution.py b/pyrecest/tests/distributions/test_abstract_hyperhemispherical_distribution.py index 54e6cdf8..ad828b53 100644 --- a/pyrecest/tests/distributions/test_abstract_hyperhemispherical_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hyperhemispherical_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import linalg from math import pi from pyrecest.backend import sum from pyrecest.backend import ones @@ -19,7 +20,7 @@ class TestAbstractHyperhemisphericalDistribution(unittest.TestCase): def setUp(self): - self.mu_ = array([0.5, 1.0, 1.0]) / np.linalg.norm([0.5, 1.0, 1.0]) + self.mu_ = array([0.5, 1.0, 1.0]) / linalg.norm([0.5, 1.0, 1.0]) self.kappa_ = 2.0 def test_get_manifold_size(self): diff --git a/pyrecest/tests/distributions/test_abstract_hypersphere_subset_distribution.py b/pyrecest/tests/distributions/test_abstract_hypersphere_subset_distribution.py index 6fa1d71c..8f3e7dff 100644 --- a/pyrecest/tests/distributions/test_abstract_hypersphere_subset_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hypersphere_subset_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import linalg from pyrecest.backend import sin from pyrecest.backend import cos from pyrecest.backend import array @@ -9,7 +10,7 @@ class TestAbstractHypersphereSubsetDistribution(unittest.TestCase): def test_pdf_hyperspherical_coords_1d(self): - mu_ = array([0.5, 1.0]) / np.linalg.norm([0.5, 1.0]) + mu_ = array([0.5, 1.0]) / linalg.norm([0.5, 1.0]) kappa_ = 2.0 vmf = VonMisesFisherDistribution(mu_, kappa_) @@ -25,7 +26,7 @@ def fangles_1d(phi): ) def test_pdf_hyperspherical_coords_2d(self): - mu_ = array([0.5, 1.0, 1.0]) / np.linalg.norm([0.5, 1.0, 1.0]) + mu_ = array([0.5, 1.0, 1.0]) / linalg.norm([0.5, 1.0, 1.0]) kappa_ = 2.0 vmf = VonMisesFisherDistribution(mu_, kappa_) @@ -51,7 +52,7 @@ def fangles_2d(phi1, phi2): ) def test_pdf_hyperspherical_coords_3d(self): - mu_ = array([0.5, 1.0, 1.0, -0.5]) / np.linalg.norm([0.5, 1.0, 1.0, -0.5]) + mu_ = array([0.5, 1.0, 1.0, -0.5]) / linalg.norm([0.5, 1.0, 1.0, -0.5]) kappa_ = 2.0 vmf = VonMisesFisherDistribution(mu_, kappa_) diff --git a/pyrecest/tests/distributions/test_abstract_hyperspherical_distribution.py b/pyrecest/tests/distributions/test_abstract_hyperspherical_distribution.py index 224b52ab..6850cdb1 100644 --- a/pyrecest/tests/distributions/test_abstract_hyperspherical_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hyperspherical_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import linalg from math import pi from pyrecest.backend import sqrt from pyrecest.backend import array @@ -17,7 +18,7 @@ class AbstractHypersphericalDistributionTest(unittest.TestCase): def testIntegral2D(self): """Tests the integral calculation in 2D.""" mu = array([1, 1, 2]) - mu = mu / np.linalg.norm(mu) + mu = mu / linalg.norm(mu) kappa = 10 vmf = VonMisesFisherDistribution(mu, kappa) self.assertAlmostEqual(vmf.integrate(), 1, delta=1e-8) @@ -25,7 +26,7 @@ def testIntegral2D(self): def testIntegral3D(self): """Tests the integral calculation in 3D.""" mu = array([1, 1, 2, 2]) - mu = mu / np.linalg.norm(mu) + mu = mu / linalg.norm(mu) kappa = 10 vmf = VonMisesFisherDistribution(mu, kappa) self.assertAlmostEqual(vmf.integrate(), 1, delta=1e-7) @@ -53,13 +54,13 @@ def test_mean_direction_numerical(self): mu = 1 / sqrt(2) * array([1, 1, 0]) kappa = 10 vmf = VonMisesFisherDistribution(mu, kappa) - self.assertLess(np.linalg.norm(vmf.mean_direction_numerical() - mu), 1e-6) + self.assertLess(linalg.norm(vmf.mean_direction_numerical() - mu), 1e-6) def test_plotting_error_free_2d(self): """Tests the plotting function""" mu = array([1, 1, 2]) - mu = mu / np.linalg.norm(mu) + mu = mu / linalg.norm(mu) kappa = 10 vmf = VonMisesFisherDistribution(mu, kappa) vmf.plot() diff --git a/pyrecest/tests/distributions/test_abstract_mixture.py b/pyrecest/tests/distributions/test_abstract_mixture.py index eb00f755..6754f847 100644 --- a/pyrecest/tests/distributions/test_abstract_mixture.py +++ b/pyrecest/tests/distributions/test_abstract_mixture.py @@ -1,3 +1,4 @@ +from pyrecest.backend import linalg from pyrecest.backend import ones from pyrecest.backend import eye from pyrecest.backend import array @@ -38,7 +39,7 @@ def test_sample_metropolis_hastings_basics_only_s2(self): vmf2 = VonMisesFisherDistribution(array([0, 1, 0]), 2) mix = HypersphericalMixture([vmf1, vmf2], [0.5, 0.5]) s = self._test_sample(mix, 10) - self.assertTrue(allclose(np.linalg.norm(s, axis=1), ones(10), rtol=1e-10)) + self.assertTrue(allclose(linalg.norm(s, axis=1), ones(10), rtol=1e-10)) def test_sample_metropolis_hastings_basics_only_h2(self): vmf = VonMisesFisherDistribution(array([1, 0, 0]), 2) @@ -46,7 +47,7 @@ def test_sample_metropolis_hastings_basics_only_h2(self): lambda x: vmf.pdf(x) + vmf.pdf(-x), 2 ) s = self._test_sample(mix, 10) - self.assertTrue(allclose(np.linalg.norm(s, axis=1), ones(10), rtol=1e-10)) + self.assertTrue(allclose(linalg.norm(s, axis=1), ones(10), rtol=1e-10)) if __name__ == "__main__": diff --git a/pyrecest/tests/distributions/test_custom_hemispherical_distribution.py b/pyrecest/tests/distributions/test_custom_hemispherical_distribution.py index 001b778a..79d24998 100644 --- a/pyrecest/tests/distributions/test_custom_hemispherical_distribution.py +++ b/pyrecest/tests/distributions/test_custom_hemispherical_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import linalg from pyrecest.backend import random from pyrecest.backend import eye from pyrecest.backend import array @@ -31,7 +32,7 @@ def test_simple_distribution_2D(self): random.seed(10) points = random.randn(100, 3) points = points[points[:, 2] >= 0, :] - points /= np.linalg.norm(points, axis=1, keepdims=True) + points /= linalg.norm(points, axis=1, keepdims=True) self.assertTrue( allclose( diff --git a/pyrecest/tests/distributions/test_custom_hyperspherical_distribution.py b/pyrecest/tests/distributions/test_custom_hyperspherical_distribution.py index 342d00cb..c04a41d4 100644 --- a/pyrecest/tests/distributions/test_custom_hyperspherical_distribution.py +++ b/pyrecest/tests/distributions/test_custom_hyperspherical_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import linalg from pyrecest.backend import random from pyrecest.backend import array from pyrecest.backend import allclose @@ -25,7 +26,7 @@ def test_simple_distribution(self): random.seed(10) points = random.randn(100, 3) - points /= np.linalg.norm(points, axis=1, keepdims=True) + points /= linalg.norm(points, axis=1, keepdims=True) self.assertTrue( allclose( diff --git a/pyrecest/tests/distributions/test_hyperhemispherical_uniform_distribution.py b/pyrecest/tests/distributions/test_hyperhemispherical_uniform_distribution.py index 72339209..40b931e4 100644 --- a/pyrecest/tests/distributions/test_hyperhemispherical_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_hyperhemispherical_uniform_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import linalg from math import pi from pyrecest.backend import random from pyrecest.backend import reshape @@ -15,7 +16,7 @@ def get_random_points(n, d): random.seed(10) points = random.randn(n, d + 1) points = points[points[:, -1] >= 0, :] - points /= reshape(np.linalg.norm(points, axis=1), (-1, 1)) + points /= reshape(linalg.norm(points, axis=1), (-1, 1)) return points diff --git a/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py b/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py index c82c266b..b229d103 100644 --- a/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import linalg from math import pi from pyrecest.backend import random from pyrecest.backend import sum @@ -19,7 +20,7 @@ def setUp(self): self.d = array( [[0.5, 3, 4, 6, 6], [2, 2, 5, 3, 0], [0.5, 0.2, 5.8, 4.3, 1.2]] ).T - self.d = self.d / np.linalg.norm(self.d, axis=1)[:, None] + self.d = self.d / linalg.norm(self.d, axis=1)[:, None] self.w = array([0.1, 0.1, 0.1, 0.1, 0.6]) self.hdd = HypersphericalDiracDistribution(self.d, self.w) @@ -32,7 +33,7 @@ def test_sampling(self): self.assertEqual(s.shape, (nSamples, self.d.shape[-1])) np.testing.assert_array_almost_equal(s, mod(s, 2 * pi)) np.testing.assert_array_almost_equal( - np.linalg.norm(s, axis=-1), ones(nSamples) + linalg.norm(s, axis=-1), ones(nSamples) ) def test_apply_function(self): diff --git a/pyrecest/tests/distributions/test_hyperspherical_uniform_distribution.py b/pyrecest/tests/distributions/test_hyperspherical_uniform_distribution.py index c3ffc9b4..f3415429 100644 --- a/pyrecest/tests/distributions/test_hyperspherical_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_hyperspherical_uniform_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import linalg from pyrecest.backend import random from pyrecest.backend import ones from pyrecest.backend import allclose @@ -26,7 +27,7 @@ def test_pdf(self): for dim in range(2, 5): hud = HypersphericalUniformDistribution(dim) x = random.rand(dim + 1) - x = x / np.linalg.norm(x) + x = x / linalg.norm(x) self.assertAlmostEqual( hud.pdf(x), 1 @@ -43,7 +44,7 @@ def test_sample(self): samples = hud.sample(n) self.assertEqual(samples.shape, (n, hud.dim + 1)) self.assertTrue( - allclose(np.linalg.norm(samples, axis=1), ones(n), rtol=1e-10) + allclose(linalg.norm(samples, axis=1), ones(n), rtol=1e-10) ) diff --git a/pyrecest/tests/distributions/test_se3_dirac_distribution.py b/pyrecest/tests/distributions/test_se3_dirac_distribution.py index a77e57a8..a2f1fd9f 100644 --- a/pyrecest/tests/distributions/test_se3_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_se3_dirac_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import linalg from pyrecest.backend import tile from pyrecest.backend import sum from pyrecest.backend import concatenate @@ -25,7 +26,7 @@ def test_constructor(self): [2, 31, 42, 3, 9.9, 5], ] ).T - dSph = dSph / np.linalg.norm(dSph, axis=-1, keepdims=True) + dSph = dSph / linalg.norm(dSph, axis=-1, keepdims=True) dLin = tile(array([-5, 0, 5, 10, 15, 20]), (3, 1)).T w = array([1, 2, 3, 1, 2, 3]) w = w / sum(w) diff --git a/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py b/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py index 7862295d..e2545950 100644 --- a/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py +++ b/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import linalg from pyrecest.backend import sqrt from pyrecest.backend import array from pyrecest.backend import allclose @@ -18,8 +19,8 @@ [0, 1, 0], [0, 0, 1], [1, 1, 0] / sqrt(2), - [1, 1, 2] / np.linalg.norm([1, 1, 2]), - -array([1, 1, 2]) / np.linalg.norm([1, 1, 2]), + [1, 1, 2] / linalg.norm([1, 1, 2]), + -array([1, 1, 2]) / linalg.norm([1, 1, 2]), ] ) @@ -27,7 +28,7 @@ class TestVonMisesFisherDistribution(unittest.TestCase): def setUp(self): self.mu = array([1, 2, 3]) - self.mu = self.mu / np.linalg.norm(self.mu) + self.mu = self.mu / linalg.norm(self.mu) self.kappa = 2 self.vmf = VonMisesFisherDistribution(self.mu, self.kappa) self.other = VonMisesFisherDistribution(array([0, 0, 1]), self.kappa / 3) @@ -73,21 +74,21 @@ def test_vmf_distribution_3d_convolve(self): def test_init_2d(self): mu = array([1, 1, 2]) - mu = mu / np.linalg.norm(mu) + mu = mu / linalg.norm(mu) kappa = 10 dist = VonMisesFisherDistribution(mu, kappa) np.testing.assert_array_almost_equal(dist.C, 7.22562325261744e-05) def test_init_3d(self): mu = array([1, 1, 2, -3]) - mu = mu / np.linalg.norm(mu) + mu = mu / linalg.norm(mu) kappa = 2 dist = VonMisesFisherDistribution(mu, kappa) np.testing.assert_array_almost_equal(dist.C, 0.0318492506152322) def test_pdf_2d(self): mu = array([1, 1, 2]) - mu = mu / np.linalg.norm(mu) + mu = mu / linalg.norm(mu) kappa = 10 dist = VonMisesFisherDistribution(mu, kappa) @@ -107,7 +108,7 @@ def test_pdf_2d(self): def test_pdf_3d(self): mu = array([1, 1, 2, -3]) - mu = mu / np.linalg.norm(mu) + mu = mu / linalg.norm(mu) kappa = 2 dist = VonMisesFisherDistribution(mu, kappa) @@ -125,7 +126,7 @@ def test_pdf_3d(self): [1, 0, 0, -1], ] ) - xs = xs_unnorm / np.linalg.norm(xs_unnorm, axis=1, keepdims=True) + xs = xs_unnorm / linalg.norm(xs_unnorm, axis=1, keepdims=True) np.testing.assert_array_almost_equal( dist.pdf(xs), @@ -176,7 +177,7 @@ def test_hellinger_distance_3d(self): # 3D vmf1 = VonMisesFisherDistribution(array([1, 0, 0]), 0.6) mu2 = array([1, 2, 3]) - vmf2 = VonMisesFisherDistribution(mu2 / np.linalg.norm(mu2), 2.1) + vmf2 = VonMisesFisherDistribution(mu2 / linalg.norm(mu2), 2.1) self._test_hellinger_distance_helper(vmf1, vmf2, numerical_delta=1e-6) @parameterized.expand( @@ -195,7 +196,7 @@ def test_from_distribution_vmf(self, _, mu, kappa): def test_from_distribution_dirac(self): dirac_dist = HypersphericalDiracDistribution( array( - [[0, 0, 1], [0, 1, 0], [1, 0, 0], [0, 1, 1] / np.linalg.norm([0, 1, 1])] + [[0, 0, 1], [0, 1, 0], [1, 0, 0], [0, 1, 1] / linalg.norm([0, 1, 1])] ) ) vmf = VonMisesFisherDistribution.from_distribution(dirac_dist) diff --git a/pyrecest/tests/distributions/test_watson_distribution.py b/pyrecest/tests/distributions/test_watson_distribution.py index 7caeba1a..e67c3888 100644 --- a/pyrecest/tests/distributions/test_watson_distribution.py +++ b/pyrecest/tests/distributions/test_watson_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import linalg from pyrecest.backend import array import unittest @@ -11,11 +12,11 @@ def setUp(self): [[1, 0, 0], [1, 2, 2], [0, 1, 0], [0, 0, 1], [1, 1, 1], [-1, -1, -1]], dtype=float, ) - self.xs = self.xs / np.linalg.norm(self.xs, axis=1, keepdims=True) + self.xs = self.xs / linalg.norm(self.xs, axis=1, keepdims=True) def test_constructor(self): mu = array([1, 2, 3]) - mu = mu / np.linalg.norm(mu) + mu = mu / linalg.norm(mu) kappa = 2 w = WatsonDistribution(mu, kappa) @@ -26,7 +27,7 @@ def test_constructor(self): def test_pdf(self): mu = array([1, 2, 3]) - mu = mu / np.linalg.norm(mu) + mu = mu / linalg.norm(mu) kappa = 2 w = WatsonDistribution(mu, kappa) @@ -46,7 +47,7 @@ def test_pdf(self): def test_integrate(self): mu = array([1, 2, 3]) - mu = mu / np.linalg.norm(mu) + mu = mu / linalg.norm(mu) kappa = 2 w = WatsonDistribution(mu, kappa) self.assertAlmostEqual(w.integrate(), 1, delta=1e-5) diff --git a/pyrecest/tests/filters/test_random_matrix_tracker.py b/pyrecest/tests/filters/test_random_matrix_tracker.py index 76ac0786..b07bf8ae 100644 --- a/pyrecest/tests/filters/test_random_matrix_tracker.py +++ b/pyrecest/tests/filters/test_random_matrix_tracker.py @@ -1,3 +1,4 @@ +from pyrecest.backend import linalg from pyrecest.backend import mean from pyrecest.backend import eye from pyrecest.backend import concatenate @@ -113,11 +114,11 @@ def test_update(self, name, offset, _): # Check if extent has changed as expected if name == "smaller": np.testing.assert_array_less( - zeros(2), np.linalg.eig(self.initial_extent - self.tracker.extent)[0] + zeros(2), linalg.eig(self.initial_extent - self.tracker.extent)[0] ) elif name == "larger": np.testing.assert_array_less( - zeros(2), np.linalg.eig(self.tracker.extent - self.initial_extent)[0] + zeros(2), linalg.eig(self.tracker.extent - self.initial_extent)[0] ) else: raise ValueError(f"Invalid test name: {name}") diff --git a/pyrecest/tests/test_evaluation_basic.py b/pyrecest/tests/test_evaluation_basic.py index 8bf9e86a..01c5e598 100644 --- a/pyrecest/tests/test_evaluation_basic.py +++ b/pyrecest/tests/test_evaluation_basic.py @@ -1,3 +1,4 @@ +from pyrecest.backend import linalg from pyrecest.backend import random from pyrecest.backend import sqrt from pyrecest.backend import shape @@ -173,7 +174,7 @@ def dummy_extract_mean(x): return x def dummy_distance_function(x, y): - return np.linalg.norm(x - y) + return linalg.norm(x - y) # Initialize the outer array with object type groundtruths = empty((3, 4), dtype=object) diff --git a/pyrecest/tests/test_hyperspherical_sampler.py b/pyrecest/tests/test_hyperspherical_sampler.py index 6ce9212e..76dcdc7c 100644 --- a/pyrecest/tests/test_hyperspherical_sampler.py +++ b/pyrecest/tests/test_hyperspherical_sampler.py @@ -1,3 +1,4 @@ +from pyrecest.backend import linalg from pyrecest.backend import random from pyrecest.backend import prod from pyrecest.backend import allclose @@ -125,7 +126,7 @@ def test_conversion(self): n = 100 # sample size random_vectors = random.randn(n, 4) unit_vectors = ( - random_vectors / np.linalg.norm(random_vectors, axis=1)[:, np.newaxis] + random_vectors / linalg.norm(random_vectors, axis=1)[:, np.newaxis] ) # Pass the quaternions through the conversion functions diff --git a/pyrecest/utils/metrics.py b/pyrecest/utils/metrics.py index c07f63ce..4b683379 100644 --- a/pyrecest/utils/metrics.py +++ b/pyrecest/utils/metrics.py @@ -1,3 +1,4 @@ +from pyrecest.backend import linalg from pyrecest.backend import mean from pyrecest.backend import zeros import numpy as np @@ -14,6 +15,6 @@ def anees(estimates, uncertainties, groundtruths): for i in range(n): error = estimates[i] - groundtruths[i] - NEES[i] = error.T @ np.linalg.solve(uncertainties[i], error) + NEES[i] = error.T @ linalg.solve(uncertainties[i], error) return mean(NEES) \ No newline at end of file diff --git a/pyrecest/utils/plotting.py b/pyrecest/utils/plotting.py index ef602438..6c036702 100644 --- a/pyrecest/utils/plotting.py +++ b/pyrecest/utils/plotting.py @@ -1,3 +1,4 @@ +from pyrecest.backend import linalg from math import pi from pyrecest.backend import sqrt from pyrecest.backend import sin @@ -36,7 +37,7 @@ def plot_ellipsoid_3d(center, shape_matrix, scaling_factor=1, color="blue"): y = outer(sin(u), sin(v)) z = outer(ones(np.size(u)), cos(v)) - V, D = np.linalg.eig(shape_matrix) + V, D = linalg.eig(shape_matrix) all_coords = V @ sqrt(D) @ array( [x.ravel(), y.ravel(), z.ravel()] ) + center.reshape(-1, 1) From be4c3b001e375622424232baee5b46949e74a251 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 17 Oct 2023 20:33:37 +0100 Subject: [PATCH 016/232] Morechanges --- .../distributions/circle/abstract_circular_distribution.py | 4 ++-- pyrecest/distributions/circle/wrapped_normal_distribution.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pyrecest/distributions/circle/abstract_circular_distribution.py b/pyrecest/distributions/circle/abstract_circular_distribution.py index 87a4f947..81a9d5f2 100644 --- a/pyrecest/distributions/circle/abstract_circular_distribution.py +++ b/pyrecest/distributions/circle/abstract_circular_distribution.py @@ -44,9 +44,9 @@ def _cdf_numerical_single( x_mod = mod(x, 2 * pi) if x_mod < starting_point_mod: - return 1 - self.integrate_numerically([x_mod, starting_point_mod]) + return 1 - self.integrate_numerically(array([x_mod, starting_point_mod])) - return self.integrate_numerically([starting_point_mod, x_mod]) + return self.integrate_numerically(array([starting_point_mod, x_mod])) def to_vm(self): """ diff --git a/pyrecest/distributions/circle/wrapped_normal_distribution.py b/pyrecest/distributions/circle/wrapped_normal_distribution.py index e2c84d29..79ab683e 100644 --- a/pyrecest/distributions/circle/wrapped_normal_distribution.py +++ b/pyrecest/distributions/circle/wrapped_normal_distribution.py @@ -54,10 +54,10 @@ def pdf(self, xs: np.ndarray | np.number | numbers.Real): if self.sigma <= 0: raise ValueError(f"sigma must be >0, but received {self.sigma}.") - xs = np.asarray(xs) + xs = array(xs) if ndim(xs) == 0: xs = array([xs]) - n_inputs = np.size(xs) + n_inputs = xs.shape[0] result = zeros(n_inputs) # check if sigma is large and return uniform distribution in this case From 3182738f5053335864bddf1c4a39946e20f82988 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 17 Oct 2023 20:38:50 +0100 Subject: [PATCH 017/232] Even more --- .../distributions/test_abstract_circular_distribution.py | 5 +++-- .../distributions/test_von_mises_fisher_distribution.py | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/pyrecest/tests/distributions/test_abstract_circular_distribution.py b/pyrecest/tests/distributions/test_abstract_circular_distribution.py index 0208332b..fba77216 100644 --- a/pyrecest/tests/distributions/test_abstract_circular_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_circular_distribution.py @@ -2,6 +2,7 @@ from pyrecest.backend import arange from pyrecest.backend import allclose from pyrecest.backend import all +from pyrecest.backend import array import unittest import numpy as np @@ -67,8 +68,8 @@ def test_integral_numerical(self): with self.subTest(distribution=dist, interval=interval): self.assertTrue( allclose( - dist.integrate_numerically(interval), - dist.integrate(interval), + dist.integrate_numerically(array(interval)), + dist.integrate(array(interval)), rtol=1e-10, ) ) diff --git a/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py b/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py index e2545950..719bdbcd 100644 --- a/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py +++ b/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py @@ -18,8 +18,8 @@ [1, 0, 0], [0, 1, 0], [0, 0, 1], - [1, 1, 0] / sqrt(2), - [1, 1, 2] / linalg.norm([1, 1, 2]), + array([1, 1, 0]) / sqrt(2), + array([1, 1, 2]) / linalg.norm([1, 1, 2]), -array([1, 1, 2]) / linalg.norm([1, 1, 2]), ] ) From e65d20914af445417d7102b390b4a41ae86c9a11 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 17 Oct 2023 20:44:00 +0100 Subject: [PATCH 018/232] More adapations --- .../test_abstract_hyperhemispherical_distribution.py | 2 +- .../tests/distributions/test_von_mises_fisher_distribution.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pyrecest/tests/distributions/test_abstract_hyperhemispherical_distribution.py b/pyrecest/tests/distributions/test_abstract_hyperhemispherical_distribution.py index ad828b53..b188bc1e 100644 --- a/pyrecest/tests/distributions/test_abstract_hyperhemispherical_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hyperhemispherical_distribution.py @@ -20,7 +20,7 @@ class TestAbstractHyperhemisphericalDistribution(unittest.TestCase): def setUp(self): - self.mu_ = array([0.5, 1.0, 1.0]) / linalg.norm([0.5, 1.0, 1.0]) + self.mu_ = array([0.5, 1.0, 1.0]) / linalg.norm(array([0.5, 1.0, 1.0])) self.kappa_ = 2.0 def test_get_manifold_size(self): diff --git a/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py b/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py index 719bdbcd..772ef7c4 100644 --- a/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py +++ b/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py @@ -19,8 +19,8 @@ [0, 1, 0], [0, 0, 1], array([1, 1, 0]) / sqrt(2), - array([1, 1, 2]) / linalg.norm([1, 1, 2]), - -array([1, 1, 2]) / linalg.norm([1, 1, 2]), + array([1, 1, 2]) / linalg.norm(array([1, 1, 2])), + -array([1, 1, 2]) / linalg.norm(array([1, 1, 2])), ] ) From 3a5e0a1a26343701318f160339876b72f959d5da Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 17 Oct 2023 20:50:19 +0100 Subject: [PATCH 019/232] More --- .../test_abstract_hypersphere_subset_distribution.py | 2 +- .../test_abstract_hypertoroidal_distribution.py | 8 ++++---- .../test_von_mises_fisher_distribution.py | 12 ++++++------ 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/pyrecest/tests/distributions/test_abstract_hypersphere_subset_distribution.py b/pyrecest/tests/distributions/test_abstract_hypersphere_subset_distribution.py index 8f3e7dff..a1b5e0a8 100644 --- a/pyrecest/tests/distributions/test_abstract_hypersphere_subset_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hypersphere_subset_distribution.py @@ -10,7 +10,7 @@ class TestAbstractHypersphereSubsetDistribution(unittest.TestCase): def test_pdf_hyperspherical_coords_1d(self): - mu_ = array([0.5, 1.0]) / linalg.norm([0.5, 1.0]) + mu_ = array([0.5, 1.0]) / linalg.norm(array([0.5, 1.0])) kappa_ = 2.0 vmf = VonMisesFisherDistribution(mu_, kappa_) diff --git a/pyrecest/tests/distributions/test_abstract_hypertoroidal_distribution.py b/pyrecest/tests/distributions/test_abstract_hypertoroidal_distribution.py index 22f9f975..84faaac3 100644 --- a/pyrecest/tests/distributions/test_abstract_hypertoroidal_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hypertoroidal_distribution.py @@ -1,6 +1,6 @@ from math import pi import unittest - +from pyrecest.backend import array import numpy as np from pyrecest.distributions import AbstractHypertoroidalDistribution @@ -8,12 +8,12 @@ class TestAbstractHypertoroidalDistribution(unittest.TestCase): def test_angular_error(self): np.testing.assert_allclose( - AbstractHypertoroidalDistribution.angular_error(pi, 0), pi + AbstractHypertoroidalDistribution.angular_error(array(pi), array(0.0)), pi ) np.testing.assert_allclose( - AbstractHypertoroidalDistribution.angular_error(0, 2 * pi), 0 + AbstractHypertoroidalDistribution.angular_error(array(0), array(2 * pi)), 0 ) np.testing.assert_allclose( - AbstractHypertoroidalDistribution.angular_error(pi / 4, 7 * pi / 4), + AbstractHypertoroidalDistribution.angular_error(array(pi / 4), array(7 * pi / 4)), pi / 2, ) \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py b/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py index 772ef7c4..1b6f9fb3 100644 --- a/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py +++ b/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py @@ -15,12 +15,12 @@ vectors_to_test_2d = array( [ - [1, 0, 0], - [0, 1, 0], - [0, 0, 1], - array([1, 1, 0]) / sqrt(2), - array([1, 1, 2]) / linalg.norm(array([1, 1, 2])), - -array([1, 1, 2]) / linalg.norm(array([1, 1, 2])), + [1.0, 0.0, 0.0], + [0.0, 1.0, 0.0], + [0.0, 0.0, 1.0], + array([1.0, 1.0, 0.0]) / sqrt(2.0), + array([1.0, 1.0, 2.0]) / linalg.norm(array([1.0, 1.0, 2.0])), + -array([1.0, 1.0, 2.0]) / linalg.norm(array([1.0, 1.0, 2.0])), ] ) From 73145d2e9f532a31a7ad65d7ce37d6737dc08326 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 17 Oct 2023 21:05:43 +0100 Subject: [PATCH 020/232] More changes --- .../hypersphere_subset/von_mises_fisher_distribution.py | 2 +- .../test_abstract_hypersphere_subset_distribution.py | 4 ++-- .../test_abstract_hyperspherical_distribution.py | 8 ++++---- .../test_spherical_harmonics_distribution_complex.py | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py b/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py index 3ef36876..98d62c25 100644 --- a/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py @@ -29,7 +29,7 @@ def __init__(self, mu: np.ndarray, kappa: np.number | numbers.Real): assert ( mu.shape[0] >= 2 ), "mu must be at least two-dimensional for the circular case" - assert abs(linalg.norm(mu) - 1) < epsilon, "mu must be a normalized" + assert abs(linalg.norm(mu) - 1.0) < epsilon, "mu must be a normalized" self.mu = mu self.kappa = kappa diff --git a/pyrecest/tests/distributions/test_abstract_hypersphere_subset_distribution.py b/pyrecest/tests/distributions/test_abstract_hypersphere_subset_distribution.py index a1b5e0a8..63deb3b6 100644 --- a/pyrecest/tests/distributions/test_abstract_hypersphere_subset_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hypersphere_subset_distribution.py @@ -26,7 +26,7 @@ def fangles_1d(phi): ) def test_pdf_hyperspherical_coords_2d(self): - mu_ = array([0.5, 1.0, 1.0]) / linalg.norm([0.5, 1.0, 1.0]) + mu_ = array([0.5, 1.0, 1.0]) / linalg.norm(array([0.5, 1.0, 1.0])) kappa_ = 2.0 vmf = VonMisesFisherDistribution(mu_, kappa_) @@ -52,7 +52,7 @@ def fangles_2d(phi1, phi2): ) def test_pdf_hyperspherical_coords_3d(self): - mu_ = array([0.5, 1.0, 1.0, -0.5]) / linalg.norm([0.5, 1.0, 1.0, -0.5]) + mu_ = array([0.5, 1.0, 1.0, -0.5]) / linalg.norm(array([0.5, 1.0, 1.0, -0.5])) kappa_ = 2.0 vmf = VonMisesFisherDistribution(mu_, kappa_) diff --git a/pyrecest/tests/distributions/test_abstract_hyperspherical_distribution.py b/pyrecest/tests/distributions/test_abstract_hyperspherical_distribution.py index 6850cdb1..4af18a61 100644 --- a/pyrecest/tests/distributions/test_abstract_hyperspherical_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hyperspherical_distribution.py @@ -17,7 +17,7 @@ class AbstractHypersphericalDistributionTest(unittest.TestCase): def testIntegral2D(self): """Tests the integral calculation in 2D.""" - mu = array([1, 1, 2]) + mu = array([1.0, 1.0, 2.0]) mu = mu / linalg.norm(mu) kappa = 10 vmf = VonMisesFisherDistribution(mu, kappa) @@ -25,7 +25,7 @@ def testIntegral2D(self): def testIntegral3D(self): """Tests the integral calculation in 3D.""" - mu = array([1, 1, 2, 2]) + mu = array([1.0, 1.0, 2.0, 2.0]) mu = mu / linalg.norm(mu) kappa = 10 vmf = VonMisesFisherDistribution(mu, kappa) @@ -51,7 +51,7 @@ def testUnitSphereSurface(self): def test_mean_direction_numerical(self): """Tests the numerical mean direction calculation.""" - mu = 1 / sqrt(2) * array([1, 1, 0]) + mu = 1 / sqrt(2) * array([1.0, 1.0, 0.0]) kappa = 10 vmf = VonMisesFisherDistribution(mu, kappa) self.assertLess(linalg.norm(vmf.mean_direction_numerical() - mu), 1e-6) @@ -59,7 +59,7 @@ def test_mean_direction_numerical(self): def test_plotting_error_free_2d(self): """Tests the plotting function""" - mu = array([1, 1, 2]) + mu = array([1.0, 1.0, 2.0]) mu = mu / linalg.norm(mu) kappa = 10 vmf = VonMisesFisherDistribution(mu, kappa) diff --git a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py index c72221d4..e8ea62f3 100644 --- a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py +++ b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py @@ -877,7 +877,7 @@ def test_conversion(self, _, coeff_mat): ], ] ), - array([1, 1, 0] / sqrt(2)), + array([1, 1, 0]) / sqrt(2.0)), SphericalHarmonicsDistributionComplex.mean_direction, ), ( From 050b02f7bafc62f70ec1e0641255b4668e4107a5 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 17 Oct 2023 21:08:18 +0100 Subject: [PATCH 021/232] Changes --- .../cart_prod/partially_wrapped_normal_distribution.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py b/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py index 7dac10f8..a6c7c314 100644 --- a/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py +++ b/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py @@ -38,7 +38,7 @@ def __init__( ): assert bound_dim >= 0, "bound_dim must be non-negative" assert ndim(mu) == 1, "mu must be a 1-dimensional array" - assert shape(C) == (np.size(mu), np.size(mu)), "C must match size of mu" + assert C.shape == (mu.shape[-1], mu.shape[-1]), "C must match size of mu" assert allclose(C, C.T), "C must be symmetric" assert all(linalg.eigvals(C) > 0), "C must be positive definite" assert bound_dim <= np.size(mu) From c1e6a9628a1d2b09149b6c806c67adbd3b813cb0 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Wed, 18 Oct 2023 06:41:34 +0100 Subject: [PATCH 022/232] More changes for backend --- .../abstract_hypercylindrical_distribution.py | 4 ++-- .../hypertoroidal_wrapped_normal_distribution.py | 14 ++++++-------- pyrecest/evaluation/plot_results.py | 2 +- .../distributions/test_watson_distribution.py | 2 +- pyrecest/utils/plotting.py | 2 +- 5 files changed, 11 insertions(+), 13 deletions(-) diff --git a/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py b/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py index 681ceb0d..c2652304 100644 --- a/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py +++ b/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py @@ -163,11 +163,11 @@ def condition_on_linear(self, input_lin, normalize=True): The distribution after conditioning. """ assert ( - np.size(input_lin) == self.lin_dim and ndim(input_lin) <= 1 + input_lin.shape[0] == self.lin_dim and ndim(input_lin) <= 1 ), "Input should be of size (lin_dim,)." def f_cond_unnorm(x, input_lin=input_lin): - n_inputs = np.size(x) // x.shape[-1] if ndim(x) > 1 else np.size(x) + n_inputs = np.size(x) // x.shape[-1] if ndim(x) > 1 else x.shape[0] input_repeated = tile(input_lin, (n_inputs, 1)) return self.pdf(np.column_stack((x, input_repeated))) diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py b/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py index aa347695..7f14e7bd 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py @@ -30,17 +30,15 @@ def __init__(self, mu: np.ndarray, C: np.ndarray): :param C: Covariance matrix. :raises AssertionError: If C_ is not square, not symmetric, not positive definite, or its dimension does not match with mu_. """ - AbstractHypertoroidalDistribution.__init__(self, np.size(mu)) - # First check is for 1-D case - assert np.size(C) == 1 or C.shape[0] == C.shape[1], "C must be dim x dim" - assert np.size(C) == 1 or allclose(C, C.T, atol=1e-8), "C must be symmetric" + assert C.shape[0] == C.shape[1], "C must be dim x dim" + assert allclose(C, C.T, atol=1e-8), "C must be symmetric" assert ( - np.size(C) == 1 and C > 0 or all(linalg.eigvals(C) > 0) + linalg.cholesky(C) # fails if not positiv definite ), "C must be positive definite" assert ( - np.size(C) == np.size(mu) or np.size(mu) == C.shape[1] - ), "mu must be dim x 1" - + np.shape(mu) == (C.shape[1],) + ), "mu must be of shape (dim,)" + AbstractHypertoroidalDistribution.__init__(self, mu.shape[0]) self.mu = mod(mu, 2 * pi) self.C = C diff --git a/pyrecest/evaluation/plot_results.py b/pyrecest/evaluation/plot_results.py index c34cdb8b..7a986502 100644 --- a/pyrecest/evaluation/plot_results.py +++ b/pyrecest/evaluation/plot_results.py @@ -151,7 +151,7 @@ def plot_results( if ( params[0] is not None and not any(isnan(params)) - and np.size(params) > 1 + and params.shape[0] > 1 ): plt.plot( times_factor * times_mean, diff --git a/pyrecest/tests/distributions/test_watson_distribution.py b/pyrecest/tests/distributions/test_watson_distribution.py index e67c3888..363b8b75 100644 --- a/pyrecest/tests/distributions/test_watson_distribution.py +++ b/pyrecest/tests/distributions/test_watson_distribution.py @@ -23,7 +23,7 @@ def test_constructor(self): self.assertIsInstance(w, WatsonDistribution) np.testing.assert_array_equal(w.mu, mu) self.assertEqual(w.kappa, kappa) - self.assertEqual(w.input_dim, np.size(mu)) + self.assertEqual(w.input_dim, mu.shape[0]) def test_pdf(self): mu = array([1, 2, 3]) diff --git a/pyrecest/utils/plotting.py b/pyrecest/utils/plotting.py index 6c036702..c7ff127f 100644 --- a/pyrecest/utils/plotting.py +++ b/pyrecest/utils/plotting.py @@ -35,7 +35,7 @@ def plot_ellipsoid_3d(center, shape_matrix, scaling_factor=1, color="blue"): v = linspace(0, pi, 100) x = outer(cos(u), sin(v)) y = outer(sin(u), sin(v)) - z = outer(ones(np.size(u)), cos(v)) + z = outer(ones(u.shape[0]), cos(v)) V, D = linalg.eig(shape_matrix) all_coords = V @ sqrt(D) @ array( From e39ea705cc2838d3aee28527a621646dd89ff4eb Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Wed, 18 Oct 2023 06:48:40 +0100 Subject: [PATCH 023/232] More adapations --- pyrecest/distributions/hypertorus/hypertoroidal_mixture.py | 2 +- pyrecest/sampling/hyperspherical_sampler.py | 2 +- .../tests/distributions/test_circular_fourier_distribution.py | 2 +- pyrecest/tests/filters/test_random_matrix_tracker.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_mixture.py b/pyrecest/distributions/hypertorus/hypertoroidal_mixture.py index 26e8e5d4..fbe3085c 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_mixture.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_mixture.py @@ -51,7 +51,7 @@ def shift(self, shift_by): :param shift_angles: angles to shift by :returns: shifted distribution """ - assert np.size(shift_by) == self.dim + assert shift_by.shape == (self.dim,) hd_shifted = copy.deepcopy(self) hd_shifted.dists = [dist.shift(shift_by) for dist in hd_shifted.dists] return hd_shifted diff --git a/pyrecest/sampling/hyperspherical_sampler.py b/pyrecest/sampling/hyperspherical_sampler.py index bccd6a25..fe30e8e8 100644 --- a/pyrecest/sampling/hyperspherical_sampler.py +++ b/pyrecest/sampling/hyperspherical_sampler.py @@ -194,7 +194,7 @@ def get_grid(self, grid_density_parameter: int | list[int]): psi_points = CircularUniformSampler().get_grid(n_sample_circle) - assert np.size(psi_points) != 0 + assert len(psi_points) != 0 nside = 2**i numpixels = hp.nside2npix(nside) diff --git a/pyrecest/tests/distributions/test_circular_fourier_distribution.py b/pyrecest/tests/distributions/test_circular_fourier_distribution.py index 1e3fcf85..7b94642a 100644 --- a/pyrecest/tests/distributions/test_circular_fourier_distribution.py +++ b/pyrecest/tests/distributions/test_circular_fourier_distribution.py @@ -63,7 +63,7 @@ def test_fourier_conversion( dist, coeffs, transformation ) self.assertEqual( - np.size(fd.c), + fd.c.shape[0], ceil(coeffs / 2), "Length of Fourier Coefficients mismatch.", ) diff --git a/pyrecest/tests/filters/test_random_matrix_tracker.py b/pyrecest/tests/filters/test_random_matrix_tracker.py index b07bf8ae..0bdaa612 100644 --- a/pyrecest/tests/filters/test_random_matrix_tracker.py +++ b/pyrecest/tests/filters/test_random_matrix_tracker.py @@ -91,7 +91,7 @@ def test_predict(self): def test_update(self, name, offset, _): ys = array([self.initial_state + offset_row for offset_row in offset]).T Cv = array([[0.1, 0.0], [0.0, 0.1]]) - H = eye(np.size(self.initial_state)) + H = eye(self.initial_state.shape[0]) # Call the update method self.tracker.update(ys, H, Cv) From 3245c87ce71ca2124e1117ba43642979636b16db Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Wed, 18 Oct 2023 07:09:32 +0100 Subject: [PATCH 024/232] More changes for backend --- pyrecest/_backend/__init__.py | 1 + pyrecest/_backend/numpy/__init__.py | 1 + pyrecest/_backend/pytorch/__init__.py | 1 + .../cart_prod/partially_wrapped_normal_distribution.py | 7 +++---- .../distributions/nonperiodic/gaussian_distribution.py | 4 ++-- pyrecest/utils/plotting.py | 1 + 6 files changed, 9 insertions(+), 6 deletions(-) diff --git a/pyrecest/_backend/__init__.py b/pyrecest/_backend/__init__.py index 3147df87..41d6e86e 100644 --- a/pyrecest/_backend/__init__.py +++ b/pyrecest/_backend/__init__.py @@ -166,6 +166,7 @@ def get_backend_name(): "zeros", "zeros_like", "trapz", + "diag", # Added for pyrecest ], "autodiff": [ "custom_gradient", diff --git a/pyrecest/_backend/numpy/__init__.py b/pyrecest/_backend/numpy/__init__.py index 45b560fa..3f7a75e1 100644 --- a/pyrecest/_backend/numpy/__init__.py +++ b/pyrecest/_backend/numpy/__init__.py @@ -71,6 +71,7 @@ vstack, where, zeros_like, + diag, ) from scipy.special import erf, gamma, polygamma # NOQA diff --git a/pyrecest/_backend/pytorch/__init__.py b/pyrecest/_backend/pytorch/__init__.py index 44a0547d..9b6a2204 100644 --- a/pyrecest/_backend/pytorch/__init__.py +++ b/pyrecest/_backend/pytorch/__init__.py @@ -33,6 +33,7 @@ ones_like, polygamma, quantile, + diag, ) from torch import repeat_interleave as repeat from torch import ( diff --git a/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py b/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py index a6c7c314..f5a3eb3b 100644 --- a/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py +++ b/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py @@ -40,14 +40,13 @@ def __init__( assert ndim(mu) == 1, "mu must be a 1-dimensional array" assert C.shape == (mu.shape[-1], mu.shape[-1]), "C must match size of mu" assert allclose(C, C.T), "C must be symmetric" - assert all(linalg.eigvals(C) > 0), "C must be positive definite" - assert bound_dim <= np.size(mu) - assert ndim(mu) == 1 + assert len(linalg.cholesky(C)) > 0, "C must be positive definite" # Will fail if not positive definite + assert bound_dim <= mu.shape[0] if bound_dim > 0: # This decreases the need for many wrappings mu[:bound_dim] = mod(mu[:bound_dim], 2 * pi) AbstractHypercylindricalDistribution.__init__( - self, bound_dim=bound_dim, lin_dim=np.size(mu) - bound_dim + self, bound_dim=bound_dim, lin_dim=mu.shape[0] - bound_dim ) self.mu = mu diff --git a/pyrecest/distributions/nonperiodic/gaussian_distribution.py b/pyrecest/distributions/nonperiodic/gaussian_distribution.py index 748f177c..feaffa4b 100644 --- a/pyrecest/distributions/nonperiodic/gaussian_distribution.py +++ b/pyrecest/distributions/nonperiodic/gaussian_distribution.py @@ -15,10 +15,10 @@ class GaussianDistribution(AbstractLinearDistribution): def __init__(self, mu: np.ndarray, C: np.ndarray, check_validity=True): AbstractLinearDistribution.__init__(self, dim=np.size(mu)) + assert ndim(mu) <= 1 assert ( - 1 == np.size(mu) == np.size(C) or np.size(mu) == C.shape[0] == C.shape[1] + 1 == mu.shape[0] == C.shape[0] or mu.shape[0] == C.shape[0] == C.shape[1] ), "Size of C invalid" - assert ndim(mu) <= 1 self.mu = mu if check_validity: diff --git a/pyrecest/utils/plotting.py b/pyrecest/utils/plotting.py index c7ff127f..0142f2da 100644 --- a/pyrecest/utils/plotting.py +++ b/pyrecest/utils/plotting.py @@ -1,4 +1,5 @@ from pyrecest.backend import linalg +from pyrecest.backend import diag from math import pi from pyrecest.backend import sqrt from pyrecest.backend import sin From b9863c797c22f6caeedcbd9b8779354444d7df03 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Wed, 18 Oct 2023 13:45:58 +0100 Subject: [PATCH 025/232] Fix --- .../test_spherical_harmonics_distribution_complex.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py index e8ea62f3..05e90a9f 100644 --- a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py +++ b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py @@ -877,7 +877,7 @@ def test_conversion(self, _, coeff_mat): ], ] ), - array([1, 1, 0]) / sqrt(2.0)), + array([1, 1, 0]) / sqrt(2.0), SphericalHarmonicsDistributionComplex.mean_direction, ), ( From d65ecd76993a1443b9e93c7d8c6b529f18c9d26b Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Wed, 18 Oct 2023 13:51:54 +0100 Subject: [PATCH 026/232] More backend adjustments --- .../test_abstract_hyperhemispherical_distribution.py | 2 +- .../test_spherical_harmonics_distribution_complex.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pyrecest/tests/distributions/test_abstract_hyperhemispherical_distribution.py b/pyrecest/tests/distributions/test_abstract_hyperhemispherical_distribution.py index b188bc1e..43039647 100644 --- a/pyrecest/tests/distributions/test_abstract_hyperhemispherical_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hyperhemispherical_distribution.py @@ -39,7 +39,7 @@ def test_mode_numerical(self): def test_sample_metropolis_hastings_basics_only(self): """Tests the sample_metropolis_hastings sampling""" - vmf = VonMisesFisherDistribution(array([1, 0, 0]), 2.0) + vmf = VonMisesFisherDistribution(array([1.0, 0.0, 0.0]), 2.0) chd = CustomHyperhemisphericalDistribution( lambda x: vmf.pdf(x) + vmf.pdf(-x), vmf.dim ) diff --git a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py index 05e90a9f..9154d0db 100644 --- a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py +++ b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py @@ -883,7 +883,7 @@ def test_conversion(self, _, coeff_mat): ( "shd_xz", array([[1, np.nan, np.nan], [sqrt(1 / 2), 1, -sqrt(1 / 2)]]), - array([1, 0, 1] / sqrt(2)), + array([1, 0, 1]) / sqrt(2), SphericalHarmonicsDistributionComplex.mean_direction, ), ( @@ -891,7 +891,7 @@ def test_conversion(self, _, coeff_mat): array( [[1, np.nan, np.nan], [1j * sqrt(1 / 2), 1, 1j * sqrt(1 / 2)]] ), - array([0, 1, 1] / sqrt(2)), + array([0, 1, 1]) / sqrt(2), SphericalHarmonicsDistributionComplex.mean_direction, ), ( From 1b0a88f05a2fa066f5aed43f61af5b9f322eab1d Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Wed, 18 Oct 2023 13:55:43 +0100 Subject: [PATCH 027/232] Progress --- .../distributions/nonperiodic/gaussian_distribution.py | 2 +- .../distributions/test_abstract_linear_distribution.py | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/pyrecest/distributions/nonperiodic/gaussian_distribution.py b/pyrecest/distributions/nonperiodic/gaussian_distribution.py index feaffa4b..d88050d1 100644 --- a/pyrecest/distributions/nonperiodic/gaussian_distribution.py +++ b/pyrecest/distributions/nonperiodic/gaussian_distribution.py @@ -14,7 +14,7 @@ class GaussianDistribution(AbstractLinearDistribution): def __init__(self, mu: np.ndarray, C: np.ndarray, check_validity=True): - AbstractLinearDistribution.__init__(self, dim=np.size(mu)) + AbstractLinearDistribution.__init__(self, dim=mu.shape[0]) assert ndim(mu) <= 1 assert ( 1 == mu.shape[0] == C.shape[0] or mu.shape[0] == C.shape[0] == C.shape[1] diff --git a/pyrecest/tests/distributions/test_abstract_linear_distribution.py b/pyrecest/tests/distributions/test_abstract_linear_distribution.py index fe0ad6f3..63d6586f 100644 --- a/pyrecest/tests/distributions/test_abstract_linear_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_linear_distribution.py @@ -16,14 +16,13 @@ class TestAbstractLinearDistribution(unittest.TestCase): def setUp(self): - self.mu_2D = array([5, 1]) - self.C_2D = array([[2, 1], [1, 1]]) - self.mu_3D = array([1, 2, 3]) - self.C_3D = array([[1.1, 0.4, 0], [0.4, 0.9, 0], [0, 0, 1]]) + self.mu_2D = array([5.0, 1.0]) + self.C_2D = array([[2.0, 1.0], [1.0, 1.0]]) + self.mu_3D = array([1.0, 2.0, 3.0]) + self.C_3D = array([[1.1, 0.4, 0.0], [0.4, 0.9, 0.0], [0.0, 0.0, 1.0]]) self.g_2D = GaussianDistribution(self.mu_2D, self.C_2D) self.g_3D = GaussianDistribution(self.mu_3D, self.C_3D) - def test_integrate_numerically(self): """Test that the numerical integration of a Gaussian distribution equals 1.""" dist = GaussianDistribution(array([1, 2]), np.diag([1, 2])) integration_result = dist.integrate_numerically() From 673268ccc4dd99b9c7bfb2a52711ec4f88801bf5 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Wed, 18 Oct 2023 14:14:54 +0100 Subject: [PATCH 028/232] More --- .../test_abstract_hyperspherical_distribution.py | 6 +++--- .../test_partially_wrapped_normal_distribution.py | 8 ++++---- .../tests/distributions/test_se3_dirac_distribution.py | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/pyrecest/tests/distributions/test_abstract_hyperspherical_distribution.py b/pyrecest/tests/distributions/test_abstract_hyperspherical_distribution.py index 4af18a61..80f98efb 100644 --- a/pyrecest/tests/distributions/test_abstract_hyperspherical_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hyperspherical_distribution.py @@ -51,8 +51,8 @@ def testUnitSphereSurface(self): def test_mean_direction_numerical(self): """Tests the numerical mean direction calculation.""" - mu = 1 / sqrt(2) * array([1.0, 1.0, 0.0]) - kappa = 10 + mu = 1 / sqrt(2.0) * array([1.0, 1.0, 0.0]) + kappa = 10.0 vmf = VonMisesFisherDistribution(mu, kappa) self.assertLess(linalg.norm(vmf.mean_direction_numerical() - mu), 1e-6) @@ -61,7 +61,7 @@ def test_plotting_error_free_2d(self): mu = array([1.0, 1.0, 2.0]) mu = mu / linalg.norm(mu) - kappa = 10 + kappa = 10.0 vmf = VonMisesFisherDistribution(mu, kappa) vmf.plot() diff --git a/pyrecest/tests/distributions/test_partially_wrapped_normal_distribution.py b/pyrecest/tests/distributions/test_partially_wrapped_normal_distribution.py index 6b33354d..67936030 100644 --- a/pyrecest/tests/distributions/test_partially_wrapped_normal_distribution.py +++ b/pyrecest/tests/distributions/test_partially_wrapped_normal_distribution.py @@ -11,8 +11,8 @@ class TestPartiallyWrappedNormalDistribution(unittest.TestCase): def setUp(self) -> None: - self.mu = array([5, 1]) - self.C = array([[2, 1], [1, 1]]) + self.mu = array([5.0, 1.0]) + self.C = array([[2.0, 1.0], [1.0, 1.0]]) self.dist_2d = PartiallyWrappedNormalDistribution(self.mu, self.C, 1) def test_pdf(self): @@ -22,8 +22,8 @@ def test_hybrid_mean_2d(self): np.testing.assert_allclose(self.dist_2d.hybrid_mean(), self.mu) def test_hybrid_mean_4d(self): - mu = array([5, 1, 3, 4]) - C = array(scipy.linalg.block_diag([[2, 1], [1, 1]], [[2, 1], [1, 1]])) + mu = array([5.0, 1.0, 3.0, 4.0]) + C = array(scipy.linalg.block_diag([[2.0, 1.0], [1.0, 1.0]], [[2.0, 1.0], [1.0, 1.0]])) dist = PartiallyWrappedNormalDistribution(mu, C, 2) np.testing.assert_allclose(dist.hybrid_mean(), mu) diff --git a/pyrecest/tests/distributions/test_se3_dirac_distribution.py b/pyrecest/tests/distributions/test_se3_dirac_distribution.py index a2f1fd9f..a15244dc 100644 --- a/pyrecest/tests/distributions/test_se3_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_se3_dirac_distribution.py @@ -26,9 +26,9 @@ def test_constructor(self): [2, 31, 42, 3, 9.9, 5], ] ).T - dSph = dSph / linalg.norm(dSph, axis=-1, keepdims=True) - dLin = tile(array([-5, 0, 5, 10, 15, 20]), (3, 1)).T - w = array([1, 2, 3, 1, 2, 3]) + dSph = dSph / linalg.norm(dSph, None, -1).reshape(-1, 1) + dLin = tile(array([-5.0, 0.0, 5.0, 10.0, 15.0, 20.0]), (3, 1)).T + w = array([1.0, 2.0, 3.0, 1.0, 2.0, 3.0]) w = w / sum(w) SE3DiracDistribution(concatenate((dSph, dLin), axis=-1), w) From 924f4a1fb60827b2285fd305ee25e83eaf494121 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Wed, 18 Oct 2023 15:00:00 +0100 Subject: [PATCH 029/232] Now using backend-specific diag --- ...ypersphere_cart_prod_dirac_distribution.py | 3 +- ...bstract_hypersphere_subset_distribution.py | 3 +- .../bingham_distribution.py | 11 ++--- .../hypertorus/toroidal_dirac_distribution.py | 3 +- .../nonperiodic/gaussian_distribution.py | 2 +- .../test_abstract_circular_distribution.py | 4 +- ...st_abstract_hyperspherical_distribution.py | 16 +++---- .../test_abstract_linear_distribution.py | 11 ++--- ...t_ellipsoidal_ball_uniform_distribution.py | 3 +- .../distributions/test_linear_mixture.py | 5 ++- .../test_se3_dirac_distribution.py | 3 +- .../filters/test_global_nearest_neighbor.py | 43 ++++++++++--------- pyrecest/tests/filters/test_kalman_filter.py | 13 +++--- .../filters/test_random_matrix_tracker.py | 3 +- 14 files changed, 67 insertions(+), 56 deletions(-) diff --git a/pyrecest/distributions/cart_prod/lin_hypersphere_cart_prod_dirac_distribution.py b/pyrecest/distributions/cart_prod/lin_hypersphere_cart_prod_dirac_distribution.py index 3b0b9bab..121d3a5e 100644 --- a/pyrecest/distributions/cart_prod/lin_hypersphere_cart_prod_dirac_distribution.py +++ b/pyrecest/distributions/cart_prod/lin_hypersphere_cart_prod_dirac_distribution.py @@ -1,5 +1,6 @@ from pyrecest.backend import linalg from pyrecest.backend import abs +from pyrecest.backend import amax import numpy as np from ..abstract_se3_distribution import AbstractSE3Distribution @@ -13,7 +14,7 @@ class LinHypersphereCartProdDiracDistribution( ): def __init__(self, bound_dim, d, w=None): assert ( - np.max(abs(linalg.norm(d[:, : (bound_dim + 1)], axis=-1) - 1)) < 1e-5 + amax(abs(linalg.norm(d[:, : (bound_dim + 1)], None, -1) - 1), 0) < 1e-5 ), "The hypersphere ssubset part of d must be normalized" AbstractSE3Distribution.__init__(self) LinBoundedCartProdDiracDistribution.__init__(self, d, w) diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py index 40da30ce..382abc7d 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py @@ -11,6 +11,7 @@ from pyrecest.backend import int64 from pyrecest.backend import int32 from pyrecest.backend import zeros +from pyrecest.backend import empty from abc import abstractmethod from collections.abc import Callable @@ -41,7 +42,7 @@ def mean_direction_numerical(self, integration_boundaries=None): self.dim ) - mu = np.full(self.dim + 1, np.nan) + mu = empty(self.dim + 1) if 1 <= self.dim <= 3: for i in range(self.dim + 1): diff --git a/pyrecest/distributions/hypersphere_subset/bingham_distribution.py b/pyrecest/distributions/hypersphere_subset/bingham_distribution.py index 63d4f735..4a78ad77 100644 --- a/pyrecest/distributions/hypersphere_subset/bingham_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/bingham_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import diag from pyrecest.backend import linalg from math import pi from pyrecest.backend import sum @@ -66,7 +67,7 @@ def ifun(u): def pdf(self, xs): assert xs.shape[-1] == self.dim + 1 - C = self.M @ np.diag(self.Z) @ self.M.T + C = self.M @ diag(self.Z) @ self.M.T p = 1 / self.F * exp(sum(xs.T * (C @ xs.T), axis=0)) return p @@ -81,8 +82,8 @@ def multiply(self, B2): raise ValueError("Dimensions do not match") C = ( - self.M @ np.diag(self.Z.ravel()) @ self.M.T - + B2.M @ np.diag(B2.Z.ravel()) @ B2.M.T + self.M @ diag(self.Z.ravel()) @ self.M.T + + B2.M @ diag(B2.Z.ravel()) @ B2.M.T ) # New exponent C = 0.5 * (C + C.T) # Symmetrize @@ -124,9 +125,9 @@ def moment(self): Returns: S (numpy.ndarray): scatter/covariance matrix in R^d """ - D = np.diag(self.dF / self.F) + D = diag(self.dF / self.F) # It should already be normalized, but numerical inaccuracies can lead to values unequal to 1 - D = D / sum(np.diag(D)) + D = D / sum(diag(D)) S = self.M @ D @ self.M.T S = (S + S.T) / 2 # Enforce symmetry return S \ No newline at end of file diff --git a/pyrecest/distributions/hypertorus/toroidal_dirac_distribution.py b/pyrecest/distributions/hypertorus/toroidal_dirac_distribution.py index 1a346475..0f2800b5 100644 --- a/pyrecest/distributions/hypertorus/toroidal_dirac_distribution.py +++ b/pyrecest/distributions/hypertorus/toroidal_dirac_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import diag from pyrecest.backend import tile from pyrecest.backend import sum from pyrecest.backend import sqrt @@ -56,6 +57,6 @@ def covariance_4D(self) -> np.ndarray: mu = dot(self.w, dbar) n = len(self.d) C = (dbar - tile(mu, (n, 1))).T @ ( - np.diag(self.w) @ (dbar - tile(mu, (n, 1))) + diag(self.w) @ (dbar - tile(mu, (n, 1))) ) return C \ No newline at end of file diff --git a/pyrecest/distributions/nonperiodic/gaussian_distribution.py b/pyrecest/distributions/nonperiodic/gaussian_distribution.py index d88050d1..7fadac0d 100644 --- a/pyrecest/distributions/nonperiodic/gaussian_distribution.py +++ b/pyrecest/distributions/nonperiodic/gaussian_distribution.py @@ -26,7 +26,7 @@ def __init__(self, mu: np.ndarray, C: np.ndarray, check_validity=True): assert C > 0, "C must be positive definite" elif self.dim == 2: assert ( - C[0, 0] > 0 and linalg.det(C) > 0 + C[0, 0] > 0.0 and linalg.det(C) > 0.0 ), "C must be positive definite" else: cholesky(C) # Will fail if C is not positive definite diff --git a/pyrecest/tests/distributions/test_abstract_circular_distribution.py b/pyrecest/tests/distributions/test_abstract_circular_distribution.py index fba77216..0d145c5d 100644 --- a/pyrecest/tests/distributions/test_abstract_circular_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_circular_distribution.py @@ -12,8 +12,8 @@ class AbstractCircularDistributionTest(unittest.TestCase): def setUp(self): self.distributions = [ - WrappedNormalDistribution(2.0, 0.7), - VonMisesDistribution(6.0, 1.2), + WrappedNormalDistribution(array(2.0), array(0.7)), + VonMisesDistribution(array(6.0), array(1.2)), ] def test_cdf_numerical(self): diff --git a/pyrecest/tests/distributions/test_abstract_hyperspherical_distribution.py b/pyrecest/tests/distributions/test_abstract_hyperspherical_distribution.py index 80f98efb..f8318567 100644 --- a/pyrecest/tests/distributions/test_abstract_hyperspherical_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hyperspherical_distribution.py @@ -19,39 +19,39 @@ def testIntegral2D(self): """Tests the integral calculation in 2D.""" mu = array([1.0, 1.0, 2.0]) mu = mu / linalg.norm(mu) - kappa = 10 + kappa = 10.0 vmf = VonMisesFisherDistribution(mu, kappa) - self.assertAlmostEqual(vmf.integrate(), 1, delta=1e-8) + self.assertAlmostEqual(vmf.integrate(), 1.0, delta=1e-8) def testIntegral3D(self): """Tests the integral calculation in 3D.""" mu = array([1.0, 1.0, 2.0, 2.0]) mu = mu / linalg.norm(mu) - kappa = 10 + kappa = 10.0 vmf = VonMisesFisherDistribution(mu, kappa) - self.assertAlmostEqual(vmf.integrate(), 1, delta=1e-7) + self.assertAlmostEqual(vmf.integrate(), 1.0, delta=1e-7) def testUnitSphereSurface(self): """Tests the unit sphere surface computation.""" self.assertAlmostEqual( AbstractHypersphericalDistribution.compute_unit_hypersphere_surface(1), - 2 * pi, + 2.0 * pi, delta=1e-10, ) self.assertAlmostEqual( AbstractHypersphericalDistribution.compute_unit_hypersphere_surface(2), - 4 * pi, + 4.0 * pi, delta=1e-10, ) self.assertAlmostEqual( AbstractHypersphericalDistribution.compute_unit_hypersphere_surface(3), - 2 * pi**2, + 2.0 * pi**2, delta=1e-10, ) def test_mean_direction_numerical(self): """Tests the numerical mean direction calculation.""" - mu = 1 / sqrt(2.0) * array([1.0, 1.0, 0.0]) + mu = 1.0 / sqrt(2.0) * array([1.0, 1.0, 0.0]) kappa = 10.0 vmf = VonMisesFisherDistribution(mu, kappa) self.assertLess(linalg.norm(vmf.mean_direction_numerical() - mu), 1e-6) diff --git a/pyrecest/tests/distributions/test_abstract_linear_distribution.py b/pyrecest/tests/distributions/test_abstract_linear_distribution.py index 63d6586f..f718c634 100644 --- a/pyrecest/tests/distributions/test_abstract_linear_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_linear_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import diag from pyrecest.backend import squeeze from pyrecest.backend import isclose from pyrecest.backend import array @@ -24,14 +25,14 @@ def setUp(self): self.g_3D = GaussianDistribution(self.mu_3D, self.C_3D) """Test that the numerical integration of a Gaussian distribution equals 1.""" - dist = GaussianDistribution(array([1, 2]), np.diag([1, 2])) + dist = GaussianDistribution(array([1.0, 2.0]), diag([1.0, 2.0])) integration_result = dist.integrate_numerically() assert isclose( integration_result, 1, rtol=1e-5 ), f"Expected 1, but got {integration_result}" def test_integrate_fun_over_domain(self): - dist = GaussianDistribution(array([1, 2]), np.diag([1, 2])) + dist = GaussianDistribution(array([1.0, 2.0]), diag([1.0, 2.0])) def f(x): return 0.3 * dist.pdf(x) @@ -50,7 +51,7 @@ def f(x): def test_mode_numerical_custom_1D(self): cd = CustomLinearDistribution( lambda x: squeeze( - ((x > -1) & (x <= 0)) * (1 + x) + ((x > 0) & (x <= 1)) * (1 - x) + ((x > -1.0) & (x <= 0.0)) * (1.0 + x) + ((x > 0.0) & (x <= 1.0)) * (1 - x) ), 1, ) @@ -61,8 +62,8 @@ def test_mean_numerical_gaussian_2D(self): np.testing.assert_allclose(self.g_2D.mean_numerical(), self.mu_2D, atol=1e-6) def test_mode_numerical_gaussian_2D_mean_far_away(self): - mu = array([5, 10]) - C = array([[2, 1], [1, 1]]) + mu = array([5.0, 10.0]) + C = array([[2.0, 1.0], [1.0, 1.0]]) g = GaussianDistribution(mu, C) np.testing.assert_allclose(g.mode_numerical(), mu, atol=2e-4) diff --git a/pyrecest/tests/distributions/test_ellipsoidal_ball_uniform_distribution.py b/pyrecest/tests/distributions/test_ellipsoidal_ball_uniform_distribution.py index 82f6ebe3..d41e0912 100644 --- a/pyrecest/tests/distributions/test_ellipsoidal_ball_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_ellipsoidal_ball_uniform_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import diag from pyrecest.backend import array import unittest @@ -8,7 +9,7 @@ class TestEllipsoidalBallUniformDistribution(unittest.TestCase): def test_pdf(self): dist = EllipsoidalBallUniformDistribution( - array([0, 0, 0]), np.diag([4, 9, 16]) + array([0, 0, 0]), diag([4, 9, 16]) ) self.assertAlmostEqual(dist.pdf(array([0, 0, 0])), 1 / 100.53096491) diff --git a/pyrecest/tests/distributions/test_linear_mixture.py b/pyrecest/tests/distributions/test_linear_mixture.py index 0f764856..7b441d78 100644 --- a/pyrecest/tests/distributions/test_linear_mixture.py +++ b/pyrecest/tests/distributions/test_linear_mixture.py @@ -1,3 +1,4 @@ +from pyrecest.backend import diag from pyrecest.backend import meshgrid from pyrecest.backend import linspace from pyrecest.backend import array @@ -28,8 +29,8 @@ def test_constructor_warning(self): ) def test_pdf(self): - gm1 = GaussianDistribution(array([1, 1]), np.diag([2, 3])) - gm2 = GaussianDistribution(-array([3, 1]), np.diag([2, 3])) + gm1 = GaussianDistribution(array([1, 1]), diag([2, 3])) + gm2 = GaussianDistribution(-array([3, 1]), diag([2, 3])) with catch_warnings(): simplefilter("ignore", category=UserWarning) diff --git a/pyrecest/tests/distributions/test_se3_dirac_distribution.py b/pyrecest/tests/distributions/test_se3_dirac_distribution.py index a15244dc..a934ce90 100644 --- a/pyrecest/tests/distributions/test_se3_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_se3_dirac_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import diag from pyrecest.backend import linalg from pyrecest.backend import tile from pyrecest.backend import sum @@ -36,7 +37,7 @@ def test_from_distribution(self): cpsd = SE3CartProdStackedDistribution( [ HyperhemisphericalUniformDistribution(3), - GaussianDistribution(array([1, 2, 3]).T, np.diag([3, 2, 1])), + GaussianDistribution(array([1, 2, 3]).T, diag([3, 2, 1])), ] ) SE3DiracDistribution.from_distribution(cpsd, 100) diff --git a/pyrecest/tests/filters/test_global_nearest_neighbor.py b/pyrecest/tests/filters/test_global_nearest_neighbor.py index 5b3859ba..983c407c 100644 --- a/pyrecest/tests/filters/test_global_nearest_neighbor.py +++ b/pyrecest/tests/filters/test_global_nearest_neighbor.py @@ -4,6 +4,7 @@ from pyrecest.backend import array from pyrecest.backend import allclose from pyrecest.backend import all, zeros +from pyrecest.backend import diag import unittest import numpy as np @@ -20,25 +21,25 @@ class GlobalNearestNeighborTest(unittest.TestCase): def setUp(self): """Initialize test variables before each test is run.""" self.kfs_init = [ - KalmanFilter(GaussianDistribution(zeros(4), np.diag([1, 2, 3, 4]))), + KalmanFilter(GaussianDistribution(zeros(4), diag([1.0, 2.0, 3.0, 4.0]))), KalmanFilter( - GaussianDistribution(array([1, 2, 3, 4]), np.diag([2, 2, 2, 2])) + GaussianDistribution(array([1.0, 2.0, 3.0, 4.0]), diag([2.0, 2.0, 2.0, 2.0])) ), KalmanFilter( - GaussianDistribution(-array([1, 2, 3, 4]), np.diag([4, 3, 2, 1])) + GaussianDistribution(-array([1.0, 2.0, 3.0, 4.0]), diag([4.0, 3.0, 2.0, 1.0])) ), ] - self.meas_mat = array([[1, 0, 0, 0], [0, 0, 1, 0]]) - self.sys_mat = scipy.linalg.block_diag([[1, 1], [0, 1]], [[1, 1], [0, 1]]) + self.meas_mat = array([[1.0, 0.0, 0.0, 0.0], [0.0, 0.0, 1.0, 0.0]]) + self.sys_mat = scipy.linalg.block_diag([[1.0, 1.0], [0.0, 1.0]], [[1.0, 1.0], [0.0, 1.0]]) self.all_different_meas_covs = np.dstack( [ - np.diag([1, 2]), + diag([1.0, 2.0]), array([[5, 0.1], [0.1, 3]]), array([[2, -0.5], [-0.5, 0.5]]), ] ) self.all_different_meas_covs_4 = np.dstack( - (self.all_different_meas_covs, array([[2, -0.5], [-0.5, 0.5]])) + (self.all_different_meas_covs, array([[2.0, -0.5], [-0.5, 0.5]])) ) def test_set_state_sets_correct_state(self): @@ -57,13 +58,13 @@ def test_get_state_returns_correct_shape(self): self.assertEqual(tracker.get_point_estimate(True).shape, (12,)) @parameterized.expand( - [("no_inputs", zeros(4)), ("with_inputs", array([1, -1, 1, -1]))] + [("no_inputs", zeros(4)), ("with_inputs", array([1.0, -1.0, 1.0, -1.0]))] ) def test_predict_linear(self, name, sys_input): C_matrices = [ - scipy.linalg.block_diag([[3, 2], [2, 2]], [[7, 4], [4, 4]]) + eye(4), - scipy.linalg.block_diag([[4, 2], [2, 2]], [[4, 2], [2, 2]]) + eye(4), - scipy.linalg.block_diag([[7, 3], [3, 3]], [[3, 1], [1, 1]]) + eye(4), + scipy.linalg.block_diag([[3.0, 2.0], [2.0, 2.0]], [[7.0, 4.0], [4.0, 4.0]]) + eye(4), + scipy.linalg.block_diag([[4.0, 2.0], [2.0, 2.0]], [[4.0, 2.0], [2.0, 2.0]]) + eye(4), + scipy.linalg.block_diag([[7.0, 3.0], [3.0, 3.0]], [[3.0, 1.0], [1.0, 1.0]]) + eye(4), ] tracker = GlobalNearestNeighbor() @@ -89,37 +90,37 @@ def test_predict_linear_different_mats_and_inputs(self): sys_mats = np.dstack( ( - scipy.linalg.block_diag([[1, 1], [0, 1]], [[1, 1], [0, 1]]), + scipy.linalg.block_diag([[1.0, 1.0], [0.0, 1.0]], [[1.0, 1.0], [0.0, 1.0]]), eye(4), - array([[0, 0, 1, 1], [0, 0, 0, 1], [1, 1, 0, 0], [0, 1, 0, 0]]), + array([[0.0, 0.0, 1.0, 1.0], [0.0, 0.0, 0.0, 1.0], [1.0, 1.0, 0.0, 0.0], [0.0, 1.0, 0.0, 0.0]]), ) ) sys_noises = np.dstack( - (eye(4), np.diag([10, 11, 12, 13]), np.diag([1, 5, 3, 5])) + (eye(4), diag([10.0, 11.0, 12.0, 13.0]), diag([1.0, 5.0, 3.0, 5.0])) ) - sys_inputs = array([[-1, 1, -1, 1], [1, 2, 3, 4], -array([4, 3, 2, 1])]).T + sys_inputs = array([[-1.0, 1.0, -1.0, 1.0], [1.0, 2.0, 3.0, 4.0], -array([4.0, 3.0, 2.0, 1.0])]).T tracker.predict_linear(sys_mats, sys_noises, sys_inputs) np.testing.assert_array_equal( - tracker.filter_bank[0].filter_state.mu, array([-1, 1, -1, 1]) + tracker.filter_bank[0].filter_state.mu, array([-1.0, 1.0, -1.0, 1.0]) ) np.testing.assert_array_equal( - tracker.filter_bank[1].filter_state.mu, array([2, 4, 6, 8]) + tracker.filter_bank[1].filter_state.mu, array([2.0, 4.0, 6.0, 8.0]) ) np.testing.assert_array_equal( - tracker.filter_bank[2].filter_state.mu, array([-11, -7, -5, -3]) + tracker.filter_bank[2].filter_state.mu, array([-11.0, -7.0, -5.0, -3.0]) ) np.testing.assert_array_equal( tracker.filter_bank[0].filter_state.C, - scipy.linalg.block_diag([[4, 2], [2, 3]], [[8, 4], [4, 5]]), + scipy.linalg.block_diag([[4.0, 2.0], [2.0, 3.0]], [[8.0, 4.0], [4.0, 5.0]]), ) np.testing.assert_array_equal( - tracker.filter_bank[1].filter_state.C, np.diag([12, 13, 14, 15]) + tracker.filter_bank[1].filter_state.C, diag([12.0, 13.0, 14.0, 15.0]) ) np.testing.assert_array_equal( tracker.filter_bank[2].filter_state.C, - scipy.linalg.block_diag([[4, 1], [1, 6]], [[10, 3], [3, 8]]), + scipy.linalg.block_diag([[4.0, 1.0], [1.0, 6.0]], [[10.0, 3.0], [3.0, 8.0]]), ) def test_association_no_clutter(self): diff --git a/pyrecest/tests/filters/test_kalman_filter.py b/pyrecest/tests/filters/test_kalman_filter.py index 1d075222..c084f382 100644 --- a/pyrecest/tests/filters/test_kalman_filter.py +++ b/pyrecest/tests/filters/test_kalman_filter.py @@ -1,3 +1,4 @@ +from pyrecest.backend import diag from pyrecest.backend import eye from pyrecest.backend import array from pyrecest.backend import allclose @@ -33,9 +34,9 @@ def test_update_with_meas_noise_and_meas_1d(self): self.assertEqual(kf.get_point_estimate(), 2) def test_update_linear_2d(self): - filter_add = KalmanFilter((array([0, 1]), np.diag([1, 2]))) + filter_add = KalmanFilter((array([0, 1]), diag([1, 2]))) filter_id = copy.deepcopy(filter_add) - gauss = GaussianDistribution(array([1, 0]), np.diag([2, 1])) + gauss = GaussianDistribution(array([1, 0]), diag([2, 1])) filter_add.update_linear(gauss.mu, eye(2), gauss.C) filter_id.update_identity(gauss.C, gauss.mu) self.assertTrue( @@ -52,11 +53,11 @@ def test_predict_identity_1d(self): self.assertEqual(kf.filter_state.C, 4) def test_predict_linear_2d(self): - kf = KalmanFilter((array([0, 1]), np.diag([1, 2]))) - kf.predict_linear(np.diag([1, 2]), np.diag([2, 1])) + kf = KalmanFilter((array([0, 1]), diag([1, 2]))) + kf.predict_linear(diag([1, 2]), diag([2, 1])) self.assertTrue(allclose(kf.get_point_estimate(), array([0, 2]))) - self.assertTrue(allclose(kf.filter_state.C, np.diag([3, 9]))) - kf.predict_linear(np.diag([1, 2]), np.diag([2, 1]), array([2, -2])) + self.assertTrue(allclose(kf.filter_state.C, diag([3, 9]))) + kf.predict_linear(diag([1, 2]), diag([2, 1]), array([2, -2])) self.assertTrue(allclose(kf.get_point_estimate(), array([2, 2]))) diff --git a/pyrecest/tests/filters/test_random_matrix_tracker.py b/pyrecest/tests/filters/test_random_matrix_tracker.py index 0bdaa612..6347672a 100644 --- a/pyrecest/tests/filters/test_random_matrix_tracker.py +++ b/pyrecest/tests/filters/test_random_matrix_tracker.py @@ -1,3 +1,4 @@ +from pyrecest.backend import diag from pyrecest.backend import linalg from pyrecest.backend import mean from pyrecest.backend import eye @@ -128,7 +129,7 @@ def test_draw_extent_3d(self, mock_show): self.tracker = RandomMatrixTracker( zeros(3), eye(3), - np.diag([1, 2, 3]), + diag([1, 2, 3]), kinematic_state_to_pos_matrix=eye(3), ) self.tracker.plot_point_estimate() From 68406f7185f276f619feddd012f77b407056816a Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Wed, 18 Oct 2023 15:04:32 +0100 Subject: [PATCH 030/232] More --- .../cart_prod/abstract_hypercylindrical_distribution.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py b/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py index c2652304..7b91c6ce 100644 --- a/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py +++ b/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py @@ -163,7 +163,7 @@ def condition_on_linear(self, input_lin, normalize=True): The distribution after conditioning. """ assert ( - input_lin.shape[0] == self.lin_dim and ndim(input_lin) <= 1 + input_lin.ndim == 0 and self.lin_dim == 1 or ndim(input_lin) == 1 and input_lin.shape[0] == self.lin_dim ), "Input should be of size (lin_dim,)." def f_cond_unnorm(x, input_lin=input_lin): From 549d02fd2991883186d80f94fcecbc575fd16989 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Wed, 18 Oct 2023 15:17:41 +0100 Subject: [PATCH 031/232] More --- pyrecest/distributions/abstract_custom_distribution.py | 2 ++ .../hypertorus/hypertoroidal_wrapped_normal_distribution.py | 4 ++-- .../test_abstract_hypercylindrical_distribution.py | 3 +++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/pyrecest/distributions/abstract_custom_distribution.py b/pyrecest/distributions/abstract_custom_distribution.py index c8ea0d60..4a5cda3f 100644 --- a/pyrecest/distributions/abstract_custom_distribution.py +++ b/pyrecest/distributions/abstract_custom_distribution.py @@ -2,6 +2,7 @@ import warnings from abc import abstractmethod from collections.abc import Callable +import pyrecest.backend import numpy as np from beartype import beartype @@ -61,6 +62,7 @@ def normalize(self, verify: bool | None = None) -> "AbstractCustomDistribution": :param verify: Whether to verify if the density is properly normalized, default is None. :returns: A copy of the original distribution, with the PDF normalized. """ + assert pyrecest.backend.__name__ == 'pyrecest.numpy', "Only supported for numpy backend" cd = copy.deepcopy(self) integral = self.integrate() diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py b/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py index 7f14e7bd..c635570a 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py @@ -30,9 +30,9 @@ def __init__(self, mu: np.ndarray, C: np.ndarray): :param C: Covariance matrix. :raises AssertionError: If C_ is not square, not symmetric, not positive definite, or its dimension does not match with mu_. """ - assert C.shape[0] == C.shape[1], "C must be dim x dim" + assert C.ndim == 0 or C.ndim == 2 and C.shape[0] == C.shape[1], "C must be dim x dim" assert allclose(C, C.T, atol=1e-8), "C must be symmetric" - assert ( + assert (C.ndim == 0 and C > 0.0 or linalg.cholesky(C) # fails if not positiv definite ), "C must be positive definite" assert ( diff --git a/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py b/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py index 888af027..cd94af7b 100644 --- a/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py @@ -6,6 +6,7 @@ from pyrecest.backend import all from pyrecest.backend import zeros import unittest +import pyrecest.backend import numpy as np from pyrecest.distributions.cart_prod.partially_wrapped_normal_distribution import ( @@ -26,6 +27,7 @@ def test_linear_mean_numerical(self): ) np.testing.assert_allclose(hwn.linear_mean_numerical(), hwn.mu[-1]) + @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") def test_condition_on_periodic(self): hwn = PartiallyWrappedNormalDistribution( array([1, 2]), array([[2, 0.3], [0.3, 1]]), 1 @@ -50,6 +52,7 @@ def test_condition_on_periodic(self): atol=1e-10, ) + @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") def test_condition_on_linear(self): hwn = PartiallyWrappedNormalDistribution( array([1, 2]), array([[2, 0.3], [0.3, 1]]), 1 From 100364e012bf027f545c84a7d9ffd36ac52124a0 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Wed, 18 Oct 2023 15:25:10 +0100 Subject: [PATCH 032/232] More --- pyrecest/distributions/abstract_dirac_distribution.py | 2 +- pyrecest/evaluation/eot_shape_database.py | 2 +- .../test_ellipsoidal_ball_uniform_distribution.py | 4 ++-- .../test_hyperhemispherical_uniform_distribution.py | 2 +- pyrecest/tests/filters/test_global_nearest_neighbor.py | 4 ++-- pyrecest/tests/test_eot_shape_database.py | 2 +- pyrecest/tests/test_evaluation_basic.py | 1 - 7 files changed, 8 insertions(+), 9 deletions(-) diff --git a/pyrecest/distributions/abstract_dirac_distribution.py b/pyrecest/distributions/abstract_dirac_distribution.py index 64776e61..2325abb3 100644 --- a/pyrecest/distributions/abstract_dirac_distribution.py +++ b/pyrecest/distributions/abstract_dirac_distribution.py @@ -33,7 +33,7 @@ def __init__(self, d: np.ndarray, w: np.ndarray | None = None): if w is None: w = ones(d.shape[0]) / d.shape[0] - assert d.shape[0] == np.size(w), "Number of Diracs and weights must match." + assert d.shape[0] == w.shape[0], "Number of Diracs and weights must match." self.d = copy.copy(d) self.w = copy.copy(w) self.normalize_in_place() diff --git a/pyrecest/evaluation/eot_shape_database.py b/pyrecest/evaluation/eot_shape_database.py index 9d84841c..efc7a5ed 100644 --- a/pyrecest/evaluation/eot_shape_database.py +++ b/pyrecest/evaluation/eot_shape_database.py @@ -172,7 +172,7 @@ def __new__(cls, height_1, height_2, width_1, width_2, centroid=None): # Use a default centroid if none is provided if centroid is None: - centroid = [0, 0] + centroid = array([0, 0]) # Calculate half dimensions for clarity half_height_1 = height_1 / 2 diff --git a/pyrecest/tests/distributions/test_ellipsoidal_ball_uniform_distribution.py b/pyrecest/tests/distributions/test_ellipsoidal_ball_uniform_distribution.py index d41e0912..3a2e5507 100644 --- a/pyrecest/tests/distributions/test_ellipsoidal_ball_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_ellipsoidal_ball_uniform_distribution.py @@ -9,9 +9,9 @@ class TestEllipsoidalBallUniformDistribution(unittest.TestCase): def test_pdf(self): dist = EllipsoidalBallUniformDistribution( - array([0, 0, 0]), diag([4, 9, 16]) + array([0.0, 0.0, 0.0]), diag(array([4.0, 9.0, 16.0])) ) - self.assertAlmostEqual(dist.pdf(array([0, 0, 0])), 1 / 100.53096491) + self.assertAlmostEqual(dist.pdf(array([0.0, 0.0, 0.0])), 1 / 100.53096491) def test_sampling(self): dist = EllipsoidalBallUniformDistribution( diff --git a/pyrecest/tests/distributions/test_hyperhemispherical_uniform_distribution.py b/pyrecest/tests/distributions/test_hyperhemispherical_uniform_distribution.py index 40b931e4..434f1a87 100644 --- a/pyrecest/tests/distributions/test_hyperhemispherical_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_hyperhemispherical_uniform_distribution.py @@ -14,7 +14,7 @@ def get_random_points(n, d): random.seed(10) - points = random.randn(n, d + 1) + points = random.normal(n, d + 1) points = points[points[:, -1] >= 0, :] points /= reshape(linalg.norm(points, axis=1), (-1, 1)) return points diff --git a/pyrecest/tests/filters/test_global_nearest_neighbor.py b/pyrecest/tests/filters/test_global_nearest_neighbor.py index 983c407c..68565a30 100644 --- a/pyrecest/tests/filters/test_global_nearest_neighbor.py +++ b/pyrecest/tests/filters/test_global_nearest_neighbor.py @@ -34,8 +34,8 @@ def setUp(self): self.all_different_meas_covs = np.dstack( [ diag([1.0, 2.0]), - array([[5, 0.1], [0.1, 3]]), - array([[2, -0.5], [-0.5, 0.5]]), + array([[5.0, 0.1], [0.1, 3.0]]), + array([[2.0, -0.5], [-0.5, 0.5]]), ] ) self.all_different_meas_covs_4 = np.dstack( diff --git a/pyrecest/tests/test_eot_shape_database.py b/pyrecest/tests/test_eot_shape_database.py index 2c4d8ad1..141a9adc 100644 --- a/pyrecest/tests/test_eot_shape_database.py +++ b/pyrecest/tests/test_eot_shape_database.py @@ -40,7 +40,7 @@ def test_compute_kernel_star_convex(self): class TestCross(unittest.TestCase): def setUp(self) -> None: - self.cross_full = Cross(2, 1, 2, 3) + self.cross_full = Cross(2.0, 1.0, 2.0, 3.0) self.cross_kernel = self.cross_full.compute_kernel() def test_area(self): diff --git a/pyrecest/tests/test_evaluation_basic.py b/pyrecest/tests/test_evaluation_basic.py index 01c5e598..f54668da 100644 --- a/pyrecest/tests/test_evaluation_basic.py +++ b/pyrecest/tests/test_evaluation_basic.py @@ -227,7 +227,6 @@ def test_configure_kf(self): self.assertIsInstance(configured_filter, KalmanFilter) self.assertIsNotNone(predictionRoutine) - self.assertIsInstance(meas_noise_for_filter, np.ndarray) def test_configure_pf(self): filter_config = {"name": "pf", "parameter": 100} From 5254d8ad5cf67870ce916c0463b2bfa54620513f Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Wed, 18 Oct 2023 15:29:17 +0100 Subject: [PATCH 033/232] More.... --- .../test_hyperhemispherical_uniform_distribution.py | 2 +- pyrecest/tests/filters/test_global_nearest_neighbor.py | 2 +- pyrecest/tests/filters/test_random_matrix_tracker.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pyrecest/tests/distributions/test_hyperhemispherical_uniform_distribution.py b/pyrecest/tests/distributions/test_hyperhemispherical_uniform_distribution.py index 434f1a87..b6678aa7 100644 --- a/pyrecest/tests/distributions/test_hyperhemispherical_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_hyperhemispherical_uniform_distribution.py @@ -14,7 +14,7 @@ def get_random_points(n, d): random.seed(10) - points = random.normal(n, d + 1) + points = random.normal(0.0, 1.0, (n, d+1)) points = points[points[:, -1] >= 0, :] points /= reshape(linalg.norm(points, axis=1), (-1, 1)) return points diff --git a/pyrecest/tests/filters/test_global_nearest_neighbor.py b/pyrecest/tests/filters/test_global_nearest_neighbor.py index 68565a30..1e5f2ac6 100644 --- a/pyrecest/tests/filters/test_global_nearest_neighbor.py +++ b/pyrecest/tests/filters/test_global_nearest_neighbor.py @@ -21,7 +21,7 @@ class GlobalNearestNeighborTest(unittest.TestCase): def setUp(self): """Initialize test variables before each test is run.""" self.kfs_init = [ - KalmanFilter(GaussianDistribution(zeros(4), diag([1.0, 2.0, 3.0, 4.0]))), + KalmanFilter(GaussianDistribution(zeros(4), diag(array([1.0, 2.0, 3.0, 4.0])))), KalmanFilter( GaussianDistribution(array([1.0, 2.0, 3.0, 4.0]), diag([2.0, 2.0, 2.0, 2.0])) ), diff --git a/pyrecest/tests/filters/test_random_matrix_tracker.py b/pyrecest/tests/filters/test_random_matrix_tracker.py index 6347672a..bb4a82f7 100644 --- a/pyrecest/tests/filters/test_random_matrix_tracker.py +++ b/pyrecest/tests/filters/test_random_matrix_tracker.py @@ -129,7 +129,7 @@ def test_draw_extent_3d(self, mock_show): self.tracker = RandomMatrixTracker( zeros(3), eye(3), - diag([1, 2, 3]), + diag(array([1.0, 2.0, 3.0])), kinematic_state_to_pos_matrix=eye(3), ) self.tracker.plot_point_estimate() From 35c93a0dbb05609ca053b2795bf94c160043645e Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Wed, 18 Oct 2023 15:37:08 +0100 Subject: [PATCH 034/232] More --- ..._hypersphere_subset_uniform_distribution.py | 3 ++- .../test_gaussian_distribution.py | 18 +++++++++--------- .../filters/test_global_nearest_neighbor.py | 2 +- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_uniform_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_uniform_distribution.py index fb2c04f6..c281c320 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_uniform_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_uniform_distribution.py @@ -32,5 +32,6 @@ def pdf(self, xs: np.ndarray) -> np.ndarray: raise ValueError("Manifold size cannot be zero.") if not isinstance(manifold_size, (int, float)): raise TypeError("Manifold size must be a numeric value.") - p = (1 / manifold_size) * ones(xs.size // (self.dim + 1)) + p = (1 / manifold_size) * ones(xs.shape[0]) if xs.ndim > 1 else 1 / manifold_size + return p \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_gaussian_distribution.py b/pyrecest/tests/distributions/test_gaussian_distribution.py index 177a7720..5883975a 100644 --- a/pyrecest/tests/distributions/test_gaussian_distribution.py +++ b/pyrecest/tests/distributions/test_gaussian_distribution.py @@ -12,15 +12,15 @@ class GaussianDistributionTest(unittest.TestCase): def test_gaussian_distribution_3d(self): - mu = array([2, 3, 4]) - C = array([[1.1, 0.4, 0], [0.4, 0.9, 0], [0, 0, 0.1]]) + mu = array([2.0, 3.0, 4.0]) + C = array([[1.1, 0.4, 0.0], [0.4, 0.9, 0.0], [0.0, 0.0, 0.1]]) g = GaussianDistribution(mu, C) xs = array( [ - [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5], - [-3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7], - [-2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8], + [-5.0, -4.0, -3.0, -2.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0], + [-3.0, -2.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0], + [-2.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0], ] ).T self.assertTrue( @@ -38,15 +38,15 @@ def test_gaussian_distribution_3d(self): ) def test_mode(self): - mu = array([1, 2, 3]) - C = array([[1.1, 0.4, 0], [0.4, 0.9, 0], [0, 0, 1]]) + mu = array([1.0, 2.0, 3.0]) + C = array([[1.1, 0.4, 0.0], [0.4, 0.9, 0.0], [0.0, 0.0, 1.0]]) g = GaussianDistribution(mu, C) self.assertTrue(allclose(g.mode(), mu, atol=1e-6)) def test_shift(self): - mu = array([3, 2, 1]) - C = array([[1.1, -0.4, 0], [-0.4, 0.9, 0], [0, 0, 1]]) + mu = array([3.0, 2.0, 1.0]) + C = array([[1.1, -0.4, 0.00], [-0.4, 0.9, 0.0], [0.0, 0.0, 1.0]]) g = GaussianDistribution(mu, C) shift_by = array([2, -2, 3]) diff --git a/pyrecest/tests/filters/test_global_nearest_neighbor.py b/pyrecest/tests/filters/test_global_nearest_neighbor.py index 1e5f2ac6..0b499715 100644 --- a/pyrecest/tests/filters/test_global_nearest_neighbor.py +++ b/pyrecest/tests/filters/test_global_nearest_neighbor.py @@ -23,7 +23,7 @@ def setUp(self): self.kfs_init = [ KalmanFilter(GaussianDistribution(zeros(4), diag(array([1.0, 2.0, 3.0, 4.0])))), KalmanFilter( - GaussianDistribution(array([1.0, 2.0, 3.0, 4.0]), diag([2.0, 2.0, 2.0, 2.0])) + GaussianDistribution(array([1.0, 2.0, 3.0, 4.0]), diag(array([2.0, 2.0, 2.0, 2.0]))) ), KalmanFilter( GaussianDistribution(-array([1.0, 2.0, 3.0, 4.0]), diag([4.0, 3.0, 2.0, 1.0])) From 7c9d979cd2b7b010d9894cb51eeb45d95a97d0e7 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Wed, 18 Oct 2023 15:44:11 +0100 Subject: [PATCH 035/232] More --- pyrecest/utils/plotting.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pyrecest/utils/plotting.py b/pyrecest/utils/plotting.py index 0142f2da..642145e0 100644 --- a/pyrecest/utils/plotting.py +++ b/pyrecest/utils/plotting.py @@ -9,6 +9,7 @@ from pyrecest.backend import linspace from pyrecest.backend import cos from pyrecest.backend import array +from pyrecest.backend import complex64 import matplotlib.pyplot as plt import numpy as np @@ -40,7 +41,7 @@ def plot_ellipsoid_3d(center, shape_matrix, scaling_factor=1, color="blue"): V, D = linalg.eig(shape_matrix) all_coords = V @ sqrt(D) @ array( - [x.ravel(), y.ravel(), z.ravel()] + [x.ravel(), y.ravel(), z.ravel()], dtype=complex64 ) + center.reshape(-1, 1) x = reshape(all_coords[0], x.shape) y = reshape(all_coords[1], y.shape) From 37fab2fc9d1ed252b7febbe9afc9dac87e91dafd Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Wed, 18 Oct 2023 15:46:28 +0100 Subject: [PATCH 036/232] More.... --- .../test_ellipsoidal_ball_uniform_distribution.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pyrecest/tests/distributions/test_ellipsoidal_ball_uniform_distribution.py b/pyrecest/tests/distributions/test_ellipsoidal_ball_uniform_distribution.py index 3a2e5507..2b549cde 100644 --- a/pyrecest/tests/distributions/test_ellipsoidal_ball_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_ellipsoidal_ball_uniform_distribution.py @@ -11,15 +11,15 @@ def test_pdf(self): dist = EllipsoidalBallUniformDistribution( array([0.0, 0.0, 0.0]), diag(array([4.0, 9.0, 16.0])) ) - self.assertAlmostEqual(dist.pdf(array([0.0, 0.0, 0.0])), 1 / 100.53096491) + np.testing.assert_allclose(dist.pdf(array([0.0, 0.0, 0.0])), 1 / 100.53096491) def test_sampling(self): dist = EllipsoidalBallUniformDistribution( - array([2, 3]), array([[4, 3], [3, 9]]) + array([2.0, 3.0]), array([[4.0, 3.0], [3.0, 9.0]]) ) samples = dist.sample(10) self.assertEqual(samples.shape[-1], dist.dim) - self.assertEqual(samples.shape[0], 10) + self.assertEqual(samples.shape[0], 10.0) p = dist.pdf(samples) self.assertTrue(all(p == p[0])) From b8aa8bc4bcaa003ec36f7dfc60339e5dd38417c3 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Wed, 18 Oct 2023 15:57:37 +0100 Subject: [PATCH 037/232] More. --- pyrecest/distributions/abstract_dirac_distribution.py | 2 +- .../ellipsoidal_ball_uniform_distribution.py | 4 ++-- .../hyperspherical_uniform_distribution.py | 4 ++-- .../distributions/nonperiodic/gaussian_distribution.py | 2 +- .../tests/distributions/test_gaussian_distribution.py | 2 +- .../tests/distributions/test_se3_dirac_distribution.py | 2 +- pyrecest/tests/filters/test_euclidean_particle_filter.py | 6 +++--- pyrecest/tests/filters/test_global_nearest_neighbor.py | 6 +++--- pyrecest/tests/filters/test_random_matrix_tracker.py | 8 ++++---- pyrecest/tests/test_evaluation_basic.py | 2 +- pyrecest/utils/plotting.py | 2 +- 11 files changed, 20 insertions(+), 20 deletions(-) diff --git a/pyrecest/distributions/abstract_dirac_distribution.py b/pyrecest/distributions/abstract_dirac_distribution.py index 2325abb3..a81cbad3 100644 --- a/pyrecest/distributions/abstract_dirac_distribution.py +++ b/pyrecest/distributions/abstract_dirac_distribution.py @@ -42,7 +42,7 @@ def normalize_in_place(self): """ Normalize the weights in-place to ensure they sum to 1. """ - if not isclose(sum(self.w), 1, atol=1e-10): + if not isclose(sum(self.w), 1.0, atol=1e-10): warnings.warn("Weights are not normalized.", RuntimeWarning) self.w = self.w / sum(self.w) diff --git a/pyrecest/distributions/ellipsoidal_ball_uniform_distribution.py b/pyrecest/distributions/ellipsoidal_ball_uniform_distribution.py index ada91911..da921d89 100644 --- a/pyrecest/distributions/ellipsoidal_ball_uniform_distribution.py +++ b/pyrecest/distributions/ellipsoidal_ball_uniform_distribution.py @@ -74,8 +74,8 @@ def sample(self, n: Union[int, int32, int64]) -> np.ndarray: :param n: Number of samples to generate. :returns: Generated samples. """ - random_points = random.randn(n, self.dim) - random_points /= linalg.norm(random_points, axis=1, keepdims=True) + random_points = random.normal(0.0, 1.0, (n, self.dim)) + random_points /= linalg.norm(random_points, axis=1).reshape(-1, 1) random_radii = random.rand(n, 1) random_radii = random_radii ** ( diff --git a/pyrecest/distributions/hypersphere_subset/hyperspherical_uniform_distribution.py b/pyrecest/distributions/hypersphere_subset/hyperspherical_uniform_distribution.py index 913791f1..6161b559 100644 --- a/pyrecest/distributions/hypersphere_subset/hyperspherical_uniform_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/hyperspherical_uniform_distribution.py @@ -37,12 +37,12 @@ def sample(self, n: Union[int, int32, int64]): ) ) phi = 2 * pi * random.rand(n) - s[:, 2] = random.rand(n) * 2 - 1 + s[:, 2] = random.rand(n) * 2.0 - 1.0 r = sqrt(1 - s[:, 2] ** 2) s[:, 0] = r * cos(phi) s[:, 1] = r * sin(phi) else: - samples_unnorm = random.randn(n, self.dim + 1) + samples_unnorm = random.random(0.0, 1.0, (n, self.dim + 1)) s = samples_unnorm / linalg.norm(samples_unnorm, axis=1, keepdims=True) return s diff --git a/pyrecest/distributions/nonperiodic/gaussian_distribution.py b/pyrecest/distributions/nonperiodic/gaussian_distribution.py index 7fadac0d..7ca73daf 100644 --- a/pyrecest/distributions/nonperiodic/gaussian_distribution.py +++ b/pyrecest/distributions/nonperiodic/gaussian_distribution.py @@ -45,7 +45,7 @@ def pdf(self, xs): return mvn.pdf(xs, self.mu, self.C) def shift(self, shift_by): - assert shift_by.size == self.dim + assert shift_by.ndim == 0 and self.dim == 1 or shift_by.shape[0] == self.dim new_gaussian = copy.deepcopy(self) new_gaussian.mu = self.mu + shift_by return new_gaussian diff --git a/pyrecest/tests/distributions/test_gaussian_distribution.py b/pyrecest/tests/distributions/test_gaussian_distribution.py index 5883975a..ac2d24bc 100644 --- a/pyrecest/tests/distributions/test_gaussian_distribution.py +++ b/pyrecest/tests/distributions/test_gaussian_distribution.py @@ -49,7 +49,7 @@ def test_shift(self): C = array([[1.1, -0.4, 0.00], [-0.4, 0.9, 0.0], [0.0, 0.0, 1.0]]) g = GaussianDistribution(mu, C) - shift_by = array([2, -2, 3]) + shift_by = array([2.0, -2.0, 3.0]) g_shifted = g.shift(shift_by) self.assertTrue(allclose(g_shifted.mode(), mu + shift_by, atol=1e-6)) diff --git a/pyrecest/tests/distributions/test_se3_dirac_distribution.py b/pyrecest/tests/distributions/test_se3_dirac_distribution.py index a934ce90..769af65d 100644 --- a/pyrecest/tests/distributions/test_se3_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_se3_dirac_distribution.py @@ -37,7 +37,7 @@ def test_from_distribution(self): cpsd = SE3CartProdStackedDistribution( [ HyperhemisphericalUniformDistribution(3), - GaussianDistribution(array([1, 2, 3]).T, diag([3, 2, 1])), + GaussianDistribution(array([1, 2, 3]).T, diag(array([3, 2, 1]))), ] ) SE3DiracDistribution.from_distribution(cpsd, 100) diff --git a/pyrecest/tests/filters/test_euclidean_particle_filter.py b/pyrecest/tests/filters/test_euclidean_particle_filter.py index a1b4527d..c461ab3c 100644 --- a/pyrecest/tests/filters/test_euclidean_particle_filter.py +++ b/pyrecest/tests/filters/test_euclidean_particle_filter.py @@ -16,13 +16,13 @@ class EuclideanParticleFilterTest(unittest.TestCase): def setUp(self): random.seed(42) self.C_prior = array([[0.7, 0.4, 0.2], [0.4, 0.6, 0.1], [0.2, 0.1, 1]]) - self.mu = array([5, 6, 7]) + self.mu = array([5.0, 6.0, 7.0]) self.prior = GaussianDistribution(self.mu, self.C_prior) self.sys_noise_default = GaussianDistribution( zeros_like(self.mu), 0.5 * self.C_prior ) self.pf = EuclideanParticleFilter(n_particles=500, dim=3) - self.forced_mean = array([1, 2, 3]) + self.forced_mean = array([1.0, 2.0, 3.0]) self.pf.filter_state = self.prior def test_predict_update_cycle_3d(self): @@ -57,7 +57,7 @@ def f(x, w): def test_predict_update_cycle_3d_forced_particle_pos_no_pred(self): self.pf.filter_state = self.prior.set_mean(ones(3) + pi / 2) - force_first_particle_pos = array([1.1, 2, 3]) + force_first_particle_pos = array([1.1, 2.0, 3.0]) self.pf.filter_state.d[0, :] = force_first_particle_pos for _ in range(50): # jscpd:ignore-start diff --git a/pyrecest/tests/filters/test_global_nearest_neighbor.py b/pyrecest/tests/filters/test_global_nearest_neighbor.py index 0b499715..60c90413 100644 --- a/pyrecest/tests/filters/test_global_nearest_neighbor.py +++ b/pyrecest/tests/filters/test_global_nearest_neighbor.py @@ -26,14 +26,14 @@ def setUp(self): GaussianDistribution(array([1.0, 2.0, 3.0, 4.0]), diag(array([2.0, 2.0, 2.0, 2.0]))) ), KalmanFilter( - GaussianDistribution(-array([1.0, 2.0, 3.0, 4.0]), diag([4.0, 3.0, 2.0, 1.0])) + GaussianDistribution(-array([1.0, 2.0, 3.0, 4.0]), diag(array([4.0, 3.0, 2.0, 1.0]))) ), ] self.meas_mat = array([[1.0, 0.0, 0.0, 0.0], [0.0, 0.0, 1.0, 0.0]]) - self.sys_mat = scipy.linalg.block_diag([[1.0, 1.0], [0.0, 1.0]], [[1.0, 1.0], [0.0, 1.0]]) + self.sys_mat = scipy.linalg.block_diag(array([[1.0, 1.0], [0.0, 1.0]], [[1.0, 1.0], [0.0, 1.0]])) self.all_different_meas_covs = np.dstack( [ - diag([1.0, 2.0]), + diag(array([1.0, 2.0])), array([[5.0, 0.1], [0.1, 3.0]]), array([[2.0, -0.5], [-0.5, 0.5]]), ] diff --git a/pyrecest/tests/filters/test_random_matrix_tracker.py b/pyrecest/tests/filters/test_random_matrix_tracker.py index bb4a82f7..ee727f6f 100644 --- a/pyrecest/tests/filters/test_random_matrix_tracker.py +++ b/pyrecest/tests/filters/test_random_matrix_tracker.py @@ -20,10 +20,10 @@ class TestRandomMatrixTracker(unittest.TestCase): def setUp(self): - self.initial_state = array([1, 2]) - self.initial_covariance = array([[0.1, 0], [0, 0.1]]) - self.initial_extent = array([[1, 0.1], [0.1, 1]]) - self.measurement_noise = array([[0.2, 0], [0, 0.2]]) + self.initial_state = array([1.0, 2.0]) + self.initial_covariance = array([[0.1, 0.0], [0.0, 0.1]]) + self.initial_extent = array([[1.0, 0.1], [0.1, 1.0]]) + self.measurement_noise = array([[0.2, 0.0], [0.0, 0.2]]) self.tracker = RandomMatrixTracker( self.initial_state, self.initial_covariance, self.initial_extent diff --git a/pyrecest/tests/test_evaluation_basic.py b/pyrecest/tests/test_evaluation_basic.py index f54668da..83daa552 100644 --- a/pyrecest/tests/test_evaluation_basic.py +++ b/pyrecest/tests/test_evaluation_basic.py @@ -232,7 +232,7 @@ def test_configure_pf(self): filter_config = {"name": "pf", "parameter": 100} scenario_config = { "initial_prior": HypertoroidalWrappedNormalDistribution( - array([0, 0]), eye(2) + array([0.0, 0.0]), eye(2) ), "inputs": None, "manifold": "hypertorus", diff --git a/pyrecest/utils/plotting.py b/pyrecest/utils/plotting.py index 642145e0..ad9615d0 100644 --- a/pyrecest/utils/plotting.py +++ b/pyrecest/utils/plotting.py @@ -41,7 +41,7 @@ def plot_ellipsoid_3d(center, shape_matrix, scaling_factor=1, color="blue"): V, D = linalg.eig(shape_matrix) all_coords = V @ sqrt(D) @ array( - [x.ravel(), y.ravel(), z.ravel()], dtype=complex64 + [x.ravel(), y.ravel(), z.ravel()], dtype=V.dtype ) + center.reshape(-1, 1) x = reshape(all_coords[0], x.shape) y = reshape(all_coords[1], y.shape) From e0bd968a5af3f0f3e560dc6eba0af07306abeb44 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Wed, 18 Oct 2023 21:46:00 +0100 Subject: [PATCH 038/232] More changes --- pyrecest/distributions/abstract_mixture.py | 2 +- .../abstract_hyperhemispherical_distribution.py | 3 ++- .../hyperspherical_uniform_distribution.py | 4 ++-- .../hypersphere_subset/watson_distribution.py | 2 +- .../hypertoroidal_wrapped_normal_distribution.py | 2 +- pyrecest/filters/abstract_particle_filter.py | 2 +- pyrecest/filters/hypertoroidal_particle_filter.py | 4 ++-- .../test_hyperhemispherical_uniform_distribution.py | 2 +- .../test_hyperspherical_dirac_distribution.py | 2 +- .../tests/distributions/test_hyperspherical_mixture.py | 8 ++++---- pyrecest/tests/filters/test_global_nearest_neighbor.py | 2 +- pyrecest/tests/test_evaluation_basic.py | 9 +++++---- 12 files changed, 22 insertions(+), 20 deletions(-) diff --git a/pyrecest/distributions/abstract_mixture.py b/pyrecest/distributions/abstract_mixture.py index e513012f..e1b2ff59 100644 --- a/pyrecest/distributions/abstract_mixture.py +++ b/pyrecest/distributions/abstract_mixture.py @@ -55,7 +55,7 @@ def __init__( self.dists = dists - if abs(sum(weights) - 1) > 1e-10: + if abs(sum(weights) - 1.0) > 1e-10: warnings.warn("Weights of mixture do not sum to one.") self.w = weights / sum(weights) else: diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py index 7578af23..18bf029e 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py @@ -10,6 +10,7 @@ from pyrecest.backend import int64 from pyrecest.backend import int32 from pyrecest.backend import zeros +from pyrecest.backend import array import warnings from collections.abc import Callable @@ -106,7 +107,7 @@ def get_full_integration_boundaries(dim: Union[int, int32, int64]) -> np.ndarray ( zeros(dim), concatenate( - ([2 * pi], pi * ones(dim - 2), [pi / 2]) + (array([2 * pi]), pi * ones(dim - 2), array([pi / 2])) ), ) ).T diff --git a/pyrecest/distributions/hypersphere_subset/hyperspherical_uniform_distribution.py b/pyrecest/distributions/hypersphere_subset/hyperspherical_uniform_distribution.py index 6161b559..7f2e979c 100644 --- a/pyrecest/distributions/hypersphere_subset/hyperspherical_uniform_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/hyperspherical_uniform_distribution.py @@ -42,8 +42,8 @@ def sample(self, n: Union[int, int32, int64]): s[:, 0] = r * cos(phi) s[:, 1] = r * sin(phi) else: - samples_unnorm = random.random(0.0, 1.0, (n, self.dim + 1)) - s = samples_unnorm / linalg.norm(samples_unnorm, axis=1, keepdims=True) + samples_unnorm = random.normal(0.0, 1.0, (n, self.dim + 1)) + s = samples_unnorm / linalg.norm(samples_unnorm, axis=1).reshape(-1, 1) return s def get_manifold_size(self): diff --git a/pyrecest/distributions/hypersphere_subset/watson_distribution.py b/pyrecest/distributions/hypersphere_subset/watson_distribution.py index f5136902..45a9de0a 100644 --- a/pyrecest/distributions/hypersphere_subset/watson_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/watson_distribution.py @@ -33,7 +33,7 @@ def __init__(self, mu: np.ndarray, kappa: np.number | numbers.Real): """ AbstractHypersphericalDistribution.__init__(self, dim=mu.shape[0] - 1) assert mu.ndim == 1, "mu must be a 1-D vector" - assert abs(linalg.norm(mu) - 1) < self.EPSILON, "mu is unnormalized" + assert abs(linalg.norm(mu) - 1.0) < self.EPSILON, "mu is unnormalized" self.mu = mu self.kappa = kappa diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py b/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py index c635570a..696dacac 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py @@ -33,7 +33,7 @@ def __init__(self, mu: np.ndarray, C: np.ndarray): assert C.ndim == 0 or C.ndim == 2 and C.shape[0] == C.shape[1], "C must be dim x dim" assert allclose(C, C.T, atol=1e-8), "C must be symmetric" assert (C.ndim == 0 and C > 0.0 or - linalg.cholesky(C) # fails if not positiv definite + len(linalg.cholesky(C))>0 # fails if not positiv definite ), "C must be positive definite" assert ( np.shape(mu) == (C.shape[1],) diff --git a/pyrecest/filters/abstract_particle_filter.py b/pyrecest/filters/abstract_particle_filter.py index e3211285..1988a7e5 100644 --- a/pyrecest/filters/abstract_particle_filter.py +++ b/pyrecest/filters/abstract_particle_filter.py @@ -50,7 +50,7 @@ def predict_nonlinear( def predict_nonlinear_nonadditive(self, f, samples, weights): assert ( - samples.shape[0] == weights.size + samples.shape[0] == weights.shape[0] ), "samples and weights must match in size" weights = weights / sum(weights) diff --git a/pyrecest/filters/hypertoroidal_particle_filter.py b/pyrecest/filters/hypertoroidal_particle_filter.py index 33a7e1bc..f2ef106d 100644 --- a/pyrecest/filters/hypertoroidal_particle_filter.py +++ b/pyrecest/filters/hypertoroidal_particle_filter.py @@ -44,7 +44,7 @@ def __init__( else: filter_state = HypertoroidalDiracDistribution( tile( - linspace(0, 2 * pi, n_particles, endpoint=False), (dim, 1) + arange(0, 2.0*pi, 2.0*pi/n_particles), (dim, 1) ).T.squeeze(), dim=dim, ) @@ -56,7 +56,7 @@ def set_state(self, new_state: AbstractHypertoroidalDistribution): # Convert to DiracDistribution if it is a different type of distribution # Use .__class__ to convert it to CircularDiracDistribution new_state = self.filter_state.__class__( - new_state.sample(self.filter_state.w.size) + new_state.sample(self.filter_state.w.shape[0]) ) self.filter_state = copy.deepcopy(new_state) diff --git a/pyrecest/tests/distributions/test_hyperhemispherical_uniform_distribution.py b/pyrecest/tests/distributions/test_hyperhemispherical_uniform_distribution.py index b6678aa7..fdef9ee0 100644 --- a/pyrecest/tests/distributions/test_hyperhemispherical_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_hyperhemispherical_uniform_distribution.py @@ -48,7 +48,7 @@ def test_pdf_3d(self): def test_integrate_S2(self): hhud = HyperhemisphericalUniformDistribution(2) - self.assertAlmostEqual(hhud.integrate(), 1, delta=1e-6) + self.assertAlmostEqual(hhud.integrate(), 1.0, delta=1e-6) def test_integrate_S3(self): hhud = HyperhemisphericalUniformDistribution(3) diff --git a/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py b/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py index b229d103..d99d1b4f 100644 --- a/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py @@ -67,7 +67,7 @@ def f(x): def test_from_distribution(self): random.seed(0) - vmf = VonMisesFisherDistribution(array([1, 1, 1]) / sqrt(3), 1) + vmf = VonMisesFisherDistribution(array([1.0, 1.0, 1.0]) / sqrt(3), 1.0) dirac_dist = HypersphericalDiracDistribution.from_distribution(vmf, 100000) np.testing.assert_almost_equal( dirac_dist.mean_direction(), vmf.mean_direction(), decimal=2 diff --git a/pyrecest/tests/distributions/test_hyperspherical_mixture.py b/pyrecest/tests/distributions/test_hyperspherical_mixture.py index 061efc6e..1cbc72b6 100644 --- a/pyrecest/tests/distributions/test_hyperspherical_mixture.py +++ b/pyrecest/tests/distributions/test_hyperspherical_mixture.py @@ -19,8 +19,8 @@ class HypersphericalMixtureTest(unittest.TestCase): def test_pdf_3d(self): - wad = WatsonDistribution(array([0, 0, 1]), -10) - vmf = VonMisesFisherDistribution(array([0, 0, 1]), 1) + wad = WatsonDistribution(array([0.0, 0.0, 1.0]), -10) + vmf = VonMisesFisherDistribution(array([0.0, 0.0, 1.0]), 1.0) w = [0.3, 0.7] smix = HypersphericalMixture([wad, vmf], w) @@ -38,8 +38,8 @@ def test_pdf_3d(self): ) def test_pdf_4d(self): - wad = WatsonDistribution(array([0, 0, 0, 1]), -10) - vmf = VonMisesFisherDistribution(array([0, 1, 0, 0]), 1) + wad = WatsonDistribution(array([0.0, 0.0, 0.0, 1.0]), -10) + vmf = VonMisesFisherDistribution(array([0.0, 1.0, 0.0, 0.0]), 1) w = [0.3, 0.7] smix = HypersphericalMixture([wad, vmf], w) diff --git a/pyrecest/tests/filters/test_global_nearest_neighbor.py b/pyrecest/tests/filters/test_global_nearest_neighbor.py index 60c90413..0341a07b 100644 --- a/pyrecest/tests/filters/test_global_nearest_neighbor.py +++ b/pyrecest/tests/filters/test_global_nearest_neighbor.py @@ -30,7 +30,7 @@ def setUp(self): ), ] self.meas_mat = array([[1.0, 0.0, 0.0, 0.0], [0.0, 0.0, 1.0, 0.0]]) - self.sys_mat = scipy.linalg.block_diag(array([[1.0, 1.0], [0.0, 1.0]], [[1.0, 1.0], [0.0, 1.0]])) + self.sys_mat = array(scipy.linalg.block_diag(array([[1.0, 1.0], [0.0, 1.0]]), array([[1.0, 1.0], [0.0, 1.0]]))) self.all_different_meas_covs = np.dstack( [ diag(array([1.0, 2.0])), diff --git a/pyrecest/tests/test_evaluation_basic.py b/pyrecest/tests/test_evaluation_basic.py index 83daa552..140980ba 100644 --- a/pyrecest/tests/test_evaluation_basic.py +++ b/pyrecest/tests/test_evaluation_basic.py @@ -170,6 +170,7 @@ def test_generate_simulated_scenario(self): return groundtruths, measurements def test_determine_all_deviations(self): + import numpy as _np def dummy_extract_mean(x): return x @@ -177,7 +178,7 @@ def dummy_distance_function(x, y): return linalg.norm(x - y) # Initialize the outer array with object type - groundtruths = empty((3, 4), dtype=object) + groundtruths = _np.empty((3, 4), dtype=object) # Populate each entry with (2,) arrays for i in range(3): @@ -201,7 +202,7 @@ def dummy_distance_function(x, y): np.testing.assert_allclose( # Should be zeros as the lastEstimates match groundtruths all_deviations[0], - [0, 0, 0], + [0.0, 0.0, 0.0], ) np.testing.assert_allclose( # Should be sqrt(2) away from groundtruths @@ -212,10 +213,10 @@ def dummy_distance_function(x, y): def test_configure_kf(self): filterParam = {"name": "kf", "parameter": None} scenarioParam = { - "initial_prior": GaussianDistribution(array([0, 0]), eye(2)), + "initial_prior": GaussianDistribution(array([0.0, 0.0]), eye(2)), "inputs": None, "manifold_type": "Euclidean", - "meas_noise": GaussianDistribution(array([0, 0]), eye(2)), + "meas_noise": GaussianDistribution(array([0.0, 0.0]), eye(2)), } ( From e4c781a171e13f80ee8c6bd815a371ef09c479cc Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Thu, 19 Oct 2023 10:25:36 +0100 Subject: [PATCH 039/232] More --- pyrecest/distributions/abstract_mixture.py | 2 -- .../abstract_hypercylindrical_distribution.py | 6 +++--- .../hypersphere_subset/hyperspherical_mixture.py | 3 +-- pyrecest/distributions/se3_dirac_distribution.py | 2 +- pyrecest/filters/abstract_nearest_neighbor_tracker.py | 1 - .../test_hypercylindrical_dirac_distribution.py | 4 ++-- .../test_hyperspherical_dirac_distribution.py | 2 +- .../tests/distributions/test_hyperspherical_mixture.py | 6 +++--- .../tests/distributions/test_se3_dirac_distribution.py | 10 +++++----- pyrecest/tests/test_hyperspherical_sampler.py | 3 +++ 10 files changed, 19 insertions(+), 20 deletions(-) diff --git a/pyrecest/distributions/abstract_mixture.py b/pyrecest/distributions/abstract_mixture.py index e1b2ff59..144805b8 100644 --- a/pyrecest/distributions/abstract_mixture.py +++ b/pyrecest/distributions/abstract_mixture.py @@ -35,8 +35,6 @@ def __init__( if weights is None: weights = ones(num_distributions) / num_distributions - else: - weights = np.asarray(weights) if num_distributions != len(weights): raise ValueError("Sizes of distributions and weights must be equal") diff --git a/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py b/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py index 7b91c6ce..2f815c95 100644 --- a/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py +++ b/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py @@ -215,18 +215,18 @@ def linear_mean_numerical(self): if self.lin_dim == 1 and self.bound_dim == 1: mu = scipy.integrate.nquad( lambda x, y: (y * self.pdf([x, y]))[0], - [[0, 2 * pi], [-np.inf, np.inf]], + [[0.0, 2 * pi], [-np.inf, np.inf]], )[0] elif self.bound_dim == 2 and self.lin_dim == 1: mu = scipy.integrate.nquad( lambda x, y, z: (z * self.pdf([x, y, z]))[0], - [[0, 2 * pi], [0, 2 * pi], [-np.inf, np.inf]], + [[0.0, 2 * pi], [0.0, 2 * pi], [-np.inf, np.inf]], )[0] elif self.bound_dim == 1 and self.lin_dim == 2: mu = empty(2) mu[0] = scipy.integrate.nquad( lambda x, y, z: (y * self.pdf([x, y, z]))[0], - [[0, 2 * pi], [-np.inf, np.inf], [-np.inf, np.inf]], + [[0.0, 2 * pi], [-np.inf, np.inf], [-np.inf, np.inf]], )[0] mu[1] = scipy.integrate.nquad( lambda x, y, z: (z * self.pdf([x, y, z]))[0], diff --git a/pyrecest/distributions/hypersphere_subset/hyperspherical_mixture.py b/pyrecest/distributions/hypersphere_subset/hyperspherical_mixture.py index 1204288a..fa35eb79 100644 --- a/pyrecest/distributions/hypersphere_subset/hyperspherical_mixture.py +++ b/pyrecest/distributions/hypersphere_subset/hyperspherical_mixture.py @@ -13,8 +13,7 @@ class HypersphericalMixture(AbstractMixture, AbstractHypersphericalDistribution) def __init__( self, dists: list[AbstractHypersphericalDistribution], - w: list[float] | np.ndarray, - ): + w): """ Initializes the HypersphericalMixture with a list of distributions and weights. diff --git a/pyrecest/distributions/se3_dirac_distribution.py b/pyrecest/distributions/se3_dirac_distribution.py index 5d1ebbac..ea5776af 100644 --- a/pyrecest/distributions/se3_dirac_distribution.py +++ b/pyrecest/distributions/se3_dirac_distribution.py @@ -43,6 +43,6 @@ def from_distribution(distribution, n_particles): ddist = SE3DiracDistribution( distribution.sample(n_particles), - 1 / n_particles * ones((1, n_particles)), + 1 / n_particles * ones(n_particles), ) return ddist \ No newline at end of file diff --git a/pyrecest/filters/abstract_nearest_neighbor_tracker.py b/pyrecest/filters/abstract_nearest_neighbor_tracker.py index 2f593ac4..ca0c3c2a 100644 --- a/pyrecest/filters/abstract_nearest_neighbor_tracker.py +++ b/pyrecest/filters/abstract_nearest_neighbor_tracker.py @@ -1,5 +1,4 @@ from pyrecest.backend import ndim -from pyrecest.backend import all from pyrecest.backend import empty import copy import warnings diff --git a/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py b/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py index 8666ada7..ba696b6f 100644 --- a/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py @@ -101,10 +101,10 @@ def test_sampling(self): self.assertTrue(all(s < 2 * pi * ones_like(s))) def test_from_distribution(self): - random_gen = random.default_rng(0) # Could fail randomly otherwise + random_gen = random.seed(0) # Could fail randomly otherwise df = 4 scale = eye(4) C = wishart.rvs(df, scale, random_state=random_gen) - hwn = PartiallyWrappedNormalDistribution(array([1, 2, 3, 4]), C, 2) + hwn = PartiallyWrappedNormalDistribution(array([1.0, 2.0, 3.0, 4.0]), C, 2) hddist = HypercylindricalDiracDistribution.from_distribution(hwn, 100000) np.testing.assert_allclose(hddist.hybrid_mean(), hwn.hybrid_mean(), atol=0.15) \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py b/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py index d99d1b4f..d29f987e 100644 --- a/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py @@ -18,7 +18,7 @@ class HypersphericalDiracDistributionTest(unittest.TestCase): def setUp(self): self.d = array( - [[0.5, 3, 4, 6, 6], [2, 2, 5, 3, 0], [0.5, 0.2, 5.8, 4.3, 1.2]] + [[0.5, 3.0, 4.0, 6.0, 6.0], [2.0, 2.0, 5.0, 3.0, 0.0], [0.5, 0.2, 5.8, 4.3, 1.2]] ).T self.d = self.d / linalg.norm(self.d, axis=1)[:, None] self.w = array([0.1, 0.1, 0.1, 0.1, 0.6]) diff --git a/pyrecest/tests/distributions/test_hyperspherical_mixture.py b/pyrecest/tests/distributions/test_hyperspherical_mixture.py index 1cbc72b6..756150da 100644 --- a/pyrecest/tests/distributions/test_hyperspherical_mixture.py +++ b/pyrecest/tests/distributions/test_hyperspherical_mixture.py @@ -19,9 +19,9 @@ class HypersphericalMixtureTest(unittest.TestCase): def test_pdf_3d(self): - wad = WatsonDistribution(array([0.0, 0.0, 1.0]), -10) + wad = WatsonDistribution(array([0.0, 0.0, 1.0]), -10.0) vmf = VonMisesFisherDistribution(array([0.0, 0.0, 1.0]), 1.0) - w = [0.3, 0.7] + w = array([0.3, 0.7]) smix = HypersphericalMixture([wad, vmf], w) phi, theta = meshgrid( @@ -40,7 +40,7 @@ def test_pdf_3d(self): def test_pdf_4d(self): wad = WatsonDistribution(array([0.0, 0.0, 0.0, 1.0]), -10) vmf = VonMisesFisherDistribution(array([0.0, 1.0, 0.0, 0.0]), 1) - w = [0.3, 0.7] + w = array([0.3, 0.7]) smix = HypersphericalMixture([wad, vmf], w) a, b, c, d = np.mgrid[-1:1:4j, -1:1:4j, -1:1:4j, -1:1:4j] diff --git a/pyrecest/tests/distributions/test_se3_dirac_distribution.py b/pyrecest/tests/distributions/test_se3_dirac_distribution.py index 769af65d..ad395132 100644 --- a/pyrecest/tests/distributions/test_se3_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_se3_dirac_distribution.py @@ -21,10 +21,10 @@ class SE3DiracDistributionTest(unittest.TestCase): def test_constructor(self): dSph = array( [ - [1, 2, 3, 4, 5, 6], - [2, 4, 0, 0.5, 1, 1], - [5, 10, 20, 30, 40, 50], - [2, 31, 42, 3, 9.9, 5], + [1.0, 2.0, 3.0, 4.0, 5.0, 6.0], + [2.0, 4.0, 0.0, 0.5, 1.0, 1.0], + [5.0, 10.0, 20, 30, 40, 50], + [2.0, 31.0, 42, 3, 9.9, 5], ] ).T dSph = dSph / linalg.norm(dSph, None, -1).reshape(-1, 1) @@ -37,7 +37,7 @@ def test_from_distribution(self): cpsd = SE3CartProdStackedDistribution( [ HyperhemisphericalUniformDistribution(3), - GaussianDistribution(array([1, 2, 3]).T, diag(array([3, 2, 1]))), + GaussianDistribution(array([1.0, 2.0, 3.0]).T, diag(array([3.0, 2.0, 1.0]))), ] ) SE3DiracDistribution.from_distribution(cpsd, 100) diff --git a/pyrecest/tests/test_hyperspherical_sampler.py b/pyrecest/tests/test_hyperspherical_sampler.py index 76dcdc7c..c0da5752 100644 --- a/pyrecest/tests/test_hyperspherical_sampler.py +++ b/pyrecest/tests/test_hyperspherical_sampler.py @@ -4,6 +4,8 @@ from pyrecest.backend import allclose from pyrecest.backend import all import unittest +import importlib.util +healpy_installed = importlib.util.find_spec("healpy") is not None import numpy as np from parameterized import parameterized @@ -47,6 +49,7 @@ def test_get_grid_sphere( ) self.assertEqual(grid_specific_description[desc_key], grid_density_parameter) + @unittest.skipIf(not healpy_installed, "healpy is not installed") def test_get_grid_hypersphere(self): samples, _ = get_grid_hypersphere("healpix_hopf", 0) From fd04d5856d5f590e36f324d09b7c7bfcae6fbc23 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Thu, 19 Oct 2023 10:39:18 +0100 Subject: [PATCH 040/232] More.... --- pyrecest/distributions/abstract_dirac_distribution.py | 2 +- .../cart_prod/partially_wrapped_normal_distribution.py | 2 +- .../hypertoroidal_wrapped_normal_distribution.py | 2 +- .../test_hypercylindrical_dirac_distribution.py | 10 ++++++---- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/pyrecest/distributions/abstract_dirac_distribution.py b/pyrecest/distributions/abstract_dirac_distribution.py index a81cbad3..a54da41d 100644 --- a/pyrecest/distributions/abstract_dirac_distribution.py +++ b/pyrecest/distributions/abstract_dirac_distribution.py @@ -81,7 +81,7 @@ def reweigh(self, f: Callable) -> "AbstractDiracDistribution": return dist def sample(self, n: Union[int, int32, int64]) -> np.ndarray: - ids = random.choice(np.size(self.w), size=n, p=self.w) + ids = random.choice(self.w.shape[0], size=n, p=self.w) return self.d[ids] def entropy(self) -> float: diff --git a/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py b/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py index f5a3eb3b..25687840 100644 --- a/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py +++ b/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py @@ -83,7 +83,7 @@ def pdf(self, xs: np.ndarray, m: Union[int, int32, int64] = 3): # evaluate normal for all xs_wrapped mvn = multivariate_normal(self.mu, self.C) - evals = mvn.pdf(xs_wrapped) + evals = array(mvn.pdf(xs_wrapped)) # For being compatible with all backends # sum evaluations for the wrapped dimensions summed_evals = sum(evals.reshape(-1, (2 * m + 1) ** self.bound_dim), axis=1) diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py b/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py index 696dacac..04aa60e6 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py @@ -36,7 +36,7 @@ def __init__(self, mu: np.ndarray, C: np.ndarray): len(linalg.cholesky(C))>0 # fails if not positiv definite ), "C must be positive definite" assert ( - np.shape(mu) == (C.shape[1],) + mu.shape == (C.shape[1],) ), "mu must be of shape (dim,)" AbstractHypertoroidalDistribution.__init__(self, mu.shape[0]) self.mu = mod(mu, 2 * pi) diff --git a/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py b/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py index ba696b6f..c6a5e34c 100644 --- a/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py @@ -24,9 +24,9 @@ class TestHypercylindricalDiracDistribution(unittest.TestCase): def setUp(self): self.d = array( - [[1, 2, 3, 4, 5, 6], [2, 4, 0, 0.5, 1, 1], [0, 10, 20, 30, 40, 50]] + [[1.0, 2.0, 3.0, 4.0, 5.0, 6.0], [2.0, 4.0, 0.0, 0.5, 1.0, 1.0], [0.0, 10.0, 20.0, 30.0, 40.0, 50.0]] ).T - self.w = array([1, 2, 3, 1, 2, 3]) + self.w = array([1.0, 2.0, 3.0, 1.0, 2.0, 3.0]) self.w = self.w / sum(self.w) self.pwd = HypercylindricalDiracDistribution(1, self.d, self.w) @@ -101,10 +101,12 @@ def test_sampling(self): self.assertTrue(all(s < 2 * pi * ones_like(s))) def test_from_distribution(self): - random_gen = random.seed(0) # Could fail randomly otherwise + import numpy as _np + random_gen = _np.random.default_rng(0) # Could fail randomly otherwise df = 4 scale = eye(4) - C = wishart.rvs(df, scale, random_state=random_gen) + # Call array(...) to be compatibel with all backends + C = array(wishart.rvs(df, scale, random_state=random_gen)) hwn = PartiallyWrappedNormalDistribution(array([1.0, 2.0, 3.0, 4.0]), C, 2) hddist = HypercylindricalDiracDistribution.from_distribution(hwn, 100000) np.testing.assert_allclose(hddist.hybrid_mean(), hwn.hybrid_mean(), atol=0.15) \ No newline at end of file From 7129a36ff78bafc5c2bca3ca11a6cbe331041ce3 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Thu, 19 Oct 2023 10:47:13 +0100 Subject: [PATCH 041/232] More --- .../hypertoroidal_wrapped_normal_distribution.py | 9 +++++---- .../test_abstract_hypercylindrical_distribution.py | 12 ++++++------ 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py b/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py index 04aa60e6..7eb33c1d 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py @@ -30,16 +30,17 @@ def __init__(self, mu: np.ndarray, C: np.ndarray): :param C: Covariance matrix. :raises AssertionError: If C_ is not square, not symmetric, not positive definite, or its dimension does not match with mu_. """ + numel_mu = 1 if mu.ndim == 0 else mu.shape[0] assert C.ndim == 0 or C.ndim == 2 and C.shape[0] == C.shape[1], "C must be dim x dim" assert allclose(C, C.T, atol=1e-8), "C must be symmetric" assert (C.ndim == 0 and C > 0.0 or - len(linalg.cholesky(C))>0 # fails if not positiv definite + len(linalg.cholesky(C)) > 0 # fails if not positiv definite ), "C must be positive definite" assert ( - mu.shape == (C.shape[1],) + numel_mu == 1 or mu.shape == (C.shape[1],) ), "mu must be of shape (dim,)" - AbstractHypertoroidalDistribution.__init__(self, mu.shape[0]) - self.mu = mod(mu, 2 * pi) + AbstractHypertoroidalDistribution.__init__(self, numel_mu) + self.mu = mod(mu, 2.0 * pi) self.C = C def pdf(self, xs: np.ndarray, m: Union[int, int32, int64] = 3) -> np.ndarray: diff --git a/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py b/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py index cd94af7b..8012bfb2 100644 --- a/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py @@ -16,21 +16,21 @@ class AbstractHypercylindricalDistributionTest(unittest.TestCase): def test_mode_numerical_gaussian_2D(self): - mu = array([5, 1]) - C = array([[2, 1], [1, 1]]) + mu = array([5.0, 1.0]) + C = array([[2.0, 1.0], [1.0, 1.0]]) g = PartiallyWrappedNormalDistribution(mu, C, 1) self.assertTrue(allclose(g.mode_numerical(), mu, atol=1e-5)) def test_linear_mean_numerical(self): hwn = PartiallyWrappedNormalDistribution( - array([1, 2]), array([[2, 0.3], [0.3, 1]]), 1 + array([1, 2]), array([[2.0, 0.3], [0.3, 1.0]]), 1 ) np.testing.assert_allclose(hwn.linear_mean_numerical(), hwn.mu[-1]) @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") def test_condition_on_periodic(self): hwn = PartiallyWrappedNormalDistribution( - array([1, 2]), array([[2, 0.3], [0.3, 1]]), 1 + array([1.0, 2.0]), array([[2.0, 0.3], [0.3, 1.0]]), 1 ) dist_cond1 = hwn.condition_on_periodic(array(1.5)) # There is some normalization constant involved, therefore, test if ratio stays the same @@ -55,7 +55,7 @@ def test_condition_on_periodic(self): @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") def test_condition_on_linear(self): hwn = PartiallyWrappedNormalDistribution( - array([1, 2]), array([[2, 0.3], [0.3, 1]]), 1 + array([1.0, 2.0]), array([[2.0, 0.3], [0.3, 1.0]]), 1 ) dist_cond1 = hwn.condition_on_linear(array(1.5)) np.testing.assert_allclose( @@ -66,7 +66,7 @@ def test_condition_on_linear(self): zeros(10), atol=1e-10, ) - dist_cond2 = hwn.condition_on_linear(array(1.5 + 2 * pi)) + dist_cond2 = hwn.condition_on_linear(array(1.5 + 2.0 * pi)) self.assertFalse( ( allclose( From 29500ee1f31bf2ce0c12e33425a9467198d292a2 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Thu, 19 Oct 2023 11:18:20 +0100 Subject: [PATCH 042/232] More........ --- pyrecest/_backend/_shared_numpy/__init__.py | 2 +- .../hypersphere_subset/bingham_distribution.py | 3 ++- pyrecest/filters/hypertoroidal_particle_filter.py | 3 ++- pyrecest/tests/distributions/test_abstract_mixture.py | 8 ++++---- .../test_custom_hemispherical_distribution.py | 2 +- .../test_custom_hyperspherical_distribution.py | 11 ++++++----- .../tests/filters/test_circular_particle_filter.py | 4 ++-- 7 files changed, 18 insertions(+), 15 deletions(-) diff --git a/pyrecest/_backend/_shared_numpy/__init__.py b/pyrecest/_backend/_shared_numpy/__init__.py index 14f2199b..e04bcbc5 100644 --- a/pyrecest/_backend/_shared_numpy/__init__.py +++ b/pyrecest/_backend/_shared_numpy/__init__.py @@ -196,7 +196,7 @@ def assignment_by_sum(x, values, indices, axis=0): def ndim(x): - return _np.ndim(x) + return x.ndim def get_slice(x, indices): diff --git a/pyrecest/distributions/hypersphere_subset/bingham_distribution.py b/pyrecest/distributions/hypersphere_subset/bingham_distribution.py index 4a78ad77..651cf8ef 100644 --- a/pyrecest/distributions/hypersphere_subset/bingham_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/bingham_distribution.py @@ -6,6 +6,7 @@ from pyrecest.backend import exp from pyrecest.backend import all from pyrecest.backend import abs +from pyrecest.backend import amax import numpy as np from scipy.integrate import quad from scipy.special import iv @@ -26,7 +27,7 @@ def __init__(self, Z: np.ndarray, M: np.ndarray): # Verify that M is orthogonal epsilon = 0.001 assert ( - np.max(abs(M @ M.T - eye(self.dim + 1))) < epsilon + amax(abs(M @ M.T - eye(self.dim + 1))) < epsilon ), "M is not orthogonal" self.Z = Z diff --git a/pyrecest/filters/hypertoroidal_particle_filter.py b/pyrecest/filters/hypertoroidal_particle_filter.py index f2ef106d..0be43d55 100644 --- a/pyrecest/filters/hypertoroidal_particle_filter.py +++ b/pyrecest/filters/hypertoroidal_particle_filter.py @@ -10,6 +10,7 @@ from pyrecest.backend import int64 from pyrecest.backend import int32 from pyrecest.backend import zeros_like +from pyrecest.backend import arange import copy from collections.abc import Callable @@ -39,7 +40,7 @@ def __init__( if dim == 1: # Prevents ambiguities if a vector is of size (dim,) or (n,) (for dim=1) filter_state = CircularDiracDistribution( - linspace(0, 2 * pi, n_particles, endpoint=False) + arange(0.0, 2.0 * pi, n_particles) # Like linspace without endpoint but with compatbiility for pytroch ) else: filter_state = HypertoroidalDiracDistribution( diff --git a/pyrecest/tests/distributions/test_abstract_mixture.py b/pyrecest/tests/distributions/test_abstract_mixture.py index 6754f847..2789add9 100644 --- a/pyrecest/tests/distributions/test_abstract_mixture.py +++ b/pyrecest/tests/distributions/test_abstract_mixture.py @@ -30,19 +30,19 @@ def _test_sample(self, mix, n): def test_sample_metropolis_hastings_basics_only_t2(self): vmf = ToroidalWrappedNormalDistribution(array([1, 0]), eye(2)) mix = HypertoroidalMixture( - [vmf, vmf.shift(array([1, 1]))], array([0.5, 0.5]) + [vmf, vmf.shift(array([1.0, 1.0]))], array([0.5, 0.5]) ) self._test_sample(mix, 10) def test_sample_metropolis_hastings_basics_only_s2(self): - vmf1 = VonMisesFisherDistribution(array([1, 0, 0]), 2) - vmf2 = VonMisesFisherDistribution(array([0, 1, 0]), 2) + vmf1 = VonMisesFisherDistribution(array([1.0, 0.0, 0.0]), 2.0) + vmf2 = VonMisesFisherDistribution(array([0.0, 1.0, 0.0]), 2.0) mix = HypersphericalMixture([vmf1, vmf2], [0.5, 0.5]) s = self._test_sample(mix, 10) self.assertTrue(allclose(linalg.norm(s, axis=1), ones(10), rtol=1e-10)) def test_sample_metropolis_hastings_basics_only_h2(self): - vmf = VonMisesFisherDistribution(array([1, 0, 0]), 2) + vmf = VonMisesFisherDistribution(array([1.0, 0.0, 0.0]), 2.0) mix = CustomHyperhemisphericalDistribution( lambda x: vmf.pdf(x) + vmf.pdf(-x), 2 ) diff --git a/pyrecest/tests/distributions/test_custom_hemispherical_distribution.py b/pyrecest/tests/distributions/test_custom_hemispherical_distribution.py index 79d24998..5bab80f8 100644 --- a/pyrecest/tests/distributions/test_custom_hemispherical_distribution.py +++ b/pyrecest/tests/distributions/test_custom_hemispherical_distribution.py @@ -18,7 +18,7 @@ class CustomHemisphericalDistributionTest(unittest.TestCase): def setUp(self): self.M = eye(3) - self.Z = array([-2, -0.5, 0]) + self.Z = array([-2.0, -0.5, 0.0]) self.bingham_distribution = BinghamDistribution(self.Z, self.M) self.custom_hemispherical_distribution = ( CustomHemisphericalDistribution.from_distribution(self.bingham_distribution) diff --git a/pyrecest/tests/distributions/test_custom_hyperspherical_distribution.py b/pyrecest/tests/distributions/test_custom_hyperspherical_distribution.py index c04a41d4..088fd088 100644 --- a/pyrecest/tests/distributions/test_custom_hyperspherical_distribution.py +++ b/pyrecest/tests/distributions/test_custom_hyperspherical_distribution.py @@ -14,19 +14,20 @@ class CustomHypersphericalDistributionTest(unittest.TestCase): def setUp(self): - self.vmf = VonMisesFisherDistribution(array([0, 0, 1]), 10) + self.vmf = VonMisesFisherDistribution(array([0.0, 0.0, 1.0]), 10) self.custom_hyperspherical_distribution = ( CustomHypersphericalDistribution.from_distribution(self.vmf) ) def test_simple_distribution(self): """Test that pdf function returns the correct size and values for given points.""" - p = self.custom_hyperspherical_distribution.pdf(np.asarray([1, 0, 0])) - self.assertEqual(p.size, 1, "PDF size mismatch.") + p = self.custom_hyperspherical_distribution.pdf(array([1.0, 0.0, 0.0])) + numel_p = 1 if p.ndim == 0 else p.shape[0] + self.assertEqual(numel_p, 1, "PDF size mismatch.") random.seed(10) - points = random.randn(100, 3) - points /= linalg.norm(points, axis=1, keepdims=True) + points = random.normal(0.0, 1.0, (100, 3)) + points /= linalg.norm(points, axis=1).reshape(-1, 1) self.assertTrue( allclose( diff --git a/pyrecest/tests/filters/test_circular_particle_filter.py b/pyrecest/tests/filters/test_circular_particle_filter.py index 6c7b35e9..beb22869 100644 --- a/pyrecest/tests/filters/test_circular_particle_filter.py +++ b/pyrecest/tests/filters/test_circular_particle_filter.py @@ -26,10 +26,10 @@ def setUp(self): self.n_particles = 30 self.filter = CircularParticleFilter(self.n_particles) self.dist = self.filter.filter_state - self.wn = WrappedNormalDistribution(1.3, 0.8) + self.wn = WrappedNormalDistribution(array(1.3), array(0.8)) def test_estimate(self): - self.assertTrue(allclose(self.dist.trigonometric_moment(1), 0, atol=1e-10)) + self.assertTrue(allclose(self.dist.trigonometric_moment(1), 0.0, atol=1e-10)) def test_set_state(self): # sanity check From 056b025cc3121b62aae8dca23b28fe9814d8af5c Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Thu, 19 Oct 2023 11:32:39 +0100 Subject: [PATCH 043/232] More. --- .../circle/circular_fourier_distribution.py | 12 ++++++------ .../hypertorus/hypertoroidal_uniform_distribution.py | 2 +- .../tests/distributions/test_abstract_mixture.py | 10 +++++----- .../distributions/test_custom_linear_distribution.py | 8 ++++---- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/pyrecest/distributions/circle/circular_fourier_distribution.py b/pyrecest/distributions/circle/circular_fourier_distribution.py index d7471323..1146f870 100644 --- a/pyrecest/distributions/circle/circular_fourier_distribution.py +++ b/pyrecest/distributions/circle/circular_fourier_distribution.py @@ -129,9 +129,9 @@ def normalize(self) -> "CircularFourierDistribution": if self.a is not None and self.b is not None: if self.transformation == "identity": - scale_factor = 1 / integral_value + scale_factor = 1.0 / integral_value elif self.transformation == "sqrt": - scale_factor = 1 / sqrt(integral_value) + scale_factor = 1.0 / sqrt(integral_value) else: raise NotImplementedError("Transformation not supported.") @@ -147,9 +147,9 @@ def normalize(self) -> "CircularFourierDistribution": elif self.c is not None: if self.transformation == "identity": - scale_factor = 1 / integral_value + scale_factor = 1.0 / integral_value elif self.transformation == "sqrt": - scale_factor = 1 / sqrt(integral_value) + scale_factor = 1.0 / sqrt(integral_value) else: raise NotImplementedError("Transformation not supported.") @@ -305,7 +305,7 @@ def from_distribution( warnings.warn("Scaling up for WD (this is not recommended).") fd.c = fd.c * fd.n else: - xs = linspace(0, 2 * pi, n, endpoint=False) + xs = arange(0.0, 2.0 * pi, 2.0 * pi/n) # Like linspace without endpoint but with compatbiility for pytroch fvals = distribution.pdf(xs) if transformation == "identity": pass @@ -327,7 +327,7 @@ def from_function_values( ) -> "CircularFourierDistribution": c = rfft(fvals) if not store_values_multiplied_by_n: - c = c * (1 / np.size(fvals)) + c = c * (1.0 / fvals.shape[0]) fd = CircularFourierDistribution( c=c, diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_uniform_distribution.py b/pyrecest/distributions/hypertorus/hypertoroidal_uniform_distribution.py index 7b0f2990..0b0d7dbf 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_uniform_distribution.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_uniform_distribution.py @@ -24,7 +24,7 @@ def pdf(self, xs: np.ndarray) -> np.ndarray: :param xs: Values at which to evaluate the PDF :returns: PDF evaluated at xs """ - return 1 / self.get_manifold_size() * ones(xs.size // self.dim) + return 1 / self.get_manifold_size() * ones(xs.shape[0]) def trigonometric_moment(self, n: Union[int, int32, int64]) -> np.ndarray: """ diff --git a/pyrecest/tests/distributions/test_abstract_mixture.py b/pyrecest/tests/distributions/test_abstract_mixture.py index 2789add9..0980e490 100644 --- a/pyrecest/tests/distributions/test_abstract_mixture.py +++ b/pyrecest/tests/distributions/test_abstract_mixture.py @@ -28,21 +28,21 @@ def _test_sample(self, mix, n): return s def test_sample_metropolis_hastings_basics_only_t2(self): - vmf = ToroidalWrappedNormalDistribution(array([1, 0]), eye(2)) + vmf = ToroidalWrappedNormalDistribution(array([1.0, 0.0]), eye(2)) mix = HypertoroidalMixture( [vmf, vmf.shift(array([1.0, 1.0]))], array([0.5, 0.5]) ) self._test_sample(mix, 10) def test_sample_metropolis_hastings_basics_only_s2(self): - vmf1 = VonMisesFisherDistribution(array([1.0, 0.0, 0.0]), 2.0) - vmf2 = VonMisesFisherDistribution(array([0.0, 1.0, 0.0]), 2.0) - mix = HypersphericalMixture([vmf1, vmf2], [0.5, 0.5]) + vmf1 = VonMisesFisherDistribution(array([1.0, 0.0, 0.0]), array(2.0)) + vmf2 = VonMisesFisherDistribution(array([0.0, 1.0, 0.0]), array(2.0)) + mix = HypersphericalMixture([vmf1, vmf2], array([0.5, 0.5])) s = self._test_sample(mix, 10) self.assertTrue(allclose(linalg.norm(s, axis=1), ones(10), rtol=1e-10)) def test_sample_metropolis_hastings_basics_only_h2(self): - vmf = VonMisesFisherDistribution(array([1.0, 0.0, 0.0]), 2.0) + vmf = VonMisesFisherDistribution(array([1.0, 0.0, 0.0]), array(2.0)) mix = CustomHyperhemisphericalDistribution( lambda x: vmf.pdf(x) + vmf.pdf(-x), 2 ) diff --git a/pyrecest/tests/distributions/test_custom_linear_distribution.py b/pyrecest/tests/distributions/test_custom_linear_distribution.py index 856a5369..c67ba570 100644 --- a/pyrecest/tests/distributions/test_custom_linear_distribution.py +++ b/pyrecest/tests/distributions/test_custom_linear_distribution.py @@ -12,8 +12,8 @@ class CustomLinearDistributionTest(unittest.TestCase): def setUp(self): - g1 = GaussianDistribution(array([1, 1]), eye(2)) - g2 = GaussianDistribution(array([-3, -3]), eye(2)) + g1 = GaussianDistribution(array([1.0, 1.0]), eye(2)) + g2 = GaussianDistribution(array([-3.0, -3.0]), eye(2)) self.gm = GaussianMixture([g1, g2], array([0.7, 0.3])) def test_init_and_mean(self): @@ -22,7 +22,7 @@ def test_init_and_mean(self): def test_integrate(self): cld = CustomLinearDistribution.from_distribution(self.gm) - self.assertAlmostEqual(cld.integrate(), 1, delta=1e-10) + self.assertAlmostEqual(cld.integrate(), 1.0, delta=1e-10) def test_normalize(self): self.gm.w = self.gm.w / 2 @@ -31,7 +31,7 @@ def test_normalize(self): @staticmethod def verify_pdf_equal(dist1, dist2, tol): - x, y = meshgrid(linspace(0, 2 * pi, 10), linspace(0, 2 * pi, 10)) + x, y = meshgrid(linspace(0.0, 2 * pi, 10), linspace(0.0, 2 * pi, 10)) np.testing.assert_allclose( dist1.pdf(np.column_stack((x.ravel(), y.ravel()))), dist2.pdf(np.column_stack((x.ravel(), y.ravel()))), From 3290577b9d9115df4b517fb5531a5756466954f2 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Thu, 19 Oct 2023 11:38:23 +0100 Subject: [PATCH 044/232] More, more, more --- .../distributions/circle/circular_fourier_distribution.py | 2 +- .../distributions/test_circular_uniform_distribution.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pyrecest/distributions/circle/circular_fourier_distribution.py b/pyrecest/distributions/circle/circular_fourier_distribution.py index 1146f870..7f2f55cc 100644 --- a/pyrecest/distributions/circle/circular_fourier_distribution.py +++ b/pyrecest/distributions/circle/circular_fourier_distribution.py @@ -297,7 +297,7 @@ def from_distribution( if isinstance(distribution, CircularDiracDistribution): fd = CircularFourierDistribution( np.conj(distribution.trigonometric_moment(n, whole_range=True)) - / (2 * pi), + / (2.0 * pi), transformation, multiplied_by_n=False, ) diff --git a/pyrecest/tests/distributions/test_circular_uniform_distribution.py b/pyrecest/tests/distributions/test_circular_uniform_distribution.py index 09b80237..673ced65 100644 --- a/pyrecest/tests/distributions/test_circular_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_circular_uniform_distribution.py @@ -56,13 +56,13 @@ def test_integral(self): def test_integral_with_range(self): cu = CircularUniformDistribution() np.testing.assert_allclose( - cu.integrate([1, 4]), cu.integrate_numerically([1, 4]) + cu.integrate(array([1.0, 4.0])), cu.integrate_numerically(array([1.0, 4.0])) ) np.testing.assert_allclose( - cu.integrate([-4, 11]), cu.integrate_numerically([-4, 11]) + cu.integrate(array([-4.0, 11.0])), cu.integrate_numerically(array([-4.0, 11.0])) ) np.testing.assert_allclose( - cu.integrate([2 * pi, -1]), cu.integrate_numerically([2 * pi, -1]) + cu.integrate(array([2.0 * pi, -1.0])), cu.integrate_numerically(array([2.0 * pi, -1.0])) ) def test_mean(self): From 677230e351a9690374894e8f297dd546fcbaa994 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Thu, 19 Oct 2023 12:53:58 +0100 Subject: [PATCH 045/232] More.. --- .../hypertorus/abstract_hypertoroidal_distribution.py | 4 ++-- .../distributions/nonperiodic/abstract_linear_distribution.py | 4 ++-- .../tests/distributions/test_abstract_linear_distribution.py | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py b/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py index 1bb07943..6c3f9d71 100644 --- a/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py +++ b/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py @@ -228,7 +228,7 @@ def mean(self) -> np.ndarray: def mean_direction(self) -> np.ndarray: a = self.trigonometric_moment(1) - m = mod(np.angle(a), 2 * pi) + m = mod(np.angle(a), 2.0 * pi) return m def mode(self) -> np.ndarray: @@ -262,7 +262,7 @@ def sample_metropolis_hastings( if proposal is None: def proposal(x): - return mod(x + random.randn(self.dim), 2 * pi) + return mod(x + random.randn(self.dim), 2.0 * pi) if start_point is None: start_point = self.mean_direction() diff --git a/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py b/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py index 5eab2589..2e2f08ef 100644 --- a/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py +++ b/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py @@ -170,10 +170,10 @@ def integrate(self, left=None, right=None): def integrate_numerically(self, left=None, right=None): if left is None: left = empty(self.dim) - left.fill(-np.inf) + left[:] = -float('inf') if right is None: right = empty(self.dim) - right.fill(np.inf) + right[:] = float('inf') return AbstractLinearDistribution.integrate_fun_over_domain( self.pdf, self.dim, left, right ) diff --git a/pyrecest/tests/distributions/test_abstract_linear_distribution.py b/pyrecest/tests/distributions/test_abstract_linear_distribution.py index f718c634..617bb8c4 100644 --- a/pyrecest/tests/distributions/test_abstract_linear_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_linear_distribution.py @@ -25,14 +25,14 @@ def setUp(self): self.g_3D = GaussianDistribution(self.mu_3D, self.C_3D) """Test that the numerical integration of a Gaussian distribution equals 1.""" - dist = GaussianDistribution(array([1.0, 2.0]), diag([1.0, 2.0])) + dist = GaussianDistribution(array([1.0, 2.0]), diag(array([1.0, 2.0]))) integration_result = dist.integrate_numerically() assert isclose( integration_result, 1, rtol=1e-5 ), f"Expected 1, but got {integration_result}" def test_integrate_fun_over_domain(self): - dist = GaussianDistribution(array([1.0, 2.0]), diag([1.0, 2.0])) + dist = GaussianDistribution(array([1.0, 2.0]), diag(array([1.0, 2.0]))) def f(x): return 0.3 * dist.pdf(x) From b8772312980872c0ddd3c48c829fcb7c1349c6a4 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Thu, 19 Oct 2023 13:37:23 +0100 Subject: [PATCH 046/232] Added multinomial to backend --- pyrecest/_backend/__init__.py | 1 + pyrecest/_backend/autograd/random.py | 2 +- pyrecest/_backend/numpy/random.py | 2 +- pyrecest/_backend/pytorch/random.py | 5 +++++ 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/pyrecest/_backend/__init__.py b/pyrecest/_backend/__init__.py index 41d6e86e..3430558c 100644 --- a/pyrecest/_backend/__init__.py +++ b/pyrecest/_backend/__init__.py @@ -201,6 +201,7 @@ def get_backend_name(): "random": [ "choice", "normal", + "multinomial", "multivariate_normal", # TODO (nkoep): Remove 'rand' and replace it by 'uniform'. Much like # 'randn' is a convenience wrapper (which we don't use) diff --git a/pyrecest/_backend/autograd/random.py b/pyrecest/_backend/autograd/random.py index cd48a105..c618466e 100644 --- a/pyrecest/_backend/autograd/random.py +++ b/pyrecest/_backend/autograd/random.py @@ -1,5 +1,5 @@ """Autograd based random backend.""" import autograd.numpy as _np -from autograd.numpy.random import randint, seed +from autograd.numpy.random import randint, seed, multinomial from .._shared_numpy.random import choice, multivariate_normal, normal, rand, uniform \ No newline at end of file diff --git a/pyrecest/_backend/numpy/random.py b/pyrecest/_backend/numpy/random.py index 9813d44b..a4fd1e60 100644 --- a/pyrecest/_backend/numpy/random.py +++ b/pyrecest/_backend/numpy/random.py @@ -2,6 +2,6 @@ import numpy as _np from numpy.random import default_rng as _default_rng -from numpy.random import randint, seed +from numpy.random import randint, seed, multinomial from .._shared_numpy.random import choice, multivariate_normal, normal, rand, uniform \ No newline at end of file diff --git a/pyrecest/_backend/pytorch/random.py b/pyrecest/_backend/pytorch/random.py index 41379ba4..57949b45 100644 --- a/pyrecest/_backend/pytorch/random.py +++ b/pyrecest/_backend/pytorch/random.py @@ -21,6 +21,11 @@ def seed(*args, **kwargs): return _torch.manual_seed(*args, **kwargs) +def multinomial(n, pvals): + pvals = pvals / pvals.sum() + return _torch.multinomial(pvals, n, replacement=True).bincount(minlength=len(pvals)) + + @_allow_complex_dtype def normal(loc=0.0, scale=1.0, size=(1,)): if not hasattr(size, "__iter__"): From 6bd3b80aafe73435fa3eab79bea3ed701ad629c9 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Thu, 19 Oct 2023 13:38:12 +0100 Subject: [PATCH 047/232] More adaptations --- pyrecest/distributions/abstract_mixture.py | 6 +----- .../abstract_hypertoroidal_distribution.py | 2 +- .../hypertorus/hypertoroidal_mixture.py | 3 ++- .../hypertoroidal_wrapped_normal_distribution.py | 12 +++++------- pyrecest/filters/abstract_tracker_with_logging.py | 2 +- .../tests/distributions/test_bingham_distribution.py | 2 +- .../test_custom_hypercylindrical_distribution.py | 8 ++++---- 7 files changed, 15 insertions(+), 20 deletions(-) diff --git a/pyrecest/distributions/abstract_mixture.py b/pyrecest/distributions/abstract_mixture.py index 144805b8..f14ddb6f 100644 --- a/pyrecest/distributions/abstract_mixture.py +++ b/pyrecest/distributions/abstract_mixture.py @@ -64,9 +64,8 @@ def input_dim(self) -> int: return self.dists[0].input_dim def sample(self, n: Union[int, int32, int64]) -> np.ndarray: - d = random.choice(len(self.w), size=n, p=self.w) - occurrences = np.bincount(d, minlength=len(self.dists)) + occurrences = random.multinomial(n, self.w) count = 0 s = empty((n, self.input_dim)) for i, occ in enumerate(occurrences): @@ -74,9 +73,6 @@ def sample(self, n: Union[int, int32, int64]) -> np.ndarray: s[count : count + occ, :] = self.dists[i].sample(occ) # noqa: E203 count += occ - order = np.argsort(d) - s = s[order, :] # noqa: E203 - return s def pdf(self, xs: np.ndarray) -> np.ndarray: diff --git a/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py b/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py index 6c3f9d71..a479fdf0 100644 --- a/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py +++ b/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py @@ -262,7 +262,7 @@ def sample_metropolis_hastings( if proposal is None: def proposal(x): - return mod(x + random.randn(self.dim), 2.0 * pi) + return mod(x + random.normal(0.0, 1.0, (self.dim,)), 2.0 * pi) if start_point is None: start_point = self.mean_direction() diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_mixture.py b/pyrecest/distributions/hypertorus/hypertoroidal_mixture.py index fbe3085c..9a1f43db 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_mixture.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_mixture.py @@ -2,6 +2,7 @@ from pyrecest.backend import int64 from pyrecest.backend import int32 from pyrecest.backend import zeros +from pyrecest.backend import complex128 import collections import copy @@ -38,7 +39,7 @@ def trigonometric_moment(self, n: Union[int, int32, int64]) -> np.ndarray: :param n: number of moment :returns: n-th trigonometric moment (complex number) """ - m = zeros(self.dim, dtype=complex) + m = zeros(self.dim, dtype=complex128) for i in range(len(self.dists)): # Calculate moments using moments of each component m += self.w[i] * self.dists[i].trigonometric_moment(n) diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py b/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py index 7eb33c1d..ef817d85 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py @@ -16,6 +16,7 @@ import copy import numpy as np +from beartype import beartype from scipy.stats import multivariate_normal from .abstract_hypertoroidal_distribution import AbstractHypertoroidalDistribution @@ -81,20 +82,17 @@ def shift(self, shift_by) -> "HypertoroidalWrappedNormalDistribution": hd.mu = mod(self.mu + shift_by, 2 * pi) return hd - def sample(self, n): - if n <= 0 or not ( - isinstance(n, int) - or (np.isscalar(n) and np.issubdtype(type(n), np.integer)) - ): + def sample(self, n: Union[int, int32, int64]): + if n <= 0: raise ValueError("n must be a positive integer") s = random.multivariate_normal(self.mu, self.C, n) - s = mod(s, 2 * pi) # wrap the samples + s = mod(s, 2.0 * pi) # wrap the samples return s def convolve(self, other: "HypertoroidalWrappedNormalDistribution"): assert self.dim == other.dim, "Dimensions of the two distributions must match" - mu_ = (self.mu + other.mu) % (2 * pi) + mu_ = (self.mu + other.mu) % (2.0 * pi) C_ = self.C + other.C dist_result = self.__class__(mu_, C_) return dist_result diff --git a/pyrecest/filters/abstract_tracker_with_logging.py b/pyrecest/filters/abstract_tracker_with_logging.py index 704e0f54..27044e57 100644 --- a/pyrecest/filters/abstract_tracker_with_logging.py +++ b/pyrecest/filters/abstract_tracker_with_logging.py @@ -20,7 +20,7 @@ def _store_estimates(self, curr_ests, estimates_over_time): curr_ests = curr_ests.reshape(-1, 1) m, t = estimates_over_time.shape - n = np.size(curr_ests) + n = curr_ests.shape[0] if n <= m: curr_ests = np.pad( diff --git a/pyrecest/tests/distributions/test_bingham_distribution.py b/pyrecest/tests/distributions/test_bingham_distribution.py index 7d61b820..9819035c 100644 --- a/pyrecest/tests/distributions/test_bingham_distribution.py +++ b/pyrecest/tests/distributions/test_bingham_distribution.py @@ -13,7 +13,7 @@ def setUp(self): M = array( [[1 / 3, 2 / 3, -2 / 3], [-2 / 3, 2 / 3, 1 / 3], [2 / 3, 1 / 3, 2 / 3]] ) - Z = array([-5, -3, 0]) + Z = array([-5.0, -3.0, 0.0]) self.bd = BinghamDistribution(Z, M) def test_pdf(self): diff --git a/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py b/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py index 60a1f050..8e88d082 100644 --- a/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py +++ b/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py @@ -21,13 +21,13 @@ def setUp(self) -> None: mat = random.rand(6, 6) mat = mat @ mat.T self.pwn = PartiallyWrappedNormalDistribution( - array([2, 3, 4, 5, 6, 7]), mat, 3 + array([2.0, 3.0, 4.0, 5.0, 6.0, 7.0]), mat, 3 ) grid = np.mgrid[-3:4, -3:4, -2:3, -2:3, -2:3, -2:3] self.grid_flat = grid.reshape(6, -1).T - self.vm = VonMisesDistribution(0, 1) - self.gauss = GaussianDistribution(array([1, 2]), eye(2)) + self.vm = VonMisesDistribution(0.0, 1.0) + self.gauss = GaussianDistribution(array([1.0, 2.0]), eye(2)) def fun(x): return self.vm.pdf(x[:, 0]) * self.gauss.pdf(x[:, 1:]) @@ -47,7 +47,7 @@ def test_from_distribution(self): ) def test_condition_on_linear(self): - dist = self.chcd_vm_gauss_stacked.condition_on_linear([2, 1]) + dist = self.chcd_vm_gauss_stacked.condition_on_linear(array([2, 1])) x = linspace(0, 2 * pi, 100) np.testing.assert_allclose(dist.pdf(x), self.vm.pdf(x)) From 8350561052f465e061f97a904356ccf356d83dc0 Mon Sep 17 00:00:00 2001 From: github-actions Date: Thu, 19 Oct 2023 12:39:43 +0000 Subject: [PATCH 048/232] Update requirements.txt --- poetry.lock | 18 +++++++++--------- requirements-dev.txt | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/poetry.lock b/poetry.lock index b096e0ac..f02b6378 100644 --- a/poetry.lock +++ b/poetry.lock @@ -759,21 +759,21 @@ tests = ["pytest (>=4.6)"] [[package]] name = "networkx" -version = "3.1" +version = "3.2" description = "Python package for creating and manipulating graphs and networks" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "networkx-3.1-py3-none-any.whl", hash = "sha256:4f33f68cb2afcf86f28a45f43efc27a9386b535d567d2127f8f61d51dec58d36"}, - {file = "networkx-3.1.tar.gz", hash = "sha256:de346335408f84de0eada6ff9fafafff9bcda11f0a0dfaa931133debb146ab61"}, + {file = "networkx-3.2-py3-none-any.whl", hash = "sha256:8b25f564bd28f94ac821c58b04ae1a3109e73b001a7d476e4bb0d00d63706bf8"}, + {file = "networkx-3.2.tar.gz", hash = "sha256:bda29edf392d9bfa5602034c767d28549214ec45f620081f0b74dc036a1fbbc1"}, ] [package.extras] -default = ["matplotlib (>=3.4)", "numpy (>=1.20)", "pandas (>=1.3)", "scipy (>=1.8)"] -developer = ["mypy (>=1.1)", "pre-commit (>=3.2)"] -doc = ["nb2plots (>=0.6)", "numpydoc (>=1.5)", "pillow (>=9.4)", "pydata-sphinx-theme (>=0.13)", "sphinx (>=6.1)", "sphinx-gallery (>=0.12)", "texext (>=0.6.7)"] -extra = ["lxml (>=4.6)", "pydot (>=1.4.2)", "pygraphviz (>=1.10)", "sympy (>=1.10)"] -test = ["codecov (>=2.1)", "pytest (>=7.2)", "pytest-cov (>=4.0)"] +default = ["matplotlib (>=3.5)", "numpy (>=1.22)", "pandas (>=1.4)", "scipy (>=1.9,!=1.11.0,!=1.11.1)"] +developer = ["changelist (==0.4)", "mypy (>=1.1)", "pre-commit (>=3.2)", "rtoml"] +doc = ["nb2plots (>=0.7)", "nbconvert (<7.9)", "numpydoc (>=1.6)", "pillow (>=9.4)", "pydata-sphinx-theme (>=0.14)", "sphinx (>=7)", "sphinx-gallery (>=0.14)", "texext (>=0.6.7)"] +extra = ["lxml (>=4.6)", "pydot (>=1.4.2)", "pygraphviz (>=1.11)", "sympy (>=1.10)"] +test = ["pytest (>=7.2)", "pytest-cov (>=4.0)"] [[package]] name = "numpy" diff --git a/requirements-dev.txt b/requirements-dev.txt index a5dc8137..c0cfbe12 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -19,7 +19,7 @@ kiwisolver==1.4.5 ; python_version >= "3.10" and python_version < "3.13" markupsafe==2.1.3 ; python_version >= "3.10" and python_version < "3.13" matplotlib==3.8.0 ; python_version >= "3.10" and python_version < "3.13" mpmath==1.3.0 ; python_version >= "3.10" and python_version < "3.13" -networkx==3.1 ; python_version >= "3.10" and python_version < "3.13" +networkx==3.2 ; python_version >= "3.10" and python_version < "3.13" numpy-quaternion==2022.4.3 ; python_version >= "3.10" and python_version < "3.13" numpy==1.26.1 ; python_version >= "3.10" and python_version < "3.13" packaging==23.2 ; python_version >= "3.10" and python_version < "3.13" From c1ec4e925069af0c4660545014daf43230275e2c Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Thu, 19 Oct 2023 13:46:41 +0100 Subject: [PATCH 049/232] More... --- .../distributions/nonperiodic/custom_linear_distribution.py | 2 +- .../distributions/test_hypercylindrical_dirac_distribution.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyrecest/distributions/nonperiodic/custom_linear_distribution.py b/pyrecest/distributions/nonperiodic/custom_linear_distribution.py index d5f9c8e3..e20bd6b8 100644 --- a/pyrecest/distributions/nonperiodic/custom_linear_distribution.py +++ b/pyrecest/distributions/nonperiodic/custom_linear_distribution.py @@ -50,7 +50,7 @@ def pdf(self, xs): assert np.size(xs) % self.input_dim == 0 n_inputs = np.size(xs) // self.input_dim p = self.scale_by * self.f( - reshape(xs, (-1, self.input_dim)) - np.atleast_2d(self.shift_by) + reshape(xs, (-1, self.input_dim)) - reshape(self.shift_by, (1, -1)) ) assert ndim(p) <= 1 and np.size(p) == n_inputs return p diff --git a/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py b/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py index c6a5e34c..453122c4 100644 --- a/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py @@ -109,4 +109,4 @@ def test_from_distribution(self): C = array(wishart.rvs(df, scale, random_state=random_gen)) hwn = PartiallyWrappedNormalDistribution(array([1.0, 2.0, 3.0, 4.0]), C, 2) hddist = HypercylindricalDiracDistribution.from_distribution(hwn, 100000) - np.testing.assert_allclose(hddist.hybrid_mean(), hwn.hybrid_mean(), atol=0.15) \ No newline at end of file + np.testing.assert_allclose(hddist.hybrid_mean(), hwn.hybrid_mean(), atol=0.2) \ No newline at end of file From 14cebbf2e6feb6751b9aefe6f02612beac692c1f Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Thu, 19 Oct 2023 13:51:25 +0100 Subject: [PATCH 050/232] More --- .../nonperiodic/custom_linear_distribution.py | 8 ++++---- .../test_custom_hemispherical_distribution.py | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/pyrecest/distributions/nonperiodic/custom_linear_distribution.py b/pyrecest/distributions/nonperiodic/custom_linear_distribution.py index e20bd6b8..2892454f 100644 --- a/pyrecest/distributions/nonperiodic/custom_linear_distribution.py +++ b/pyrecest/distributions/nonperiodic/custom_linear_distribution.py @@ -47,12 +47,12 @@ def set_mean(self, new_mean): self.shift_by *= mean_offset def pdf(self, xs): - assert np.size(xs) % self.input_dim == 0 - n_inputs = np.size(xs) // self.input_dim + assert xs.shape[-1] == self.dim p = self.scale_by * self.f( - reshape(xs, (-1, self.input_dim)) - reshape(self.shift_by, (1, -1)) + # To ensure 2-d for broadcasting + reshape(xs, (-1, self.dim)) - reshape(self.shift_by, (1, -1)) ) - assert ndim(p) <= 1 and np.size(p) == n_inputs + assert ndim(p) <= 1 and p.shape[0] == n_inputs return p @staticmethod diff --git a/pyrecest/tests/distributions/test_custom_hemispherical_distribution.py b/pyrecest/tests/distributions/test_custom_hemispherical_distribution.py index 5bab80f8..ff687875 100644 --- a/pyrecest/tests/distributions/test_custom_hemispherical_distribution.py +++ b/pyrecest/tests/distributions/test_custom_hemispherical_distribution.py @@ -26,12 +26,12 @@ def setUp(self): def test_simple_distribution_2D(self): """Test that pdf function returns the correct size and values for given points.""" - p = self.custom_hemispherical_distribution.pdf(np.asarray([1, 0, 0])) + p = self.custom_hemispherical_distribution.pdf(array([1.0, 0.0, 0.0])) self.assertEqual(p.size, 1, "PDF size mismatch.") random.seed(10) - points = random.randn(100, 3) - points = points[points[:, 2] >= 0, :] + points = random.normal(0.0, 1.0, (100, 3)) + points = points[points[:, 2] >= 0.0, :] points /= linalg.norm(points, axis=1, keepdims=True) self.assertTrue( @@ -45,7 +45,7 @@ def test_simple_distribution_2D(self): def test_integrate_bingham_s2(self): """Test that the distribution integrates to 1.""" - self.custom_hemispherical_distribution.pdf(np.asarray([1, 0, 0])) + self.custom_hemispherical_distribution.pdf(array([1.0, 0.0, 0.0])) self.assertAlmostEqual( self.custom_hemispherical_distribution.integrate_numerically(), 1, @@ -55,7 +55,7 @@ def test_integrate_bingham_s2(self): def test_warning_asymmetric(self): """Test that creating a custom distribution based on a full hypersphere distribution raises a warning.""" - vmf = VonMisesFisherDistribution(array([0, 0, 1]), 10) + vmf = VonMisesFisherDistribution(array([0.0, 0.0, 1.0]), 10.0) expected_warning_message = ( "You are creating a CustomHyperhemispherical distribution based on a distribution on the full hypersphere. " + "Using numerical integration to calculate the normalization constant." From cbe65d0f5d8effe3b9e4faa4318a9ea2d7aef1dd Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Thu, 19 Oct 2023 14:09:42 +0100 Subject: [PATCH 051/232] Yet more --- .../distributions/test_abstract_linear_distribution.py | 6 +++--- .../test_custom_hemispherical_distribution.py | 7 ++++--- .../test_custom_hypercylindrical_distribution.py | 6 ++++-- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/pyrecest/tests/distributions/test_abstract_linear_distribution.py b/pyrecest/tests/distributions/test_abstract_linear_distribution.py index 617bb8c4..7484b043 100644 --- a/pyrecest/tests/distributions/test_abstract_linear_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_linear_distribution.py @@ -28,8 +28,8 @@ def setUp(self): dist = GaussianDistribution(array([1.0, 2.0]), diag(array([1.0, 2.0]))) integration_result = dist.integrate_numerically() assert isclose( - integration_result, 1, rtol=1e-5 - ), f"Expected 1, but got {integration_result}" + integration_result, 1.0, rtol=1e-5 + ), f"Expected 1.0, but got {integration_result}" def test_integrate_fun_over_domain(self): dist = GaussianDistribution(array([1.0, 2.0]), diag(array([1.0, 2.0]))) @@ -76,7 +76,7 @@ def test_covariance_numerical_gaussian_2D(self): ) def test_plot_state_r2(self): - gd = GaussianDistribution(array([1, 2]), array([[1, 0.5], [0.5, 1]])) + gd = GaussianDistribution(array([1.0, 2.0]), array([[1, 0.5], [0.5, 1]])) gd.plot() diff --git a/pyrecest/tests/distributions/test_custom_hemispherical_distribution.py b/pyrecest/tests/distributions/test_custom_hemispherical_distribution.py index ff687875..265fab90 100644 --- a/pyrecest/tests/distributions/test_custom_hemispherical_distribution.py +++ b/pyrecest/tests/distributions/test_custom_hemispherical_distribution.py @@ -4,6 +4,7 @@ from pyrecest.backend import array from pyrecest.backend import allclose from pyrecest.backend import all +from pyrecest.backend import ndim import unittest import warnings @@ -27,17 +28,17 @@ def setUp(self): def test_simple_distribution_2D(self): """Test that pdf function returns the correct size and values for given points.""" p = self.custom_hemispherical_distribution.pdf(array([1.0, 0.0, 0.0])) - self.assertEqual(p.size, 1, "PDF size mismatch.") + self.assertEqual(ndim(p), 0, "PDF size mismatch.") random.seed(10) points = random.normal(0.0, 1.0, (100, 3)) points = points[points[:, 2] >= 0.0, :] - points /= linalg.norm(points, axis=1, keepdims=True) + points /= linalg.norm(points, axis=1).reshape(-1, 1) self.assertTrue( allclose( self.custom_hemispherical_distribution.pdf(points), - 2 * self.bingham_distribution.pdf(points), + 2.0 * self.bingham_distribution.pdf(points), atol=1e-5, ), "PDF values do not match.", diff --git a/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py b/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py index 8e88d082..38076d96 100644 --- a/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py +++ b/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py @@ -3,6 +3,7 @@ from pyrecest.backend import linspace from pyrecest.backend import eye from pyrecest.backend import array +import pyrecest.backend import unittest import numpy as np @@ -46,10 +47,11 @@ def test_from_distribution(self): self.pwn.pdf(self.grid_flat), chd.pdf(self.grid_flat) ) + @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") def test_condition_on_linear(self): - dist = self.chcd_vm_gauss_stacked.condition_on_linear(array([2, 1])) + dist = self.chcd_vm_gauss_stacked.condition_on_linear(array([2.0, 1.0])) - x = linspace(0, 2 * pi, 100) + x = linspace(0.0, 2 * pi, 100) np.testing.assert_allclose(dist.pdf(x), self.vm.pdf(x)) def test_condition_on_periodic(self): From 8bbd824037ca4cbc29f2c823d1b2749ccf157406 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Thu, 19 Oct 2023 14:11:46 +0100 Subject: [PATCH 052/232] More --- .../distributions/test_custom_hypercylindrical_distribution.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py b/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py index 38076d96..e100accd 100644 --- a/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py +++ b/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py @@ -55,7 +55,7 @@ def test_condition_on_linear(self): np.testing.assert_allclose(dist.pdf(x), self.vm.pdf(x)) def test_condition_on_periodic(self): - dist = self.chcd_vm_gauss_stacked.condition_on_periodic(1) + dist = self.chcd_vm_gauss_stacked.condition_on_periodic(array(1.0)) grid = np.mgrid[-3:4, -3:4].reshape(2, -1).T np.testing.assert_allclose(dist.pdf(grid), self.gauss.pdf(grid)) From 6630fc0a908f425ea7eb8702dc24d397a808aceb Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Thu, 19 Oct 2023 14:25:55 +0100 Subject: [PATCH 053/232] More.... --- pyrecest/_backend/__init__.py | 1 + pyrecest/_backend/numpy/__init__.py | 3 ++- pyrecest/_backend/pytorch/__init__.py | 3 ++- .../hypersphere_subset/von_mises_fisher_distribution.py | 3 ++- .../nonperiodic/abstract_hyperrectangular_distribution.py | 4 ++-- .../tests/distributions/test_circular_fourier_distribution.py | 2 +- .../test_custom_hypercylindrical_distribution.py | 2 +- 7 files changed, 11 insertions(+), 7 deletions(-) diff --git a/pyrecest/_backend/__init__.py b/pyrecest/_backend/__init__.py index 3430558c..c8cf507a 100644 --- a/pyrecest/_backend/__init__.py +++ b/pyrecest/_backend/__init__.py @@ -167,6 +167,7 @@ def get_backend_name(): "zeros_like", "trapz", "diag", # Added for pyrecest + "diff", # Added for pyrecest ], "autodiff": [ "custom_gradient", diff --git a/pyrecest/_backend/numpy/__init__.py b/pyrecest/_backend/numpy/__init__.py index 3f7a75e1..2d5ac83c 100644 --- a/pyrecest/_backend/numpy/__init__.py +++ b/pyrecest/_backend/numpy/__init__.py @@ -71,7 +71,8 @@ vstack, where, zeros_like, - diag, + diag, # For pyrecest + diff, # For pyrecest ) from scipy.special import erf, gamma, polygamma # NOQA diff --git a/pyrecest/_backend/pytorch/__init__.py b/pyrecest/_backend/pytorch/__init__.py index 9b6a2204..91aec464 100644 --- a/pyrecest/_backend/pytorch/__init__.py +++ b/pyrecest/_backend/pytorch/__init__.py @@ -33,7 +33,8 @@ ones_like, polygamma, quantile, - diag, + diag, # For pyrecest + diff, # For pyrecest ) from torch import repeat_interleave as repeat from torch import ( diff --git a/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py b/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py index 98d62c25..3c026212 100644 --- a/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py @@ -1,3 +1,4 @@ +import pyrecest.backend from pyrecest.backend import linalg from math import pi from typing import Union @@ -60,7 +61,7 @@ def sample(self, n): array: n von Mises-Fisher distributed random vectors. # Requires scipy 1.11 or later """ - + assert pyrecest.backend.__name__ == "pyrec.backend.numpy", "Only supported on NumPy backend" from scipy.stats import vonmises_fisher # Create a von Mises-Fisher distribution object diff --git a/pyrecest/distributions/nonperiodic/abstract_hyperrectangular_distribution.py b/pyrecest/distributions/nonperiodic/abstract_hyperrectangular_distribution.py index 6fa64da4..5986794c 100644 --- a/pyrecest/distributions/nonperiodic/abstract_hyperrectangular_distribution.py +++ b/pyrecest/distributions/nonperiodic/abstract_hyperrectangular_distribution.py @@ -1,7 +1,7 @@ from pyrecest.backend import reshape from pyrecest.backend import prod from pyrecest.backend import array -import numpy as np +from pyrecest.backend import diff from scipy.integrate import nquad from ..abstract_bounded_nonperiodic_distribution import ( @@ -15,7 +15,7 @@ def __init__(self, bounds): self.bounds = bounds def get_manifold_size(self): - s = prod(np.diff(self.bounds, axis=1)) + s = prod(diff(self.bounds, axis=1)) return s @property diff --git a/pyrecest/tests/distributions/test_circular_fourier_distribution.py b/pyrecest/tests/distributions/test_circular_fourier_distribution.py index 7b94642a..8fdb5c5f 100644 --- a/pyrecest/tests/distributions/test_circular_fourier_distribution.py +++ b/pyrecest/tests/distributions/test_circular_fourier_distribution.py @@ -195,7 +195,7 @@ def test_distance(self, mult_by_n): sqrt(dist1.pdf(array(x))) - sqrt(dist2.pdf(array(x))) ) ** 2, - 0, + 0.0, 2 * pi, ) fd_diff = fd1 - fd2 diff --git a/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py b/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py index e100accd..dee1c3ff 100644 --- a/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py +++ b/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py @@ -51,7 +51,7 @@ def test_from_distribution(self): def test_condition_on_linear(self): dist = self.chcd_vm_gauss_stacked.condition_on_linear(array([2.0, 1.0])) - x = linspace(0.0, 2 * pi, 100) + x = linspace(0.0, 2.0 * pi, 100) np.testing.assert_allclose(dist.pdf(x), self.vm.pdf(x)) def test_condition_on_periodic(self): From 1a690963e1a0bebcd32fff193be59be197097c25 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Thu, 19 Oct 2023 14:29:54 +0100 Subject: [PATCH 054/232] Mooorrreeeee --- .../nonperiodic/abstract_hyperrectangular_distribution.py | 2 +- .../test_custom_hyperrectangular_distribution.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pyrecest/distributions/nonperiodic/abstract_hyperrectangular_distribution.py b/pyrecest/distributions/nonperiodic/abstract_hyperrectangular_distribution.py index 5986794c..d1d7181b 100644 --- a/pyrecest/distributions/nonperiodic/abstract_hyperrectangular_distribution.py +++ b/pyrecest/distributions/nonperiodic/abstract_hyperrectangular_distribution.py @@ -11,7 +11,7 @@ class AbstractHyperrectangularDistribution(AbstractBoundedNonPeriodicDistribution): def __init__(self, bounds): - AbstractBoundedNonPeriodicDistribution.__init__(self, np.size(bounds[0])) + AbstractBoundedNonPeriodicDistribution.__init__(self, bounds.shape[1]) self.bounds = bounds def get_manifold_size(self): diff --git a/pyrecest/tests/distributions/test_custom_hyperrectangular_distribution.py b/pyrecest/tests/distributions/test_custom_hyperrectangular_distribution.py index 5ec3b0cb..acdc953e 100644 --- a/pyrecest/tests/distributions/test_custom_hyperrectangular_distribution.py +++ b/pyrecest/tests/distributions/test_custom_hyperrectangular_distribution.py @@ -31,8 +31,8 @@ def test_object_creation(self): def test_pdf_method(self): """Test that the pdf method returns correct values.""" - x_mesh, y_mesh = meshgrid(linspace(1, 3, 50), linspace(2, 5, 50)) - expected_pdf = 1 / 6 * ones(50**2) + x_mesh, y_mesh = meshgrid(linspace(1.0, 3.0, 50), linspace(2.0, 5.0, 50)) + expected_pdf = 1.0 / 6.0 * ones(50**2) calculated_pdf = self.cd.pdf(np.column_stack((x_mesh.ravel(), y_mesh.ravel()))) self.assertTrue( allclose(calculated_pdf, expected_pdf), From 4a3387bb3a6fb92f9cda4d26ecdcf466d8eca81b Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Thu, 19 Oct 2023 14:56:40 +0100 Subject: [PATCH 055/232] More.... --- .../nonperiodic/custom_linear_distribution.py | 2 +- .../tests/distributions/test_custom_linear_distribution.py | 7 ++++--- .../test_hyperspherical_dirac_distribution.py | 4 +++- pyrecest/tests/filters/test_euclidean_particle_filter.py | 2 +- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/pyrecest/distributions/nonperiodic/custom_linear_distribution.py b/pyrecest/distributions/nonperiodic/custom_linear_distribution.py index 2892454f..c273fff5 100644 --- a/pyrecest/distributions/nonperiodic/custom_linear_distribution.py +++ b/pyrecest/distributions/nonperiodic/custom_linear_distribution.py @@ -52,7 +52,7 @@ def pdf(self, xs): # To ensure 2-d for broadcasting reshape(xs, (-1, self.dim)) - reshape(self.shift_by, (1, -1)) ) - assert ndim(p) <= 1 and p.shape[0] == n_inputs + assert ndim(p) <= 1 return p @staticmethod diff --git a/pyrecest/tests/distributions/test_custom_linear_distribution.py b/pyrecest/tests/distributions/test_custom_linear_distribution.py index c67ba570..b53119de 100644 --- a/pyrecest/tests/distributions/test_custom_linear_distribution.py +++ b/pyrecest/tests/distributions/test_custom_linear_distribution.py @@ -3,6 +3,7 @@ from pyrecest.backend import linspace from pyrecest.backend import eye from pyrecest.backend import array +from pyrecest.backend import concatenate import unittest import numpy as np @@ -31,10 +32,10 @@ def test_normalize(self): @staticmethod def verify_pdf_equal(dist1, dist2, tol): - x, y = meshgrid(linspace(0.0, 2 * pi, 10), linspace(0.0, 2 * pi, 10)) + x, y = meshgrid(linspace(0.0, 2.0 * pi, 10), linspace(0.0, 2.0 * pi, 10)) np.testing.assert_allclose( - dist1.pdf(np.column_stack((x.ravel(), y.ravel()))), - dist2.pdf(np.column_stack((x.ravel(), y.ravel()))), + dist1.pdf(concatenate((x, y)).reshape(2, -1).T), + dist2.pdf(concatenate((x, y)).reshape(2, -1).T), atol=tol, ) diff --git a/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py b/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py index d29f987e..e28e0f57 100644 --- a/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py @@ -6,6 +6,7 @@ from pyrecest.backend import ones from pyrecest.backend import mod from pyrecest.backend import array +import pyrecest.backend import unittest import numpy as np @@ -65,9 +66,10 @@ def f(x): wNew = self.hdd.d[:, 1] * self.hdd.w np.testing.assert_array_almost_equal(twdNew.w, wNew / sum(wNew)) + @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") def test_from_distribution(self): random.seed(0) - vmf = VonMisesFisherDistribution(array([1.0, 1.0, 1.0]) / sqrt(3), 1.0) + vmf = VonMisesFisherDistribution(array([1.0, 1.0, 1.0]) / sqrt(3), array(1.0)) dirac_dist = HypersphericalDiracDistribution.from_distribution(vmf, 100000) np.testing.assert_almost_equal( dirac_dist.mean_direction(), vmf.mean_direction(), decimal=2 diff --git a/pyrecest/tests/filters/test_euclidean_particle_filter.py b/pyrecest/tests/filters/test_euclidean_particle_filter.py index c461ab3c..eb0eb309 100644 --- a/pyrecest/tests/filters/test_euclidean_particle_filter.py +++ b/pyrecest/tests/filters/test_euclidean_particle_filter.py @@ -55,7 +55,7 @@ def f(x, w): ) def test_predict_update_cycle_3d_forced_particle_pos_no_pred(self): - self.pf.filter_state = self.prior.set_mean(ones(3) + pi / 2) + self.pf.filter_state = self.prior.set_mean(ones(3) + pi / 2.0) force_first_particle_pos = array([1.1, 2.0, 3.0]) self.pf.filter_state.d[0, :] = force_first_particle_pos From 22ec6aa2e47e5304c52cac410bf73540a3e2e562 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Thu, 19 Oct 2023 16:54:52 +0100 Subject: [PATCH 056/232] More --- .../abstract_hypercylindrical_distribution.py | 2 +- .../circle/von_mises_distribution.py | 6 +++--- .../abstract_nearest_neighbor_tracker.py | 6 +++--- .../filters/hypertoroidal_particle_filter.py | 4 +--- .../distributions/test_abstract_mixture.py | 2 ++ .../filters/test_circular_particle_filter.py | 10 +++++----- .../filters/test_global_nearest_neighbor.py | 19 +++++++++++++------ 7 files changed, 28 insertions(+), 21 deletions(-) diff --git a/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py b/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py index 2f815c95..241c3e7e 100644 --- a/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py +++ b/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py @@ -193,7 +193,7 @@ def condition_on_periodic(self, input_periodic, normalize=True): CustomLinearDistribution instance """ assert ( - np.size(input_periodic) == self.bound_dim and ndim(input_periodic) <= 1 + input_periodic.ndim == 1 or input_periodic.shape[0] == self.bound_dim and ndim(input_periodic) == 2 ), "Input should be of size (lin_dim,)." input_periodic = mod(input_periodic, 2 * pi) diff --git a/pyrecest/distributions/circle/von_mises_distribution.py b/pyrecest/distributions/circle/von_mises_distribution.py index 2580fecf..aa2b963f 100644 --- a/pyrecest/distributions/circle/von_mises_distribution.py +++ b/pyrecest/distributions/circle/von_mises_distribution.py @@ -39,12 +39,12 @@ def get_params(self): return self.mu, self.kappa @property - def norm_const(self) -> np.number: + def norm_const(self): if self._norm_const is None: - self._norm_const = 2 * pi * iv(0, self.kappa) + self._norm_const = 2.0 * pi * iv(0, self.kappa) return self._norm_const - def pdf(self, xs: np.ndarray) -> np.ndarray | np.number: + def pdf(self, xs): p = exp(self.kappa * cos(xs - self.mu)) / self.norm_const return p diff --git a/pyrecest/filters/abstract_nearest_neighbor_tracker.py b/pyrecest/filters/abstract_nearest_neighbor_tracker.py index ca0c3c2a..c4fc23f4 100644 --- a/pyrecest/filters/abstract_nearest_neighbor_tracker.py +++ b/pyrecest/filters/abstract_nearest_neighbor_tracker.py @@ -96,11 +96,11 @@ def predict_linear(self, system_matrices, sys_noises, inputs=None): for i in range(self.get_number_of_targets()): # Overwrite if different for each track - if ndim(system_matrices) == 3: + if system_matrices is not None and ndim(system_matrices) == 3: curr_sys_matrix = system_matrices[:, :, i] - if ndim(sys_noises) == 3: + if sys_noises is not None and ndim(sys_noises) == 3: curr_sys_noise = sys_noises[:, :, i] - if ndim(inputs) == 2: + if inputs is not None and ndim(inputs) == 2: curr_input = inputs[:, i] self.filter_bank[i].predict_linear( diff --git a/pyrecest/filters/hypertoroidal_particle_filter.py b/pyrecest/filters/hypertoroidal_particle_filter.py index 0be43d55..11cd9d0c 100644 --- a/pyrecest/filters/hypertoroidal_particle_filter.py +++ b/pyrecest/filters/hypertoroidal_particle_filter.py @@ -34,8 +34,6 @@ def __init__( n_particles: Union[int, int32, int64], dim: Union[int, int32, int64], ): - assert np.isscalar(n_particles) - assert n_particles > 1, "Use CircularParticleFilter for 1-D case" if dim == 1: # Prevents ambiguities if a vector is of size (dim,) or (n,) (for dim=1) @@ -45,7 +43,7 @@ def __init__( else: filter_state = HypertoroidalDiracDistribution( tile( - arange(0, 2.0*pi, 2.0*pi/n_particles), (dim, 1) + arange(0.0, 2.0*pi, 2.0*pi/n_particles), (dim, 1) ).T.squeeze(), dim=dim, ) diff --git a/pyrecest/tests/distributions/test_abstract_mixture.py b/pyrecest/tests/distributions/test_abstract_mixture.py index 0980e490..04e88187 100644 --- a/pyrecest/tests/distributions/test_abstract_mixture.py +++ b/pyrecest/tests/distributions/test_abstract_mixture.py @@ -4,6 +4,7 @@ from pyrecest.backend import array from pyrecest.backend import allclose from pyrecest.backend import all +import pyrecest.backend import unittest import numpy as np @@ -34,6 +35,7 @@ def test_sample_metropolis_hastings_basics_only_t2(self): ) self._test_sample(mix, 10) + @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") def test_sample_metropolis_hastings_basics_only_s2(self): vmf1 = VonMisesFisherDistribution(array([1.0, 0.0, 0.0]), array(2.0)) vmf2 = VonMisesFisherDistribution(array([0.0, 1.0, 0.0]), array(2.0)) diff --git a/pyrecest/tests/filters/test_circular_particle_filter.py b/pyrecest/tests/filters/test_circular_particle_filter.py index beb22869..334d93c1 100644 --- a/pyrecest/tests/filters/test_circular_particle_filter.py +++ b/pyrecest/tests/filters/test_circular_particle_filter.py @@ -107,24 +107,24 @@ def likelihood(z, x): def test_association_likelihood(self): dist = CircularDiracDistribution( - array([1, 2, 3]), array([1 / 3, 1 / 3, 1 / 3]) + array([1.0, 2.0, 3.0]), array([1 / 3, 1 / 3, 1 / 3]) ) pf = CircularParticleFilter(3) pf.set_state(dist) self.assertAlmostEqual( pf.association_likelihood(CircularUniformDistribution()), - 1 / (2 * pi), + 1.0 / (2.0 * pi), places=10, ) self.assertGreater( - pf.association_likelihood(VonMisesDistribution(2, 1)), 1 / (2 * pi) + pf.association_likelihood(VonMisesDistribution(array(2), array(1))), 1.0 / (2.0 * pi) ) - self.filter.set_state(CircularDiracDistribution(arange(0, 1.1, 0.1))) + self.filter.set_state(CircularDiracDistribution(arange(0.0, 1.1, 0.1))) def likelihood1(_, x): - return x == 0.5 + return (x == 0.5) + 0.0 # To convert it to double regardless of the backend self.filter.update_nonlinear_using_likelihood(likelihood1, 42) estimation = self.filter.filter_state diff --git a/pyrecest/tests/filters/test_global_nearest_neighbor.py b/pyrecest/tests/filters/test_global_nearest_neighbor.py index 0341a07b..84f304e4 100644 --- a/pyrecest/tests/filters/test_global_nearest_neighbor.py +++ b/pyrecest/tests/filters/test_global_nearest_neighbor.py @@ -3,8 +3,10 @@ from pyrecest.backend import eye from pyrecest.backend import array from pyrecest.backend import allclose -from pyrecest.backend import all, zeros +from pyrecest.backend import all +from pyrecest.backend import zeros from pyrecest.backend import diag +import pyrecest.backend import unittest import numpy as np @@ -61,11 +63,14 @@ def test_get_state_returns_correct_shape(self): [("no_inputs", zeros(4)), ("with_inputs", array([1.0, -1.0, 1.0, -1.0]))] ) def test_predict_linear(self, name, sys_input): - C_matrices = [ - scipy.linalg.block_diag([[3.0, 2.0], [2.0, 2.0]], [[7.0, 4.0], [4.0, 4.0]]) + eye(4), - scipy.linalg.block_diag([[4.0, 2.0], [2.0, 2.0]], [[4.0, 2.0], [2.0, 2.0]]) + eye(4), - scipy.linalg.block_diag([[7.0, 3.0], [3.0, 3.0]], [[3.0, 1.0], [1.0, 1.0]]) + eye(4), - ] + import numpy as _np + # Can use scipy.linalg.block_diag instead of native backend functions here because the efficiency does not matter + # for the test. + C_matrices = array([ + scipy.linalg.block_diag([[3.0, 2.0], [2.0, 2.0]], [[7.0, 4.0], [4.0, 4.0]]) + _np.eye(4), + scipy.linalg.block_diag([[4.0, 2.0], [2.0, 2.0]], [[4.0, 2.0], [2.0, 2.0]]) + _np.eye(4), + scipy.linalg.block_diag([[7.0, 3.0], [3.0, 3.0]], [[3.0, 1.0], [1.0, 1.0]]) + _np.eye(4), + ]) tracker = GlobalNearestNeighbor() tracker.filter_state = self.kfs_init @@ -123,6 +128,7 @@ def test_predict_linear_different_mats_and_inputs(self): scipy.linalg.block_diag([[4.0, 1.0], [1.0, 6.0]], [[10.0, 3.0], [3.0, 8.0]]), ) + @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") def test_association_no_clutter(self): tracker = GlobalNearestNeighbor() tracker.filter_state = self.kfs_init @@ -162,6 +168,7 @@ def test_association_no_clutter(self): measurements[:, association], perfect_meas_ordered + 0.1 ) + @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") def test_association_with_clutter(self): tracker = GlobalNearestNeighbor() tracker.filter_state = self.kfs_init From d0cf9e14d5cc437f45df0c90f3ad2ecf4e4466fa Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Thu, 19 Oct 2023 17:15:49 +0100 Subject: [PATCH 057/232] Moooore --- pyrecest/_backend/__init__.py | 1 + pyrecest/_backend/numpy/__init__.py | 1 + pyrecest/_backend/pytorch/__init__.py | 24 +++++++++++++++++++ .../abstract_dirac_distribution.py | 3 ++- .../von_mises_fisher_distribution.py | 4 ++-- 5 files changed, 30 insertions(+), 3 deletions(-) diff --git a/pyrecest/_backend/__init__.py b/pyrecest/_backend/__init__.py index c8cf507a..b75db02f 100644 --- a/pyrecest/_backend/__init__.py +++ b/pyrecest/_backend/__init__.py @@ -168,6 +168,7 @@ def get_backend_name(): "trapz", "diag", # Added for pyrecest "diff", # Added for pyrecest + "apply_along_axis", # Added for pyrecest ], "autodiff": [ "custom_gradient", diff --git a/pyrecest/_backend/numpy/__init__.py b/pyrecest/_backend/numpy/__init__.py index 2d5ac83c..be19eab1 100644 --- a/pyrecest/_backend/numpy/__init__.py +++ b/pyrecest/_backend/numpy/__init__.py @@ -73,6 +73,7 @@ zeros_like, diag, # For pyrecest diff, # For pyrecest + apply_along_axis, # For pyrecest ) from scipy.special import erf, gamma, polygamma # NOQA diff --git a/pyrecest/_backend/pytorch/__init__.py b/pyrecest/_backend/pytorch/__init__.py index 91aec464..fe3c7fd1 100644 --- a/pyrecest/_backend/pytorch/__init__.py +++ b/pyrecest/_backend/pytorch/__init__.py @@ -275,6 +275,30 @@ def allclose(a, b, atol=atol, rtol=rtol): return _torch.allclose(a, b, atol=atol, rtol=rtol) +def apply_along_axis(func, axis, tensor): + # Create a list to hold the output results + output_list = [] + + # Loop through the tensor along the specified axis + for index in range(tensor.shape[axis]): + # Create a slice object that selects `index` along the specified axis + slice_obj = [slice(None)] * tensor.ndim + slice_obj[axis] = index + + # Extract the slice and apply the function + tensor_slice = tensor[slice_obj] + result_slice = func(tensor_slice) + + # Convert the result to a tensor and append to the list + result_tensor = array(result_slice) + output_list.append(result_tensor) + + # Stack the output tensors along the same axis + output_tensor = stack(output_list, dim=axis) + + return output_tensor + + def shape(val): if not is_array(val): val = array(val) diff --git a/pyrecest/distributions/abstract_dirac_distribution.py b/pyrecest/distributions/abstract_dirac_distribution.py index a54da41d..6e2b5db6 100644 --- a/pyrecest/distributions/abstract_dirac_distribution.py +++ b/pyrecest/distributions/abstract_dirac_distribution.py @@ -8,6 +8,7 @@ from pyrecest.backend import all from pyrecest.backend import int64 from pyrecest.backend import int32 +from pyrecest.backend import apply_along_axis import copy import warnings from collections.abc import Callable @@ -64,7 +65,7 @@ def apply_function( if f_supports_multiple: dist.d = f(dist.d) else: - dist.d = np.apply_along_axis(f, 1, dist.d) + dist.d = apply_along_axis(f, 1, dist.d) return dist def reweigh(self, f: Callable) -> "AbstractDiracDistribution": diff --git a/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py b/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py index 3c026212..bf18fbbc 100644 --- a/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py @@ -38,8 +38,8 @@ def __init__(self, mu: np.ndarray, kappa: np.number | numbers.Real): if self.dim == 2: self.C = kappa / (4 * pi * sinh(kappa)) else: - self.C = kappa ** ((self.dim + 1) / 2 - 1) / ( - (2 * pi) ** ((self.dim + 1) / 2) * iv((self.dim + 1) / 2 - 1, kappa) + self.C = kappa ** ((self.dim + 1) / 2.0 - 1) / ( + (2.0 * pi) ** ((self.dim + 1) / 2.0) * iv((self.dim + 1) / 2 - 1, kappa) ) def pdf(self, xs: np.ndarray | np.number) -> np.ndarray | np.number: From e2283dc6c62b2b40c8d27f60a38852673059e57d Mon Sep 17 00:00:00 2001 From: github-actions Date: Thu, 19 Oct 2023 16:17:14 +0000 Subject: [PATCH 058/232] Update requirements.txt --- poetry.lock | 6 +++--- requirements-dev.txt | 2 +- requirements.txt | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index f02b6378..df621120 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1575,13 +1575,13 @@ zstd = ["zstandard (>=0.18.0)"] [[package]] name = "xarray" -version = "2023.9.0" +version = "2023.10.0" description = "N-D labeled arrays and datasets in Python" optional = false python-versions = ">=3.9" files = [ - {file = "xarray-2023.9.0-py3-none-any.whl", hash = "sha256:3fc4a558bd70968040a4e1cefc6ddb3f9a7a86ef6a48e67857156ffe655d3a66"}, - {file = "xarray-2023.9.0.tar.gz", hash = "sha256:271955c05dc626dad37791a7807d920aaf9c64cac71d03b45ec7e402cc646603"}, + {file = "xarray-2023.10.0-py3-none-any.whl", hash = "sha256:cae883c10913a081c58f38d0dc39e92cc87e0fbb43e869331c60fd0430e97fb4"}, + {file = "xarray-2023.10.0.tar.gz", hash = "sha256:69ac225b073610672e2d9e77fe18709e3b0ac0220fc8154abef87e02d97c03cf"}, ] [package.dependencies] diff --git a/requirements-dev.txt b/requirements-dev.txt index c0cfbe12..456502db 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -50,4 +50,4 @@ tqdm==4.66.1 ; python_version >= "3.10" and python_version < "3.13" typing-extensions==4.8.0 ; python_version >= "3.10" and python_version < "3.13" tzdata==2023.3 ; python_version >= "3.10" and python_version < "3.13" urllib3==2.0.7 ; python_version >= "3.10" and python_version < "3.13" -xarray==2023.9.0 ; python_version >= "3.10" and python_version < "3.13" +xarray==2023.10.0 ; python_version >= "3.10" and python_version < "3.13" diff --git a/requirements.txt b/requirements.txt index 9e5faa06..362af19c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -35,4 +35,4 @@ tqdm==4.66.1 ; python_version >= "3.10" and python_version < "3.13" typing-extensions==4.8.0 ; python_version >= "3.10" and python_version < "3.13" tzdata==2023.3 ; python_version >= "3.10" and python_version < "3.13" urllib3==2.0.7 ; python_version >= "3.10" and python_version < "3.13" -xarray==2023.9.0 ; python_version >= "3.10" and python_version < "3.13" +xarray==2023.10.0 ; python_version >= "3.10" and python_version < "3.13" From 47f7cd9250d0a8f9fc1ec1081fce0f76e29ac9c8 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Thu, 19 Oct 2023 17:49:31 +0100 Subject: [PATCH 059/232] More --- .../cart_prod/abstract_hypercylindrical_distribution.py | 4 ++-- .../distributions/circle/circular_dirac_distribution.py | 8 ++------ .../distributions/circle/circular_fourier_distribution.py | 4 ++-- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py b/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py index 241c3e7e..41bb9f60 100644 --- a/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py +++ b/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py @@ -193,10 +193,10 @@ def condition_on_periodic(self, input_periodic, normalize=True): CustomLinearDistribution instance """ assert ( - input_periodic.ndim == 1 or input_periodic.shape[0] == self.bound_dim and ndim(input_periodic) == 2 + input_periodic.ndim == 0 or input_periodic.shape[0] == self.bound_dim and ndim(input_periodic) == 2 ), "Input should be of size (lin_dim,)." - input_periodic = mod(input_periodic, 2 * pi) + input_periodic = mod(input_periodic, 2.0 * pi) def f_cond_unnorm(x, input_periodic=input_periodic): n_inputs = np.size(x) // x.shape[-1] if ndim(x) > 1 else np.size(x) diff --git a/pyrecest/distributions/circle/circular_dirac_distribution.py b/pyrecest/distributions/circle/circular_dirac_distribution.py index af8372fe..56f2e143 100644 --- a/pyrecest/distributions/circle/circular_dirac_distribution.py +++ b/pyrecest/distributions/circle/circular_dirac_distribution.py @@ -1,5 +1,3 @@ -from pyrecest.backend import squeeze -from pyrecest.backend import shape import numpy as np from beartype import beartype @@ -21,10 +19,8 @@ def __init__(self, d: np.ndarray, w: np.ndarray | None = None): super().__init__( d, w, dim=1 ) # Necessary so it is clear that the dimension is 1. - d = squeeze(d) - assert w is None or shape(d) == shape( - w - ), "The shapes of d and w should match." + d = d.squeeze() + assert w is None or d.shape == w.shape, "The shapes of d and w should match." def plot_interpolated(self, _): """ diff --git a/pyrecest/distributions/circle/circular_fourier_distribution.py b/pyrecest/distributions/circle/circular_fourier_distribution.py index 7f2f55cc..e42cfb3c 100644 --- a/pyrecest/distributions/circle/circular_fourier_distribution.py +++ b/pyrecest/distributions/circle/circular_fourier_distribution.py @@ -51,7 +51,7 @@ def __init__( warnings.warn( "It is not clear for complex ones since they may include another coefficient or not (imaginary part of the last coefficient). Assuming it is relevant." ) - self.n = 2 * np.size(c) - 1 + self.n = 2 * c.shape[0] - 1 else: self.n = n elif a is not None and b is not None: @@ -252,7 +252,7 @@ def get_a_b(self) -> tuple[np.ndarray, np.ndarray]: a = 2 * real(self.c) b = -2 * imag(self.c[1:]) assert ( - self.n is None or (np.size(a) + np.size(b)) == self.n + self.n is None or (a.shape[0] + b.shape[0]) == self.n ) # Other case not implemented yet! return a, b From 7d0cce01531b4663fe1333da18adade56e6438df Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Fri, 20 Oct 2023 12:26:23 +0100 Subject: [PATCH 060/232] More.. --- pyrecest/_backend/pytorch/random.py | 26 ++++++++++++++----- .../hypertoroidal_dirac_distribution.py | 2 +- .../filters/hypertoroidal_particle_filter.py | 4 +-- .../test_circular_fourier_distribution.py | 2 +- ...st_custom_hypercylindrical_distribution.py | 1 + .../test_hyperspherical_mixture.py | 2 +- .../test_hypertoroidal_dirac_distribution.py | 4 +-- 7 files changed, 28 insertions(+), 13 deletions(-) diff --git a/pyrecest/_backend/pytorch/random.py b/pyrecest/_backend/pytorch/random.py index 57949b45..b538a432 100644 --- a/pyrecest/_backend/pytorch/random.py +++ b/pyrecest/_backend/pytorch/random.py @@ -9,12 +9,26 @@ from ._dtype import _allow_complex_dtype, _modify_func_default_dtype -def choice(x, a): - """Generate a random sample from an array of given size.""" - if _torch.is_tensor(x): - return x[_torch.randint(len(x), (a,))] - - return x +def choice(a, size=None, replace=True, p=None): + assert _torch.is_tensor(a), "a must be a tensor" + if p is not None: + assert _torch.is_tensor(p), "p must be a tensor" + if not replace: + raise ValueError("Sampling without replacement is not supported with PyTorch when probabilities are given.") + + p = _torch.tensor(p, dtype=_torch.float32) + p = p / p.sum() # Normalize probabilities + indices = _torch.multinomial(p, num_samples=_torch.prod(size), replacement=True) + else: + indices = _torch.randint(0, len(a), size) + + result = a[indices] + + # Reshape the result to match the given size + if size is not None: + result = result.reshape(size) + + return result def seed(*args, **kwargs): diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py b/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py index 6b6bf489..edb2e218 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py @@ -93,7 +93,7 @@ def marginalize_out(self, dimensions: int | list[int]): def shift(self, shift_by) -> "HypertoroidalDiracDistribution": assert shift_by.shape[-1] == self.dim hd = copy.copy(self) - hd.d = mod(self.d + reshape(shift_by, (1, -1)), 2 * pi) + hd.d = mod(self.d + reshape(shift_by, (1, -1)), 2.0 * pi) return hd def entropy(self): diff --git a/pyrecest/filters/hypertoroidal_particle_filter.py b/pyrecest/filters/hypertoroidal_particle_filter.py index 11cd9d0c..8e743a59 100644 --- a/pyrecest/filters/hypertoroidal_particle_filter.py +++ b/pyrecest/filters/hypertoroidal_particle_filter.py @@ -72,8 +72,8 @@ def predict_nonlinear( if noise_distribution is not None: noise = noise_distribution.sample(self.filter_state.w.size) - self.filter_state.d += squeeze(noise) - self.filter_state.d = mod(self.filter_state.d, 2 * pi) + self.filter_state.d += noise.squeeze() + self.filter_state.d = mod(self.filter_state.d, 2.0 * pi) def predict_nonlinear_nonadditive( self, f: Callable, samples: np.ndarray, weights: np.ndarray diff --git a/pyrecest/tests/distributions/test_circular_fourier_distribution.py b/pyrecest/tests/distributions/test_circular_fourier_distribution.py index 8fdb5c5f..97a1436c 100644 --- a/pyrecest/tests/distributions/test_circular_fourier_distribution.py +++ b/pyrecest/tests/distributions/test_circular_fourier_distribution.py @@ -196,7 +196,7 @@ def test_distance(self, mult_by_n): ) ** 2, 0.0, - 2 * pi, + 2.0 * pi, ) fd_diff = fd1 - fd2 np.testing.assert_array_almost_equal(fd_diff.integrate(), hel_like_distance) diff --git a/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py b/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py index dee1c3ff..e0007db9 100644 --- a/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py +++ b/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py @@ -54,6 +54,7 @@ def test_condition_on_linear(self): x = linspace(0.0, 2.0 * pi, 100) np.testing.assert_allclose(dist.pdf(x), self.vm.pdf(x)) + @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") def test_condition_on_periodic(self): dist = self.chcd_vm_gauss_stacked.condition_on_periodic(array(1.0)) diff --git a/pyrecest/tests/distributions/test_hyperspherical_mixture.py b/pyrecest/tests/distributions/test_hyperspherical_mixture.py index 756150da..23a97720 100644 --- a/pyrecest/tests/distributions/test_hyperspherical_mixture.py +++ b/pyrecest/tests/distributions/test_hyperspherical_mixture.py @@ -25,7 +25,7 @@ def test_pdf_3d(self): smix = HypersphericalMixture([wad, vmf], w) phi, theta = meshgrid( - linspace(0, 2 * pi, 10), linspace(-pi / 2, pi / 2, 10) + linspace(0.0, 2.0 * pi, 10), linspace(-pi / 2.0, pi / 2.0, 10) ) points = AbstractHypersphereSubsetDistribution.polar_to_cart( stack([phi.ravel(), theta.ravel()], axis=-1) diff --git a/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py b/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py index e63549cd..48c2c1c5 100644 --- a/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py @@ -54,7 +54,7 @@ def test_marginalize_to_1D(self): for i in range(self.d.shape[-1]): wd = self.twd.marginalize_to_1D(i) np.testing.assert_array_almost_equal(self.twd.w, wd.w) - np.testing.assert_array_almost_equal(squeeze(wd.d), self.twd.d[:, i]) + np.testing.assert_array_almost_equal(wd.d, self.twd.d[:, i]) def test_apply_function(self): same = self.twd.apply_function(lambda x: x) @@ -119,7 +119,7 @@ def test_marginalization(self): hwd = TestHypertoroidalDiracDistribution.get_pseudorandom_hypertoroidal_wd(2) wd1 = hwd.marginalize_to_1D(0) wd2 = hwd.marginalize_out(1) - np.testing.assert_array_almost_equal(wd1.d, squeeze(wd2.d)) + np.testing.assert_array_almost_equal(wd1.d, wd2.d) np.testing.assert_array_almost_equal(wd1.w, wd2.w) From 65b80328af62ebb6120eea6e0d8c33195a3d1007 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Fri, 20 Oct 2023 12:33:38 +0100 Subject: [PATCH 061/232] Added nonzero to backend --- pyrecest/_backend/__init__.py | 1 + pyrecest/_backend/numpy/__init__.py | 1 + pyrecest/_backend/pytorch/__init__.py | 1 + pyrecest/distributions/abstract_dirac_distribution.py | 4 ++-- pyrecest/distributions/abstract_mixture.py | 3 ++- 5 files changed, 7 insertions(+), 3 deletions(-) diff --git a/pyrecest/_backend/__init__.py b/pyrecest/_backend/__init__.py index b75db02f..047467f1 100644 --- a/pyrecest/_backend/__init__.py +++ b/pyrecest/_backend/__init__.py @@ -169,6 +169,7 @@ def get_backend_name(): "diag", # Added for pyrecest "diff", # Added for pyrecest "apply_along_axis", # Added for pyrecest + "nonzero", # Added for pyrecest ], "autodiff": [ "custom_gradient", diff --git a/pyrecest/_backend/numpy/__init__.py b/pyrecest/_backend/numpy/__init__.py index be19eab1..d336fc0f 100644 --- a/pyrecest/_backend/numpy/__init__.py +++ b/pyrecest/_backend/numpy/__init__.py @@ -74,6 +74,7 @@ diag, # For pyrecest diff, # For pyrecest apply_along_axis, # For pyrecest + nonzero, # For pyrecest ) from scipy.special import erf, gamma, polygamma # NOQA diff --git a/pyrecest/_backend/pytorch/__init__.py b/pyrecest/_backend/pytorch/__init__.py index fe3c7fd1..00d7e1d8 100644 --- a/pyrecest/_backend/pytorch/__init__.py +++ b/pyrecest/_backend/pytorch/__init__.py @@ -35,6 +35,7 @@ quantile, diag, # For pyrecest diff, # For pyrecest + nonzero, # For pyrecest ) from torch import repeat_interleave as repeat from torch import ( diff --git a/pyrecest/distributions/abstract_dirac_distribution.py b/pyrecest/distributions/abstract_dirac_distribution.py index 6e2b5db6..395f8594 100644 --- a/pyrecest/distributions/abstract_dirac_distribution.py +++ b/pyrecest/distributions/abstract_dirac_distribution.py @@ -82,8 +82,8 @@ def reweigh(self, f: Callable) -> "AbstractDiracDistribution": return dist def sample(self, n: Union[int, int32, int64]) -> np.ndarray: - ids = random.choice(self.w.shape[0], size=n, p=self.w) - return self.d[ids] + samples = random.choice(self.d, size=n, p=self.w) + return samples def entropy(self) -> float: warnings.warn("Entropy is not defined in a continuous sense") diff --git a/pyrecest/distributions/abstract_mixture.py b/pyrecest/distributions/abstract_mixture.py index f14ddb6f..af2b92e7 100644 --- a/pyrecest/distributions/abstract_mixture.py +++ b/pyrecest/distributions/abstract_mixture.py @@ -6,6 +6,7 @@ from pyrecest.backend import int32 from pyrecest.backend import empty from pyrecest.backend import zeros +from pyrecest.backend import nonzero import collections import copy import warnings @@ -42,7 +43,7 @@ def __init__( if not all(dists[0].dim == dist.dim for dist in dists): raise ValueError("All distributions must have the same dimension") - non_zero_indices = np.nonzero(weights)[0] + non_zero_indices = nonzero(weights)[0] if len(non_zero_indices) < len(weights): warnings.warn( From 21d4362b6e195d269f5be334429516a0b58d5f19 Mon Sep 17 00:00:00 2001 From: github-actions Date: Fri, 20 Oct 2023 11:35:11 +0000 Subject: [PATCH 062/232] Update requirements.txt --- poetry.lock | 29 ++++++++++++++++------------- requirements-dev.txt | 4 ++-- requirements.txt | 4 ++-- 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/poetry.lock b/poetry.lock index df621120..52541aed 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1099,19 +1099,22 @@ files = [ [[package]] name = "pyerfa" -version = "2.0.1" +version = "2.0.1.1" description = "Python bindings for ERFA" optional = false python-versions = ">=3.9" files = [ - {file = "pyerfa-2.0.1-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:03af4032af0a1016203b3ee987448df2957dd8f6882b95f5d9cad3e5681ae30e"}, - {file = "pyerfa-2.0.1-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:378cd4bc78a6dfa4a23f950c5151ba903e0b671254c587fcfc45aa7f05bc0a09"}, - {file = "pyerfa-2.0.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb0a79635e70126b16620289b649a49a3df2e5a0ae9799e32d002101c5f181a7"}, - {file = "pyerfa-2.0.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:504272e6b05cab8060e6e699ac6c290ebbf32a31cd968b94e4b7319a6357d403"}, - {file = "pyerfa-2.0.1-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:059d1be17d3f65958e15777657b3d5a8c8f49f7b68e62887098156c6fd6e172d"}, - {file = "pyerfa-2.0.1-cp39-abi3-win32.whl", hash = "sha256:be9fb433d8a9505d82e1a2c07bdf18e683956f1f817c254775ed758756edd746"}, - {file = "pyerfa-2.0.1-cp39-abi3-win_amd64.whl", hash = "sha256:71102e79ad9913501c061706a80ccb972b7522175a7c40a1adeab6b69f0fe405"}, - {file = "pyerfa-2.0.1.tar.gz", hash = "sha256:c8572fd24ac779f067209dce1f2f6996d0701359724ecb89422ceb431632d554"}, + {file = "pyerfa-2.0.1.1-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:1ce322ac30673c2aeb0ee22ced4938c1e9e26db0cbe175912a213aaff42383df"}, + {file = "pyerfa-2.0.1.1-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:67dfc00dcdea87a9b3c0bb4596fb0cfb54ee9c1c75fdcf19411d1029a18f6eec"}, + {file = "pyerfa-2.0.1.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:34ee545780246fb0d1d3f7e46a6daa152be06a26b2d27fbfe309cab9ab488ea7"}, + {file = "pyerfa-2.0.1.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1db85db72ab352da6ffc790e41209d8f41feb5b175d682cf1f0e3e60e9e5cdf8"}, + {file = "pyerfa-2.0.1.1-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:c50b7cdb005632931b7b56a679cf25361ed6b3aa7c21e491e65cc89cb337e66a"}, + {file = "pyerfa-2.0.1.1-cp39-abi3-win32.whl", hash = "sha256:30649047b7a8ce19f43e4d18a26b8a44405a6bb406df16c687330a3b937723b2"}, + {file = "pyerfa-2.0.1.1-cp39-abi3-win_amd64.whl", hash = "sha256:94df7566ce5a5abb14e2dd1fe879204390639e9a76383ec27f10598eb24be760"}, + {file = "pyerfa-2.0.1.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0e95cf3d11f76f473bf011980e9ea367ca7e68ca675d8b32499814fb6e387d4c"}, + {file = "pyerfa-2.0.1.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08b5abb90b34e819c1fca69047a76c0d344cb0c8fe4f7c8773f032d8afd623b4"}, + {file = "pyerfa-2.0.1.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:1c0c1efa701cab986aa58d03c58f77e47ea1898bff2684377d29580a055f836a"}, + {file = "pyerfa-2.0.1.1.tar.gz", hash = "sha256:dbac74ef8d3d3b0f22ef0ad3bbbdb30b2a9e10570b1fa5a98be34c7be36c9a6b"}, ] [package.dependencies] @@ -1575,17 +1578,17 @@ zstd = ["zstandard (>=0.18.0)"] [[package]] name = "xarray" -version = "2023.10.0" +version = "2023.10.1" description = "N-D labeled arrays and datasets in Python" optional = false python-versions = ">=3.9" files = [ - {file = "xarray-2023.10.0-py3-none-any.whl", hash = "sha256:cae883c10913a081c58f38d0dc39e92cc87e0fbb43e869331c60fd0430e97fb4"}, - {file = "xarray-2023.10.0.tar.gz", hash = "sha256:69ac225b073610672e2d9e77fe18709e3b0ac0220fc8154abef87e02d97c03cf"}, + {file = "xarray-2023.10.1-py3-none-any.whl", hash = "sha256:71ea549e9be6dfeab19c2736acf659967b861aad2397691a80e5fad0c61db2ad"}, + {file = "xarray-2023.10.1.tar.gz", hash = "sha256:9eeee170c3fc2f3321eb6ba40c17ffe4d8c98d49d55e4a3fba66a75bdc7dd9e5"}, ] [package.dependencies] -numpy = ">=1.21" +numpy = ">=1.22" packaging = ">=21.3" pandas = ">=1.4" diff --git a/requirements-dev.txt b/requirements-dev.txt index 456502db..1dc0d91b 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -30,7 +30,7 @@ platformdirs==3.11.0 ; python_version >= "3.10" and python_version < "3.13" pluggy==1.3.0 ; python_version >= "3.10" and python_version < "3.13" pooch==1.7.0 ; python_version >= "3.10" and python_version < "3.13" pycodestyle==2.11.1 ; python_version >= "3.10" and python_version < "3.13" -pyerfa==2.0.1 ; python_version >= "3.10" and python_version < "3.13" +pyerfa==2.0.1.1 ; python_version >= "3.10" and python_version < "3.13" pyparsing==3.1.1 ; python_version >= "3.10" and python_version < "3.13" pyshtools==4.10.4 ; python_version >= "3.10" and python_version < "3.13" pytest==7.4.2 ; python_version >= "3.10" and python_version < "3.13" @@ -50,4 +50,4 @@ tqdm==4.66.1 ; python_version >= "3.10" and python_version < "3.13" typing-extensions==4.8.0 ; python_version >= "3.10" and python_version < "3.13" tzdata==2023.3 ; python_version >= "3.10" and python_version < "3.13" urllib3==2.0.7 ; python_version >= "3.10" and python_version < "3.13" -xarray==2023.10.0 ; python_version >= "3.10" and python_version < "3.13" +xarray==2023.10.1 ; python_version >= "3.10" and python_version < "3.13" diff --git a/requirements.txt b/requirements.txt index 362af19c..69691cb2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -18,7 +18,7 @@ pandas==2.1.1 ; python_version >= "3.10" and python_version < "3.13" pillow==10.1.0 ; python_version >= "3.10" and python_version < "3.13" platformdirs==3.11.0 ; python_version >= "3.10" and python_version < "3.13" pooch==1.7.0 ; python_version >= "3.10" and python_version < "3.13" -pyerfa==2.0.1 ; python_version >= "3.10" and python_version < "3.13" +pyerfa==2.0.1.1 ; python_version >= "3.10" and python_version < "3.13" pyparsing==3.1.1 ; python_version >= "3.10" and python_version < "3.13" pyshtools==4.10.4 ; python_version >= "3.10" and python_version < "3.13" python-dateutil==2.8.2 ; python_version >= "3.10" and python_version < "3.13" @@ -35,4 +35,4 @@ tqdm==4.66.1 ; python_version >= "3.10" and python_version < "3.13" typing-extensions==4.8.0 ; python_version >= "3.10" and python_version < "3.13" tzdata==2023.3 ; python_version >= "3.10" and python_version < "3.13" urllib3==2.0.7 ; python_version >= "3.10" and python_version < "3.13" -xarray==2023.10.0 ; python_version >= "3.10" and python_version < "3.13" +xarray==2023.10.1 ; python_version >= "3.10" and python_version < "3.13" From b1420d883274eedf765281ed0bd2e9caceb86b70 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Fri, 20 Oct 2023 14:38:53 +0100 Subject: [PATCH 063/232] More --- pyrecest/_backend/__init__.py | 1 + pyrecest/_backend/numpy/__init__.py | 1 + pyrecest/_backend/pytorch/__init__.py | 19 +++--- .../circle/abstract_circular_distribution.py | 2 +- .../abstract_hypertoroidal_distribution.py | 3 +- .../abstract_linear_distribution.py | 15 ++--- .../nonperiodic/custom_linear_distribution.py | 2 +- .../filters/hypertoroidal_particle_filter.py | 2 +- pyrecest/filters/wrapped_normal_filter.py | 2 +- .../test_abstract_linear_distribution.py | 8 ++- .../test_circular_fourier_distribution.py | 10 ++-- .../test_wrapped_laplace_distribution.py | 15 ++--- .../test_wrapped_normal_distribution.py | 8 +-- .../filters/test_wrapped_normal_filter.py | 59 +++++++++---------- 14 files changed, 77 insertions(+), 70 deletions(-) diff --git a/pyrecest/_backend/__init__.py b/pyrecest/_backend/__init__.py index 047467f1..096707f5 100644 --- a/pyrecest/_backend/__init__.py +++ b/pyrecest/_backend/__init__.py @@ -170,6 +170,7 @@ def get_backend_name(): "diff", # Added for pyrecest "apply_along_axis", # Added for pyrecest "nonzero", # Added for pyrecest + "column_stack", # Added for pyrecest ], "autodiff": [ "custom_gradient", diff --git a/pyrecest/_backend/numpy/__init__.py b/pyrecest/_backend/numpy/__init__.py index d336fc0f..7b8d7a5d 100644 --- a/pyrecest/_backend/numpy/__init__.py +++ b/pyrecest/_backend/numpy/__init__.py @@ -75,6 +75,7 @@ diff, # For pyrecest apply_along_axis, # For pyrecest nonzero, # For pyrecest + column_stack, # For pyrecest ) from scipy.special import erf, gamma, polygamma # NOQA diff --git a/pyrecest/_backend/pytorch/__init__.py b/pyrecest/_backend/pytorch/__init__.py index 00d7e1d8..2a738ee5 100644 --- a/pyrecest/_backend/pytorch/__init__.py +++ b/pyrecest/_backend/pytorch/__init__.py @@ -36,6 +36,7 @@ diag, # For pyrecest diff, # For pyrecest nonzero, # For pyrecest + column_stack, # For pyrecest ) from torch import repeat_interleave as repeat from torch import ( @@ -385,12 +386,16 @@ def trace(x): return _torch.einsum("...ii", x) -def linspace(start, stop, num=50, dtype=None): +def linspace(start, stop, endpoint=True, num=50, dtype=None): start_is_array = _torch.is_tensor(start) stop_is_array = _torch.is_tensor(stop) - if not (start_is_array or stop_is_array): + if not (start_is_array or stop_is_array) and endpoint: return _torch.linspace(start=start, end=stop, steps=num, dtype=dtype) + elif not (start_is_array or stop_is_array): # Added for pyrecest + return _torch.arange(start=start, end=stop, step=(stop-start)/num, dtype=dtype) + else: + raise ValueError("endpoint=False not supported for vectors") if not start_is_array: start = _torch.tensor(start) @@ -696,7 +701,7 @@ def triu_to_vec(x, k=0): return x[..., rows, cols] -def mat_from_diag_triu_tril(diag, tri_upp, tri_low): +def mat_from_diag_triu_tril(diag_entries, tri_upp, tri_low): """Build matrix from given components. Forms a matrix from diagonal, strictly upper triangular and @@ -712,13 +717,13 @@ def mat_from_diag_triu_tril(diag, tri_upp, tri_low): ------- mat : array_like, shape=[..., n, n] """ - diag, tri_upp, tri_low = convert_to_wider_dtype([diag, tri_upp, tri_low]) + diag_entries, tri_upp, tri_low = convert_to_wider_dtype([diag_entries, tri_upp, tri_low]) - n = diag.shape[-1] + n = diag_entries.shape[-1] (i,) = diag_indices(n, ndim=1) j, k = triu_indices(n, k=1) - mat = _torch.zeros((diag.shape + (n,)), dtype=diag.dtype) - mat[..., i, i] = diag + mat = _torch.zeros((diag_entries.shape + (n,)), dtype=diag_entries.dtype) + mat[..., i, i] = diag_entries mat[..., j, k] = tri_upp mat[..., k, j] = tri_low return mat diff --git a/pyrecest/distributions/circle/abstract_circular_distribution.py b/pyrecest/distributions/circle/abstract_circular_distribution.py index 81a9d5f2..0830324d 100644 --- a/pyrecest/distributions/circle/abstract_circular_distribution.py +++ b/pyrecest/distributions/circle/abstract_circular_distribution.py @@ -74,6 +74,6 @@ def to_wn(self): @staticmethod def plot_circle(*args, **kwargs): - theta = np.append(linspace(0, 2 * pi, 320), 0) + theta = np.append(linspace(0.0, 2.0 * pi, 320), 0) p = plt.plot(cos(theta), sin(theta), *args, **kwargs) return p \ No newline at end of file diff --git a/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py b/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py index a479fdf0..2c819ba1 100644 --- a/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py +++ b/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py @@ -85,11 +85,12 @@ def integrate_fun_over_domain_part( return nquad(f, integration_boundaries)[0] def integrate_numerically( + assert pyrecest.backend.__name__ == 'pyrecest.numpy', "Only supported for numpy backend" self, integration_boundaries=None ) -> np.number | numbers.Real: if integration_boundaries is None: integration_boundaries = vstack( - (zeros(self.dim), 2 * pi * ones(self.dim)) + (zeros(self.dim), 2.0 * pi * ones(self.dim)) ) integration_boundaries = reshape(integration_boundaries, (2, -1)) diff --git a/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py b/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py index 2e2f08ef..8f062dd5 100644 --- a/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py +++ b/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py @@ -9,6 +9,8 @@ from pyrecest.backend import array from pyrecest.backend import int64 from pyrecest.backend import int32 +from pyrecest.backend import column_stack +import pyrecest.backend import numbers from collections.abc import Callable @@ -43,9 +45,10 @@ def mode(self, starting_point=None): return self.mode_numerical(starting_point) def mode_numerical(self, starting_point=None): + assert pyrecest.backend.__name__ == 'pyrecest.numpy', "Only supported for numpy backend" if starting_point is None: # Ensure 1-D for minimize - starting_point = squeeze(self.sample(1)) + starting_point = self.sample(1).squeeze() def neg_pdf(x): return -self.pdf(x) @@ -87,10 +90,10 @@ def proposal(x): ) def mean_numerical(self): + mu = empty(self.dim) if self.dim == 1: - mu = quad(lambda x: x * self.pdf(x), -np.inf, np.inf)[0] + mu = quad(lambda x: x * self.pdf(x), array(-float('inf')), array(float('inf')))[0] elif self.dim == 2: - mu = array([np.NaN, np.NaN]) mu[0] = dblquad( lambda x, y: x * self.pdf(array([x, y])), -np.inf, @@ -106,8 +109,6 @@ def mean_numerical(self): lambda _: np.inf, )[0] elif self.dim == 3: - mu = array([np.NaN, np.NaN, np.NaN]) - def integrand1(x, y, z): return x * self.pdf(array([x, y, z])) @@ -137,7 +138,7 @@ def covariance_numerical(self): if self.dim == 1: C = quad(lambda x: (x - mu) ** 2 * self.pdf(x), -np.inf, np.inf)[0] elif self.dim == 2: - C = array([[np.NaN, np.NaN], [np.NaN, np.NaN]]) + C = empty((2, 2)) def integrand1(x, y): return (x - mu[0]) ** 2 * self.pdf(array([x, y])) @@ -247,7 +248,7 @@ def plot(self, *args, plot_range=None, **kwargs): x = linspace(plot_range[0], plot_range[1], 100) y = linspace(plot_range[2], plot_range[3], 100) x_grid, y_grid = meshgrid(x, y) - z_grid = self.pdf(np.column_stack((x_grid.ravel(), y_grid.ravel()))) + z_grid = self.pdf(column_stack((x_grid.ravel(), y_grid.ravel()))) ax = plt.axes(projection="3d") ax.plot_surface( diff --git a/pyrecest/distributions/nonperiodic/custom_linear_distribution.py b/pyrecest/distributions/nonperiodic/custom_linear_distribution.py index c273fff5..70b61042 100644 --- a/pyrecest/distributions/nonperiodic/custom_linear_distribution.py +++ b/pyrecest/distributions/nonperiodic/custom_linear_distribution.py @@ -37,7 +37,7 @@ def __init__(self, f, dim, scale_by=1, shift_by=None): self.shift_by = zeros(dim) def shift(self, shift_by): - assert self.dim == np.size(shift_by) and shift_by.ndim <= 1 + assert self.dim == 1 or self.dim == shift_by.shape[0] and shift_by.ndim == 1 cd = copy.deepcopy(self) cd.shift_by = self.shift_by + shift_by return cd diff --git a/pyrecest/filters/hypertoroidal_particle_filter.py b/pyrecest/filters/hypertoroidal_particle_filter.py index 8e743a59..b0b289fd 100644 --- a/pyrecest/filters/hypertoroidal_particle_filter.py +++ b/pyrecest/filters/hypertoroidal_particle_filter.py @@ -38,7 +38,7 @@ def __init__( if dim == 1: # Prevents ambiguities if a vector is of size (dim,) or (n,) (for dim=1) filter_state = CircularDiracDistribution( - arange(0.0, 2.0 * pi, n_particles) # Like linspace without endpoint but with compatbiility for pytroch + linspace(0.0, 2.0 * pi, num = n_particles, endpoint=False) # Like linspace without endpoint but with compatbiility for pytroch ) else: filter_state = HypertoroidalDiracDistribution( diff --git a/pyrecest/filters/wrapped_normal_filter.py b/pyrecest/filters/wrapped_normal_filter.py index 750c15c4..f10f1843 100644 --- a/pyrecest/filters/wrapped_normal_filter.py +++ b/pyrecest/filters/wrapped_normal_filter.py @@ -14,7 +14,7 @@ class WrappedNormalFilter(AbstractCircularFilter): def __init__(self, wn=None): """Initialize the filter.""" if wn is None: - wn = WrappedNormalDistribution(0, 1) + wn = WrappedNormalDistribution(array(0.0), array(1.0)) AbstractCircularFilter.__init__(self, wn) def predict_identity(self, wn_sys): diff --git a/pyrecest/tests/distributions/test_abstract_linear_distribution.py b/pyrecest/tests/distributions/test_abstract_linear_distribution.py index 7484b043..e171e0a7 100644 --- a/pyrecest/tests/distributions/test_abstract_linear_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_linear_distribution.py @@ -2,6 +2,7 @@ from pyrecest.backend import squeeze from pyrecest.backend import isclose from pyrecest.backend import array +import pyrecest.backend import unittest import matplotlib @@ -48,11 +49,12 @@ def f(x): integration_result, 0.3, rtol=1e-5 ), f"Expected 0.3, but got {integration_result}" + @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") def test_mode_numerical_custom_1D(self): cd = CustomLinearDistribution( - lambda x: squeeze( - ((x > -1.0) & (x <= 0.0)) * (1.0 + x) + ((x > 0.0) & (x <= 1.0)) * (1 - x) - ), + lambda x: array( + ((x > -1.0) & (x <= 0.0)) * (1.0 + x) + ((x > 0.0) & (x <= 1.0)) * (1.0 - x) + ).squeeze(), 1, ) cd = cd.shift(array(0.5)) diff --git a/pyrecest/tests/distributions/test_circular_fourier_distribution.py b/pyrecest/tests/distributions/test_circular_fourier_distribution.py index 97a1436c..eeeb693d 100644 --- a/pyrecest/tests/distributions/test_circular_fourier_distribution.py +++ b/pyrecest/tests/distributions/test_circular_fourier_distribution.py @@ -81,7 +81,7 @@ def test_fourier_conversion( ] ) def test_vm_to_fourier(self, mult_by_n, transformation): - xs = linspace(0, 2 * pi, 100) + xs = linspace(0.0, 2.0 * pi, 100) dist = VonMisesDistribution(2.5, 1.5) fd = CircularFourierDistribution.from_distribution( dist, @@ -166,8 +166,8 @@ def test_integrate(self, mult_by_n, transformation): fd_norm = fd_unnorm.normalize() fd_unnorm_real = fd_unnorm.to_real_fd() fd_norm_real = fd_unnorm_real.normalize() - np.testing.assert_array_almost_equal(fd_norm.integrate(), 1) - np.testing.assert_array_almost_equal(fd_norm_real.integrate(), 1) + np.testing.assert_array_almost_equal(fd_norm.integrate(), 1.0) + np.testing.assert_array_almost_equal(fd_norm_real.integrate(), 1.0) @parameterized.expand( [ @@ -176,8 +176,8 @@ def test_integrate(self, mult_by_n, transformation): ] ) def test_distance(self, mult_by_n): - dist1 = VonMisesDistribution(0.0, 1.0) - dist2 = VonMisesDistribution(2.0, 1.0) + dist1 = VonMisesDistribution(array(0.0), array(1.0)) + dist2 = VonMisesDistribution(array(2.0), array(1.0)) fd1 = CircularFourierDistribution.from_distribution( dist1, n=31, diff --git a/pyrecest/tests/distributions/test_wrapped_laplace_distribution.py b/pyrecest/tests/distributions/test_wrapped_laplace_distribution.py index 4f0f9df4..6ff82f28 100644 --- a/pyrecest/tests/distributions/test_wrapped_laplace_distribution.py +++ b/pyrecest/tests/distributions/test_wrapped_laplace_distribution.py @@ -2,6 +2,7 @@ from pyrecest.backend import linspace from pyrecest.backend import exp from pyrecest.backend import arange +from pyrecest.backend import array import unittest import numpy as np @@ -12,8 +13,8 @@ class WrappedLaplaceDistributionTest(unittest.TestCase): def setUp(self): - self.lambda_ = 2 - self.kappa = 1.3 + self.lambda_ = array(2.0) + self.kappa = array(1.3) self.wl = WrappedLaplaceDistribution(self.lambda_, self.kappa) def test_pdf(self): @@ -31,16 +32,16 @@ def laplace(x): ) def pdftemp(x): - return sum(laplace(z) for z in x + 2 * pi * arange(-20, 21)) + return sum(laplace(z) for z in x + 2.0 * pi * arange(-20, 21)) - for x in [0, 1, 2, 3, 4]: + for x in [0.0, 1.0, 2.0, 3.0, 4.0]: np.testing.assert_allclose(self.wl.pdf(x), pdftemp(x), rtol=1e-10) def test_integral(self): - np.testing.assert_allclose(self.wl.integrate(), 1, rtol=1e-10) - np.testing.assert_allclose(self.wl.integrate_numerically(), 1, rtol=1e-10) + np.testing.assert_allclose(self.wl.integrate(), 1.0, rtol=1e-10) + np.testing.assert_allclose(self.wl.integrate_numerically(), 1.0, rtol=1e-10) np.testing.assert_allclose( - self.wl.integrate([0, pi]) + self.wl.integrate([pi, 2 * pi]), + self.wl.integrate(array([0.0, pi])) + self.wl.integrate(array([pi, 2.0 * pi])), 1, rtol=1e-10, ) diff --git a/pyrecest/tests/distributions/test_wrapped_normal_distribution.py b/pyrecest/tests/distributions/test_wrapped_normal_distribution.py index a076c988..2613b250 100644 --- a/pyrecest/tests/distributions/test_wrapped_normal_distribution.py +++ b/pyrecest/tests/distributions/test_wrapped_normal_distribution.py @@ -17,8 +17,8 @@ class WrappedNormalDistributionTest(unittest.TestCase): def setUp(self): - self.mu = 3 - self.sigma = 1.5 + self.mu = array(3.0) + self.sigma = array(1.5) self.wn = WrappedNormalDistribution(self.mu, self.sigma) def test_pdf_values_are_as_expected(self): @@ -36,8 +36,8 @@ def approx_with_wrapping(x): test_points = [self.mu, self.mu - 1, self.mu + 2] for point in test_points: with self.subTest(x=point): - self.assertAlmostEqual( - self.wn.pdf(point), approx_with_wrapping(point), places=10 + np.testing.assert_almost_equal( + self.wn.pdf(point), approx_with_wrapping(point), decimal=10 ) x = arange(0, 7) diff --git a/pyrecest/tests/filters/test_wrapped_normal_filter.py b/pyrecest/tests/filters/test_wrapped_normal_filter.py index a8042661..5deab62e 100644 --- a/pyrecest/tests/filters/test_wrapped_normal_filter.py +++ b/pyrecest/tests/filters/test_wrapped_normal_filter.py @@ -1,54 +1,49 @@ import unittest - +from pyrecest.backend import array import numpy as np from pyrecest.distributions import WrappedNormalDistribution from pyrecest.filters.wrapped_normal_filter import WrappedNormalFilter class WrappedNormalFilterTest(unittest.TestCase): - def test_initialization(self): - wn_filter = WrappedNormalFilter() - wn = WrappedNormalDistribution(1.3, 0.8) - # Sanity check - wn_filter.filter_state = wn - wn1 = wn_filter.filter_state + def setUp(self): + self.wn_filter = WrappedNormalFilter() + self.wn = WrappedNormalDistribution(array(1.3), array(0.8)) + self.meas_noise = WrappedNormalDistribution(array(0.0), array(0.9)) + self.wn_filter.filter_state = self.wn + + def test_initialization(self): + wn1 = self.wn_filter.filter_state self.assertIsInstance(wn1, WrappedNormalDistribution) - self.assertEqual(wn.mu, wn1.mu) - self.assertEqual(wn.sigma, wn1.sigma) + self.assertEqual(self.wn.mu, wn1.mu) + self.assertEqual(self.wn.sigma, wn1.sigma) def test_predict_identity(self): - wn_filter = WrappedNormalFilter() - wn = WrappedNormalDistribution(1.3, 0.8) - - wn_filter.filter_state = wn - wn_filter.predict_identity(WrappedNormalDistribution(0, wn.sigma)) - wn_identity = wn_filter.filter_state + self.wn_filter.predict_identity(WrappedNormalDistribution(array(0.0), self.wn.sigma)) + wn_identity = self.wn_filter.filter_state self.assertIsInstance(wn_identity, WrappedNormalDistribution) - self.assertEqual(wn.mu, wn_identity.mu) - self.assertLess(wn.sigma, wn_identity.sigma) + self.assertEqual(self.wn.mu, wn_identity.mu) + self.assertLess(self.wn.sigma, wn_identity.sigma) def test_update(self): - wn_filter = WrappedNormalFilter() - wn = WrappedNormalDistribution(1.3, 0.8) - meas_noise = WrappedNormalDistribution(0, 0.9) - # update identity - wn_filter.filter_state = wn - wn_filter.update_identity(meas_noise, wn.mu) - wn_identity = wn_filter.filter_state + self.wn_filter.update_identity(self.meas_noise, self.wn.mu) + wn_identity = self.wn_filter.filter_state self.assertIsInstance(wn_identity, WrappedNormalDistribution) - np.testing.assert_almost_equal(wn.mu, wn_identity.mu) - self.assertGreater(wn.sigma, wn_identity.sigma) + np.testing.assert_almost_equal(self.wn.mu, wn_identity.mu) + self.assertGreater(self.wn.sigma, wn_identity.sigma) + + # reset filter state for the next test within this function + self.wn_filter.filter_state = self.wn # update identity with different measurement - wn_filter.filter_state = wn - wn_filter.update_identity(meas_noise, wn.mu + 0.1) - wn_identity2 = wn_filter.filter_state + self.wn_filter.update_identity(self.meas_noise, self.wn.mu + 0.1) + wn_identity2 = self.wn_filter.filter_state self.assertIsInstance(wn_identity2, WrappedNormalDistribution) - self.assertLess(wn.mu, wn_identity2.mu) - self.assertGreater(wn.sigma, wn_identity2.sigma) + self.assertLess(self.wn.mu, wn_identity2.mu) + self.assertGreater(self.wn.sigma, wn_identity2.sigma) if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() From 45549d583d132db75dd8827d01004053feaba613 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Fri, 20 Oct 2023 16:55:44 +0100 Subject: [PATCH 064/232] More --- ...abstract_manifold_specific_distribution.py | 2 +- .../circle/abstract_circular_distribution.py | 5 +--- .../abstract_hypertoroidal_distribution.py | 25 ++++++++++--------- .../test_abstract_circular_distribution.py | 2 ++ 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/pyrecest/distributions/abstract_manifold_specific_distribution.py b/pyrecest/distributions/abstract_manifold_specific_distribution.py index 03dfd474..d369a326 100644 --- a/pyrecest/distributions/abstract_manifold_specific_distribution.py +++ b/pyrecest/distributions/abstract_manifold_specific_distribution.py @@ -44,7 +44,7 @@ def input_dim(self) -> int: pass @abstractmethod - def pdf(self, xs: np.ndarray) -> np.ndarray: + def pdf(self, xs): pass @abstractmethod diff --git a/pyrecest/distributions/circle/abstract_circular_distribution.py b/pyrecest/distributions/circle/abstract_circular_distribution.py index 0830324d..e9cf546a 100644 --- a/pyrecest/distributions/circle/abstract_circular_distribution.py +++ b/pyrecest/distributions/circle/abstract_circular_distribution.py @@ -10,10 +10,7 @@ import numpy as np from beartype import beartype -from ..hypertorus.abstract_hypertoroidal_distribution import ( - AbstractHypertoroidalDistribution, -) - +from ..hypertorus.abstract_hypertoroidal_distribution import AbstractHypertoroidalDistribution class AbstractCircularDistribution(AbstractHypertoroidalDistribution): def __init__(self): diff --git a/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py b/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py index 2c819ba1..5a4aa69a 100644 --- a/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py +++ b/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py @@ -18,6 +18,7 @@ from pyrecest.backend import int64 from pyrecest.backend import int32 from pyrecest.backend import zeros +import pyrecest.backend import numbers from collections.abc import Callable @@ -41,7 +42,7 @@ def input_dim(self) -> int: @staticmethod def integrate_fun_over_domain(f: Callable, dim: Union[int, int32, int64]) -> float: - integration_boundaries = [(0, 2 * pi)] * dim + integration_boundaries = [(0.0, 2 * pi)] * dim return AbstractHypertoroidalDistribution.integrate_fun_over_domain_part( f, dim, integration_boundaries ) @@ -85,9 +86,9 @@ def integrate_fun_over_domain_part( return nquad(f, integration_boundaries)[0] def integrate_numerically( - assert pyrecest.backend.__name__ == 'pyrecest.numpy', "Only supported for numpy backend" self, integration_boundaries=None ) -> np.number | numbers.Real: + assert pyrecest.backend.__name__ == 'pyrecest.numpy', "Only supported for numpy backend" if integration_boundaries is None: integration_boundaries = vstack( (zeros(self.dim), 2.0 * pi * ones(self.dim)) @@ -139,7 +140,7 @@ def entropy_fun(*args): return -self.integrate_fun_over_domain(entropy_fun, self.dim) def get_manifold_size(self): - return (2 * pi) ** self.dim + return (2.0 * pi) ** self.dim @staticmethod def angular_error(alpha, beta): @@ -155,14 +156,14 @@ def angular_error(alpha, beta): """ assert not isnan(alpha).any() and not isnan(beta).any() # Ensure the angles are between 0 and 2*pi - alpha = mod(alpha, 2 * pi) - beta = mod(beta, 2 * pi) + alpha = mod(alpha, 2.0 * pi) + beta = mod(beta, 2.0 * pi) # Calculate the absolute difference diff = abs(alpha - beta) # Calculate the angular error - e = np.minimum(diff, 2 * pi - diff) + e = np.minimum(diff, 2.0 * pi - diff) return e @@ -194,14 +195,14 @@ def total_variation_dist_fun(*args): def plot(self, resolution=128, **kwargs): if self.dim == 1: - theta = linspace(0, 2 * pi, resolution) + theta = linspace(0.0, 2 * pi, resolution) f_theta = self.pdf(theta) p = plt.plot(theta, f_theta, **kwargs) AbstractHypertoroidalDistribution.setup_axis_circular("x") elif self.dim == 2: step = 2 * pi / resolution alpha, beta = meshgrid( - arange(0, 2 * pi, step), arange(0, 2 * pi, step) + arange(0.0, 2.0 * pi, step), arange(0.0, 2.0 * pi, step) ) f = self.pdf(vstack((alpha.ravel(), beta.ravel()))) f = f.reshape(alpha.shape) @@ -276,18 +277,18 @@ def proposal(x): @staticmethod def setup_axis_circular(axis_name: str = "x", ax=plt.gca()) -> None: - ticks = [0, pi, 2 * pi] + ticks = [0.0, pi, 2.0 * pi] tick_labels = ["0", r"$\pi$", r"$2\pi$"] if axis_name == "x": - ax.set_xlim(left=0, right=2 * pi) + ax.set_xlim(left=0.0, right=2.0 * pi) ax.set_xticks(ticks) ax.set_xticklabels(tick_labels) elif axis_name == "y": - ax.set_ylim(left=0, right=2 * pi) + ax.set_ylim(left=0.0, right=2.0 * pi) ax.set_yticks(ticks) ax.set_yticklabels(tick_labels) elif axis_name == "z": - ax.set_zlim(left=0, right=2 * pi) + ax.set_zlim(left=0.0, right=2.0 * pi) ax.set_zticks(ticks) ax.set_zticklabels(tick_labels) else: diff --git a/pyrecest/tests/distributions/test_abstract_circular_distribution.py b/pyrecest/tests/distributions/test_abstract_circular_distribution.py index 0d145c5d..c8286142 100644 --- a/pyrecest/tests/distributions/test_abstract_circular_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_circular_distribution.py @@ -3,6 +3,7 @@ from pyrecest.backend import allclose from pyrecest.backend import all from pyrecest.backend import array +import pyrecest.backend import unittest import numpy as np @@ -16,6 +17,7 @@ def setUp(self): VonMisesDistribution(array(6.0), array(1.2)), ] + @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") def test_cdf_numerical(self): """Tests if the numerical computation of cdf matches the actual cdf.""" x = arange(0, 7) From 73c2dfc6c3383ecd54a1572ee99cc988915080bd Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Sat, 21 Oct 2023 09:59:17 +0100 Subject: [PATCH 065/232] More.... --- pyrecest/_backend/__init__.py | 1 + pyrecest/_backend/numpy/__init__.py | 1 + pyrecest/_backend/pytorch/__init__.py | 1 + .../abstract_custom_distribution.py | 7 ++-- .../abstract_dirac_distribution.py | 7 ++-- .../abstract_disk_distribution.py | 1 - .../abstract_ellipsoidal_ball_distribution.py | 5 +-- ...abstract_manifold_specific_distribution.py | 11 +++-- pyrecest/distributions/abstract_mixture.py | 6 +-- .../abstract_orthogonal_basis_distribution.py | 5 +-- .../abstract_periodic_distribution.py | 9 ++-- .../abstract_se3_distribution.py | 4 +- .../abstract_uniform_distribution.py | 14 +++---- .../abstract_hypercylindrical_distribution.py | 24 +++++------ ...ract_lin_bounded_cart_prod_distribution.py | 4 +- ...act_lin_periodic_cart_prod_distribution.py | 4 +- .../cart_prod_stacked_distribution.py | 4 +- .../hypercylindrical_dirac_distribution.py | 2 +- ...in_bounded_cart_prod_dirac_distribution.py | 2 +- ...ypersphere_cart_prod_dirac_distribution.py | 2 +- ...n_hypersphere_subset_dirac_distribution.py | 2 +- .../partially_wrapped_normal_distribution.py | 8 ++-- .../circle/abstract_circular_distribution.py | 14 +++---- .../circle/circular_dirac_distribution.py | 8 ++-- .../circle/circular_fourier_distribution.py | 34 ++++++++------- .../distributions/circle/circular_mixture.py | 4 +- .../circle/circular_uniform_distribution.py | 2 +- .../circle/custom_circular_distribution.py | 12 +++--- .../circle/von_mises_distribution.py | 16 +++---- .../circle/wrapped_cauchy_distribution.py | 2 +- .../circle/wrapped_laplace_distribution.py | 2 +- .../circle/wrapped_normal_distribution.py | 16 +++---- .../custom_hyperrectangular_distribution.py | 6 +-- .../disk_uniform_distribution.py | 2 +- .../ellipsoidal_ball_uniform_distribution.py | 6 +-- ...bstract_hyperhemispherical_distribution.py | 20 ++++----- ...t_hypersphere_subset_dirac_distribution.py | 2 +- ...bstract_hypersphere_subset_distribution.py | 12 +++--- ...hypersphere_subset_uniform_distribution.py | 8 ++-- .../abstract_hyperspherical_distribution.py | 16 +++---- .../abstract_sphere_subset_distribution.py | 28 ++++++------- ...stract_spherical_harmonics_distribution.py | 2 +- .../bingham_distribution.py | 4 +- .../custom_hyperhemispherical_distribution.py | 2 +- ...hyperhemispherical_uniform_distribution.py | 4 +- .../hyperhemispherical_watson_distribution.py | 14 +++---- .../hyperspherical_dirac_distribution.py | 2 +- .../hyperspherical_mixture.py | 2 +- .../hyperspherical_uniform_distribution.py | 4 +- ...pherical_harmonics_distribution_complex.py | 2 +- .../spherical_harmonics_distribution_real.py | 2 +- .../von_mises_fisher_distribution.py | 14 +++---- .../hypersphere_subset/watson_distribution.py | 6 +-- .../abstract_hypertoroidal_distribution.py | 24 +++++------ .../abstract_toroidal_distribution.py | 6 +-- .../custom_hypertoroidal_distribution.py | 4 +- .../hypertoroidal_dirac_distribution.py | 8 ++-- .../hypertorus/hypertoroidal_mixture.py | 6 +-- .../hypertoroidal_uniform_distribution.py | 10 ++--- ...pertoroidal_wrapped_normal_distribution.py | 6 +-- .../hypertorus/toroidal_dirac_distribution.py | 6 +-- .../hypertorus/toroidal_mixture.py | 4 +- .../toroidal_von_mises_sine_distribution.py | 2 +- .../toroidal_wrapped_normal_distribution.py | 6 +-- .../abstract_linear_distribution.py | 42 +++++++++---------- .../nonperiodic/custom_linear_distribution.py | 2 +- .../nonperiodic/gaussian_distribution.py | 4 +- .../nonperiodic/gaussian_mixture.py | 6 +-- .../nonperiodic/linear_dirac_distribution.py | 2 +- .../nonperiodic/linear_mixture.py | 4 +- .../se3_cart_prod_stacked_distribution.py | 4 +- .../distributions/se3_dirac_distribution.py | 4 +- .../evaluation/determine_all_deviations.py | 12 +++--- pyrecest/evaluation/eot_shape_database.py | 6 +-- pyrecest/evaluation/evaluate_for_file.py | 12 +++--- .../evaluate_for_simulation_config.py | 12 +++--- pyrecest/evaluation/evaluate_for_variables.py | 2 +- pyrecest/evaluation/generate_groundtruth.py | 6 +-- pyrecest/evaluation/generate_measurements.py | 4 +- .../generate_simulated_scenarios.py | 6 +-- pyrecest/evaluation/get_distance_function.py | 2 +- .../evaluation/iterate_configs_and_runs.py | 2 +- .../perform_predict_update_cycles.py | 2 +- pyrecest/evaluation/plot_results.py | 2 +- pyrecest/evaluation/simulation_database.py | 2 +- .../evaluation/summarize_filter_results.py | 2 +- .../filters/abstract_hypertoroidal_filter.py | 4 +- .../abstract_nearest_neighbor_tracker.py | 2 +- pyrecest/filters/abstract_particle_filter.py | 2 +- .../filters/abstract_tracker_with_logging.py | 2 +- pyrecest/filters/circular_particle_filter.py | 2 +- pyrecest/filters/euclidean_particle_filter.py | 2 +- pyrecest/filters/global_nearest_neighbor.py | 2 +- .../filters/hypertoroidal_particle_filter.py | 4 +- pyrecest/filters/kalman_filter.py | 24 +++++------ pyrecest/filters/random_matrix_tracker.py | 2 +- pyrecest/filters/toroidal_particle_filter.py | 2 +- .../filters/toroidal_wrapped_normal_filter.py | 2 +- pyrecest/filters/von_mises_filter.py | 2 +- pyrecest/filters/von_mises_fisher_filter.py | 2 +- pyrecest/filters/wrapped_normal_filter.py | 10 ++--- pyrecest/sampling/abstract_sampler.py | 4 +- pyrecest/sampling/euclidean_sampler.py | 4 +- pyrecest/sampling/hyperspherical_sampler.py | 27 ++++++------ pyrecest/sampling/hypertoroidal_sampler.py | 4 +- .../test_abstract_circular_distribution.py | 2 +- ..._abstract_hypercylindrical_distribution.py | 2 +- ...bstract_hyperhemispherical_distribution.py | 2 +- ...bstract_hypersphere_subset_distribution.py | 2 +- ...st_abstract_hyperspherical_distribution.py | 2 +- ...est_abstract_hypertoroidal_distribution.py | 2 +- .../test_abstract_linear_distribution.py | 6 +-- .../distributions/test_abstract_mixture.py | 2 +- .../test_bingham_distribution.py | 2 +- .../test_circular_fourier_distribution.py | 25 ++++++----- .../test_circular_uniform_distribution.py | 2 +- .../test_custom_hemispherical_distribution.py | 2 +- ...st_custom_hypercylindrical_distribution.py | 2 +- ...st_custom_hyperrectangular_distribution.py | 2 +- ...test_custom_hyperspherical_distribution.py | 2 +- .../test_custom_linear_distribution.py | 2 +- .../test_disk_uniform_distribution.py | 2 +- ...t_ellipsoidal_ball_uniform_distribution.py | 2 +- .../test_gaussian_distribution.py | 4 +- ...test_hemispherical_uniform_distribution.py | 2 +- ...est_hypercylindrical_dirac_distribution.py | 2 +- ...hyperhemispherical_uniform_distribution.py | 2 +- .../test_hyperspherical_dirac_distribution.py | 2 +- .../test_hyperspherical_mixture.py | 2 +- ...est_hyperspherical_uniform_distribution.py | 2 +- .../test_hypertoroidal_dirac_distribution.py | 2 +- ...pertoroidal_wrapped_normal_distribution.py | 2 +- .../test_linear_dirac_distribution.py | 2 +- .../distributions/test_linear_mixture.py | 2 +- ...t_partially_wrapped_normal_distribution.py | 2 +- .../test_se3_dirac_distribution.py | 2 +- .../test_sphere_subset_distribution.py | 2 +- ...pherical_harmonics_distribution_complex.py | 2 +- ...t_spherical_harmonics_distribution_real.py | 2 +- .../test_toroidal_uniform_distribution.py | 2 +- ...st_toroidal_von_mises_sine_distribution.py | 2 +- ...st_toroidal_wrapped_normal_distribution.py | 2 +- .../test_von_mises_distribution.py | 2 +- .../test_von_mises_fisher_distribution.py | 2 +- .../distributions/test_watson_distribution.py | 2 +- .../test_wrapped_cauchy_distribution.py | 2 +- .../test_wrapped_laplace_distribution.py | 2 +- .../test_wrapped_normal_distribution.py | 2 +- .../filters/test_circular_particle_filter.py | 2 +- .../filters/test_euclidean_particle_filter.py | 2 +- .../filters/test_global_nearest_neighbor.py | 2 +- .../test_hypertoroidal_particle_filter.py | 2 +- pyrecest/tests/filters/test_kalman_filter.py | 2 +- .../filters/test_random_matrix_tracker.py | 2 +- .../filters/test_toroidal_particle_filter.py | 2 +- .../test_toroidal_wrapped_normal_filter.py | 2 +- .../tests/filters/test_von_mises_filter.py | 2 +- .../filters/test_von_mises_fisher_filter.py | 2 +- .../filters/test_wrapped_normal_filter.py | 2 +- pyrecest/tests/test_euclidean_sampler.py | 2 +- pyrecest/tests/test_evaluation_basic.py | 8 ++-- pyrecest/tests/test_hyperspherical_sampler.py | 2 +- pyrecest/tests/test_hypertoroidal_sampler.py | 2 +- pyrecest/tests/test_metrics.py | 2 +- pyrecest/utils/metrics.py | 2 +- pyrecest/utils/plotting.py | 2 +- 166 files changed, 435 insertions(+), 439 deletions(-) diff --git a/pyrecest/_backend/__init__.py b/pyrecest/_backend/__init__.py index 096707f5..b45178d2 100644 --- a/pyrecest/_backend/__init__.py +++ b/pyrecest/_backend/__init__.py @@ -171,6 +171,7 @@ def get_backend_name(): "apply_along_axis", # Added for pyrecest "nonzero", # Added for pyrecest "column_stack", # Added for pyrecest + "conj", # Added for pyrecest ], "autodiff": [ "custom_gradient", diff --git a/pyrecest/_backend/numpy/__init__.py b/pyrecest/_backend/numpy/__init__.py index 7b8d7a5d..cd865797 100644 --- a/pyrecest/_backend/numpy/__init__.py +++ b/pyrecest/_backend/numpy/__init__.py @@ -76,6 +76,7 @@ apply_along_axis, # For pyrecest nonzero, # For pyrecest column_stack, # For pyrecest + conj, # For pyrecest ) from scipy.special import erf, gamma, polygamma # NOQA diff --git a/pyrecest/_backend/pytorch/__init__.py b/pyrecest/_backend/pytorch/__init__.py index 2a738ee5..e2465d7b 100644 --- a/pyrecest/_backend/pytorch/__init__.py +++ b/pyrecest/_backend/pytorch/__init__.py @@ -37,6 +37,7 @@ diff, # For pyrecest nonzero, # For pyrecest column_stack, # For pyrecest + conj, # For pyrecest ) from torch import repeat_interleave as repeat from torch import ( diff --git a/pyrecest/distributions/abstract_custom_distribution.py b/pyrecest/distributions/abstract_custom_distribution.py index 4a5cda3f..b2cb7ab0 100644 --- a/pyrecest/distributions/abstract_custom_distribution.py +++ b/pyrecest/distributions/abstract_custom_distribution.py @@ -4,7 +4,6 @@ from collections.abc import Callable import pyrecest.backend -import numpy as np from beartype import beartype from .abstract_distribution_type import AbstractDistributionType @@ -18,7 +17,7 @@ class AbstractCustomDistribution(AbstractDistributionType): and a scaling factor `scale_by` to adjust the PDF. Methods: - - pdf(xs : Union[float, np.ndarray]) -> Union[float, np.ndarray]: + - pdf(xs : Union[float, ]) -> Union[float, ]: Compute the probability density function at given points. - integrate(integration_boundaries: Optional[Union[float, Tuple[float, float]]] = None) -> float: Calculate the integral of the probability density function. @@ -26,7 +25,7 @@ class AbstractCustomDistribution(AbstractDistributionType): Normalize the PDF such that its integral is 1. Returns a copy of the original distribution. """ - def __init__(self, f: Callable[[np.ndarray], np.ndarray], scale_by=1): + def __init__(self, f, scale_by=1): """ Initialize AbstractCustomDistribution. @@ -36,7 +35,7 @@ def __init__(self, f: Callable[[np.ndarray], np.ndarray], scale_by=1): self.f = f self.scale_by = scale_by - def pdf(self, xs: np.ndarray) -> np.ndarray | np.number: + def pdf(self, xs): """ Compute the probability density function at given points. diff --git a/pyrecest/distributions/abstract_dirac_distribution.py b/pyrecest/distributions/abstract_dirac_distribution.py index 395f8594..46702860 100644 --- a/pyrecest/distributions/abstract_dirac_distribution.py +++ b/pyrecest/distributions/abstract_dirac_distribution.py @@ -13,7 +13,6 @@ import warnings from collections.abc import Callable -import numpy as np from beartype import beartype from .abstract_distribution_type import AbstractDistributionType @@ -24,7 +23,7 @@ class AbstractDiracDistribution(AbstractDistributionType): This class represents an abstract base for Dirac distributions. """ - def __init__(self, d: np.ndarray, w: np.ndarray | None = None): + def __init__(self, d, w = None): """ Initialize a Dirac distribution with given Dirac locations and weights. @@ -81,7 +80,7 @@ def reweigh(self, f: Callable) -> "AbstractDiracDistribution": return dist - def sample(self, n: Union[int, int32, int64]) -> np.ndarray: + def sample(self, n: Union[int, int32, int64]): samples = random.choice(self.d, size=n, p=self.w) return samples @@ -89,7 +88,7 @@ def entropy(self) -> float: warnings.warn("Entropy is not defined in a continuous sense") return -sum(self.w * log(self.w)) - def integrate(self, left=None, right=None) -> np.ndarray: + def integrate(self, left=None, right=None): assert ( left is None and right is None ), "Must overwrite in child class to use integral limits" diff --git a/pyrecest/distributions/abstract_disk_distribution.py b/pyrecest/distributions/abstract_disk_distribution.py index 0798fe99..3d4f176f 100644 --- a/pyrecest/distributions/abstract_disk_distribution.py +++ b/pyrecest/distributions/abstract_disk_distribution.py @@ -1,6 +1,5 @@ from pyrecest.backend import eye from pyrecest.backend import array -import numpy as np from .abstract_ellipsoidal_ball_distribution import AbstractEllipsoidalBallDistribution diff --git a/pyrecest/distributions/abstract_ellipsoidal_ball_distribution.py b/pyrecest/distributions/abstract_ellipsoidal_ball_distribution.py index 7ca52330..cad97283 100644 --- a/pyrecest/distributions/abstract_ellipsoidal_ball_distribution.py +++ b/pyrecest/distributions/abstract_ellipsoidal_ball_distribution.py @@ -3,7 +3,6 @@ from pyrecest.backend import sqrt import numbers -import numpy as np from beartype import beartype from scipy.special import gamma @@ -17,7 +16,7 @@ class AbstractEllipsoidalBallDistribution(AbstractBoundedNonPeriodicDistribution This class represents distributions on ellipsoidal balls. """ - def __init__(self, center: np.ndarray, shape_matrix: np.ndarray): + def __init__(self, center, shape_matrix): """ Initialize the class with a center and shape matrix. @@ -30,7 +29,7 @@ def __init__(self, center: np.ndarray, shape_matrix: np.ndarray): assert center.ndim == 1 and shape_matrix.ndim == 2 assert shape_matrix.shape[0] == self.dim and shape_matrix.shape[1] == self.dim - def get_manifold_size(self) -> np.number | numbers.Real: + def get_manifold_size(self): """ Calculate the size of the manifold. diff --git a/pyrecest/distributions/abstract_manifold_specific_distribution.py b/pyrecest/distributions/abstract_manifold_specific_distribution.py index d369a326..bf878b63 100644 --- a/pyrecest/distributions/abstract_manifold_specific_distribution.py +++ b/pyrecest/distributions/abstract_manifold_specific_distribution.py @@ -8,7 +8,6 @@ from abc import ABC, abstractmethod from collections.abc import Callable -import numpy as np from beartype import beartype @@ -48,12 +47,12 @@ def pdf(self, xs): pass @abstractmethod - def mean(self) -> np.ndarray: + def mean(self): """ Convenient access to a reasonable "mean" for different manifolds. :return: The mean of the distribution. - :rtype: np.ndarray + :rtype: """ def set_mode(self, _): @@ -63,7 +62,7 @@ def set_mode(self, _): raise NotImplementedError("set_mode is not implemented for this distribution") # Need to use Union instead of | to support torch.dtype - def sample(self, n: Union[int, int32, int64]) -> np.ndarray: + def sample(self, n: Union[int, int32, int64]): """Obtain n samples from the distribution.""" return self.sample_metropolis_hastings(n) @@ -74,8 +73,8 @@ def sample_metropolis_hastings( burn_in: Union[int, int32, int64] = 10, skipping: Union[int, int32, int64] = 5, proposal: Callable | None = None, - start_point: np.number | numbers.Real | np.ndarray | None = None, - ) -> np.ndarray: + start_point = None, + ): # jscpd:ignore-end """Metropolis Hastings sampling algorithm.""" diff --git a/pyrecest/distributions/abstract_mixture.py b/pyrecest/distributions/abstract_mixture.py index af2b92e7..d7a5aabe 100644 --- a/pyrecest/distributions/abstract_mixture.py +++ b/pyrecest/distributions/abstract_mixture.py @@ -11,7 +11,7 @@ import copy import warnings -import numpy as np + from beartype import beartype from .abstract_distribution_type import AbstractDistributionType @@ -64,7 +64,7 @@ def __init__( def input_dim(self) -> int: return self.dists[0].input_dim - def sample(self, n: Union[int, int32, int64]) -> np.ndarray: + def sample(self, n: Union[int, int32, int64]): occurrences = random.multinomial(n, self.w) count = 0 @@ -76,7 +76,7 @@ def sample(self, n: Union[int, int32, int64]) -> np.ndarray: return s - def pdf(self, xs: np.ndarray) -> np.ndarray: + def pdf(self, xs): assert xs.shape[-1] == self.input_dim, "Dimension mismatch" p = zeros(1) if xs.ndim == 1 else zeros(xs.shape[0]) diff --git a/pyrecest/distributions/abstract_orthogonal_basis_distribution.py b/pyrecest/distributions/abstract_orthogonal_basis_distribution.py index f97a6fb4..c92f454e 100644 --- a/pyrecest/distributions/abstract_orthogonal_basis_distribution.py +++ b/pyrecest/distributions/abstract_orthogonal_basis_distribution.py @@ -6,7 +6,6 @@ import warnings from abc import abstractmethod -import numpy as np from beartype import beartype from .abstract_distribution_type import AbstractDistributionType @@ -35,7 +34,7 @@ def normalize_in_place(self): """ @abstractmethod - def value(self, xs: np.ndarray | np.number) -> np.ndarray | np.number: + def value(self, xs): """ Abstract method to get value of the distribution for given input. Implementation required in subclasses. @@ -51,7 +50,7 @@ def normalize(self): result = copy.deepcopy(self) return result.normalize_in_place() - def pdf(self, xs: np.ndarray | np.number) -> np.ndarray | np.number: + def pdf(self, xs): """ Calculates probability density function for the given input. diff --git a/pyrecest/distributions/abstract_periodic_distribution.py b/pyrecest/distributions/abstract_periodic_distribution.py index a805450c..25db756a 100644 --- a/pyrecest/distributions/abstract_periodic_distribution.py +++ b/pyrecest/distributions/abstract_periodic_distribution.py @@ -3,7 +3,6 @@ from pyrecest.backend import int32 from abc import abstractmethod -import numpy as np from beartype import beartype from .abstract_bounded_domain_distribution import AbstractBoundedDomainDistribution @@ -15,23 +14,23 @@ class AbstractPeriodicDistribution(AbstractBoundedDomainDistribution): def __init__(self, dim: Union[int, int32, int64]): super().__init__(dim=dim) - def mean(self) -> np.ndarray: + def mean(self): """ Convenient access to mean_direction to have a consistent interface throughout manifolds. :return: The mean of the distribution. - :rtype: np.ndarray + :rtype: """ return self.mean_direction() @abstractmethod - def mean_direction(self) -> np.ndarray: + def mean_direction(self): """ Abstract method to compute the mean direction of the distribution. Returns ------- - mean_direction: np.ndarray + mean_direction: The mean direction of the distribution. """ \ No newline at end of file diff --git a/pyrecest/distributions/abstract_se3_distribution.py b/pyrecest/distributions/abstract_se3_distribution.py index 97115f90..6b7db59b 100644 --- a/pyrecest/distributions/abstract_se3_distribution.py +++ b/pyrecest/distributions/abstract_se3_distribution.py @@ -6,7 +6,7 @@ from abc import abstractmethod import matplotlib.pyplot as plt -import numpy as np + import quaternion from .cart_prod.abstract_lin_bounded_cart_prod_distribution import ( @@ -110,4 +110,4 @@ def plot_trajectory(periodicStates, linStates, animate=False, delay=0.05): return h def get_manifold_size(self): - return np.inf \ No newline at end of file + return float('inf') \ No newline at end of file diff --git a/pyrecest/distributions/abstract_uniform_distribution.py b/pyrecest/distributions/abstract_uniform_distribution.py index 7fce0d85..6709ffd2 100644 --- a/pyrecest/distributions/abstract_uniform_distribution.py +++ b/pyrecest/distributions/abstract_uniform_distribution.py @@ -1,7 +1,7 @@ from pyrecest.backend import ones from abc import abstractmethod -import numpy as np + from beartype import beartype from .abstract_distribution_type import AbstractDistributionType @@ -10,27 +10,27 @@ class AbstractUniformDistribution(AbstractDistributionType): """Abstract class for a uniform distribution on a manifold.""" - def pdf(self, xs: np.ndarray) -> np.ndarray: + def pdf(self, xs): """Compute the probability density function at each point in xs. :param xs: Points at which to compute the pdf. - :type xs: np.ndarray + :type xs: :return: The pdf evaluated at each point in xs. - :rtype: np.ndarray + :rtype: """ return 1 / self.get_manifold_size() * ones(xs.shape[0]) @abstractmethod - def get_manifold_size(self) -> np.ndarray: + def get_manifold_size(self): """ Compute the probability density function at each point in xs. :param xs: Points at which to compute the pdf. - :type xs: np.ndarray + :type xs: :return: The pdf evaluated at each point in xs. - :rtype: np.ndarray + :rtype: """ def mode(self): diff --git a/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py b/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py index 41bb9f60..5375a5c5 100644 --- a/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py +++ b/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py @@ -18,7 +18,7 @@ from pyrecest.backend import zeros from abc import abstractmethod -import numpy as np + import scipy.integrate import scipy.optimize from beartype import beartype @@ -57,7 +57,7 @@ def f(*args): return integration_result - def get_reasonable_integration_boundaries(self, scalingFactor=10) -> np.ndarray: + def get_reasonable_integration_boundaries(self, scalingFactor=10): """ Returns reasonable integration boundaries for the specific distribution based on the mode and covariance. @@ -119,29 +119,29 @@ def linear_covariance_numerical(self, approximate_mean=None): if self.bound_dim == 1 and self.lin_dim == 1: C, _ = nquad( lambda x, y: (y - approximate_mean) ** 2 * self.pdf([x, y]), - [[0, 2 * pi], [-np.inf, np.inf]], + [[0, 2 * pi], [-float('inf'), float('inf')]], ) elif self.bound_dim == 2 and self.lin_dim == 1: C, _ = nquad( lambda x, y, z: (z - approximate_mean) ** 2 * self.pdf([x, y, z]), - [[0, 2 * pi], [0, 2 * pi], [-np.inf, np.inf]], + [[0, 2 * pi], [0, 2 * pi], [-float('inf'), float('inf')]], ) elif self.bound_dim == 1 and self.lin_dim == 2: C = empty((2, 2)) C[0, 0], _ = nquad( lambda x, y, z: (y - approximate_mean[0]) ** 2 * self.pdf([x, y, z]), - [[0, 2 * pi], [-np.inf, np.inf], [-np.inf, np.inf]], + [[0, 2 * pi], [-float('inf'), float('inf')], [-float('inf'), float('inf')]], ) C[0, 1], _ = nquad( lambda x, y, z: (y - approximate_mean[0]) * (z - approximate_mean[1]) * self.pdf([x, y, z]), - [[0, 2 * pi], [-np.inf, np.inf], [-np.inf, np.inf]], + [[0, 2 * pi], [-float('inf'), float('inf')], [-float('inf'), float('inf')]], ) C[1, 0] = C[0, 1] C[1, 1], _ = nquad( lambda x, y, z: (z - approximate_mean[1]) ** 2 * self.pdf([x, y, z]), - [[0, 2 * pi], [-np.inf, np.inf], [-np.inf, np.inf]], + [[0, 2 * pi], [-float('inf'), float('inf')], [-float('inf'), float('inf')]], ) else: raise ValueError("Cannot determine linear covariance for this dimension.") @@ -215,22 +215,22 @@ def linear_mean_numerical(self): if self.lin_dim == 1 and self.bound_dim == 1: mu = scipy.integrate.nquad( lambda x, y: (y * self.pdf([x, y]))[0], - [[0.0, 2 * pi], [-np.inf, np.inf]], + [[0.0, 2 * pi], [-float('inf'), float('inf')]], )[0] elif self.bound_dim == 2 and self.lin_dim == 1: mu = scipy.integrate.nquad( lambda x, y, z: (z * self.pdf([x, y, z]))[0], - [[0.0, 2 * pi], [0.0, 2 * pi], [-np.inf, np.inf]], + [[0.0, 2 * pi], [0.0, 2 * pi], [-float('inf'), float('inf')]], )[0] elif self.bound_dim == 1 and self.lin_dim == 2: mu = empty(2) mu[0] = scipy.integrate.nquad( lambda x, y, z: (y * self.pdf([x, y, z]))[0], - [[0.0, 2 * pi], [-np.inf, np.inf], [-np.inf, np.inf]], + [[0.0, 2 * pi], [-float('inf'), float('inf')], [-float('inf'), float('inf')]], )[0] mu[1] = scipy.integrate.nquad( lambda x, y, z: (z * self.pdf([x, y, z]))[0], - [[0, 2 * pi], [-np.inf, np.inf], [-np.inf, np.inf]], + [[0, 2 * pi], [-float('inf'), float('inf')], [-float('inf'), float('inf')]], )[0] else: raise ValueError("Cannot determine linear mean for this dimension.") @@ -257,7 +257,7 @@ def mode_numerical(self, starting_point=None): # Define bounds for the optimization bounds = [ - (0, 2 * pi) if i < self.bound_dim else (-np.inf, np.inf) + (0, 2 * pi) if i < self.bound_dim else (-float('inf'), float('inf')) for i in range(self.bound_dim + self.lin_dim) ] diff --git a/pyrecest/distributions/cart_prod/abstract_lin_bounded_cart_prod_distribution.py b/pyrecest/distributions/cart_prod/abstract_lin_bounded_cart_prod_distribution.py index 8fc9bdcd..211da7d6 100644 --- a/pyrecest/distributions/cart_prod/abstract_lin_bounded_cart_prod_distribution.py +++ b/pyrecest/distributions/cart_prod/abstract_lin_bounded_cart_prod_distribution.py @@ -3,7 +3,7 @@ from pyrecest.backend import int32 from abc import abstractmethod -import numpy as np + from beartype import beartype from .abstract_cart_prod_distribution import AbstractCartProdDistribution @@ -42,7 +42,7 @@ def mean(self): throughout manifolds. :return: The mean of the distribution. - :rtype: np.ndarray + :rtype: """ return self.hybrid_mean() diff --git a/pyrecest/distributions/cart_prod/abstract_lin_periodic_cart_prod_distribution.py b/pyrecest/distributions/cart_prod/abstract_lin_periodic_cart_prod_distribution.py index 7a111b40..ae27c9c4 100644 --- a/pyrecest/distributions/cart_prod/abstract_lin_periodic_cart_prod_distribution.py +++ b/pyrecest/distributions/cart_prod/abstract_lin_periodic_cart_prod_distribution.py @@ -1,4 +1,4 @@ -import numpy as np + from .abstract_lin_bounded_cart_prod_distribution import ( AbstractLinBoundedCartProdDistribution, @@ -18,4 +18,4 @@ def get_manifold_size(self): assert ( self.lin_dim > 0 ), "This class is not intended to be used for purely periodic domains." - return np.inf \ No newline at end of file + return float('inf') \ No newline at end of file diff --git a/pyrecest/distributions/cart_prod/cart_prod_stacked_distribution.py b/pyrecest/distributions/cart_prod/cart_prod_stacked_distribution.py index b922efc0..0365faf3 100644 --- a/pyrecest/distributions/cart_prod/cart_prod_stacked_distribution.py +++ b/pyrecest/distributions/cart_prod/cart_prod_stacked_distribution.py @@ -2,7 +2,7 @@ from pyrecest.backend import hstack from pyrecest.backend import concatenate from pyrecest.backend import empty -import numpy as np + from .abstract_cart_prod_distribution import AbstractCartProdDistribution @@ -51,7 +51,7 @@ def mean(self): throughout manifolds. :return: The mean of the distribution. - :rtype: np.ndarray + :rtype: """ return self.hybrid_mean() diff --git a/pyrecest/distributions/cart_prod/hypercylindrical_dirac_distribution.py b/pyrecest/distributions/cart_prod/hypercylindrical_dirac_distribution.py index e08623d5..c7999f1f 100644 --- a/pyrecest/distributions/cart_prod/hypercylindrical_dirac_distribution.py +++ b/pyrecest/distributions/cart_prod/hypercylindrical_dirac_distribution.py @@ -5,7 +5,7 @@ from pyrecest.backend import cos from pyrecest.backend import int64 from pyrecest.backend import int32 -import numpy as np + from ..hypertorus.hypertoroidal_dirac_distribution import HypertoroidalDiracDistribution from .abstract_hypercylindrical_distribution import AbstractHypercylindricalDistribution diff --git a/pyrecest/distributions/cart_prod/lin_bounded_cart_prod_dirac_distribution.py b/pyrecest/distributions/cart_prod/lin_bounded_cart_prod_dirac_distribution.py index b0d9d713..e6988c14 100644 --- a/pyrecest/distributions/cart_prod/lin_bounded_cart_prod_dirac_distribution.py +++ b/pyrecest/distributions/cart_prod/lin_bounded_cart_prod_dirac_distribution.py @@ -2,7 +2,7 @@ import warnings from abc import abstractmethod -import numpy as np + from ..abstract_dirac_distribution import AbstractDiracDistribution from ..nonperiodic.linear_dirac_distribution import LinearDiracDistribution diff --git a/pyrecest/distributions/cart_prod/lin_hypersphere_cart_prod_dirac_distribution.py b/pyrecest/distributions/cart_prod/lin_hypersphere_cart_prod_dirac_distribution.py index 121d3a5e..d2e19447 100644 --- a/pyrecest/distributions/cart_prod/lin_hypersphere_cart_prod_dirac_distribution.py +++ b/pyrecest/distributions/cart_prod/lin_hypersphere_cart_prod_dirac_distribution.py @@ -1,7 +1,7 @@ from pyrecest.backend import linalg from pyrecest.backend import abs from pyrecest.backend import amax -import numpy as np + from ..abstract_se3_distribution import AbstractSE3Distribution from .lin_bounded_cart_prod_dirac_distribution import ( diff --git a/pyrecest/distributions/cart_prod/lin_hypersphere_subset_dirac_distribution.py b/pyrecest/distributions/cart_prod/lin_hypersphere_subset_dirac_distribution.py index 496934f7..68a5f80f 100644 --- a/pyrecest/distributions/cart_prod/lin_hypersphere_subset_dirac_distribution.py +++ b/pyrecest/distributions/cart_prod/lin_hypersphere_subset_dirac_distribution.py @@ -1,7 +1,7 @@ from typing import Union from pyrecest.backend import int64 from pyrecest.backend import int32 -import numpy as np + from .abstract_lin_hyperhemisphere_cart_prod_distribution import ( AbstractLinHypersphereSubsetCartProdDistribution, diff --git a/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py b/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py index 25687840..7fc2f0fd 100644 --- a/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py +++ b/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py @@ -21,7 +21,7 @@ from pyrecest.backend import empty import copy -import numpy as np + from beartype import beartype from scipy.stats import multivariate_normal @@ -34,7 +34,7 @@ class PartiallyWrappedNormalDistribution(AbstractHypercylindricalDistribution): def __init__( - self, mu: np.ndarray, C: np.ndarray, bound_dim: Union[int, int32, int64] + self, mu, C, bound_dim: Union[int, int32, int64] ): assert bound_dim >= 0, "bound_dim must be non-negative" assert ndim(mu) == 1, "mu must be a 1-dimensional array" @@ -53,7 +53,7 @@ def __init__( self.mu[:bound_dim] = mod(self.mu[:bound_dim], 2 * pi) self.C = C - def pdf(self, xs: np.ndarray, m: Union[int, int32, int64] = 3): + def pdf(self, xs, m: Union[int, int32, int64] = 3): xs = np.atleast_2d(xs) if self.bound_dim > 0: xs[:, : self.bound_dim] = mod(xs[:, : self.bound_dim], 2 * pi) @@ -98,7 +98,7 @@ def mode(self): """ return self.mu - def set_mode(self, new_mode: np.ndarray): + def set_mode(self, new_mode): self.mu = copy.copy(new_mode) return self diff --git a/pyrecest/distributions/circle/abstract_circular_distribution.py b/pyrecest/distributions/circle/abstract_circular_distribution.py index e9cf546a..8495fbc9 100644 --- a/pyrecest/distributions/circle/abstract_circular_distribution.py +++ b/pyrecest/distributions/circle/abstract_circular_distribution.py @@ -7,7 +7,7 @@ import numbers import matplotlib.pyplot as plt -import numpy as np + from beartype import beartype from ..hypertorus.abstract_hypertoroidal_distribution import AbstractHypertoroidalDistribution @@ -16,16 +16,16 @@ class AbstractCircularDistribution(AbstractHypertoroidalDistribution): def __init__(self): AbstractHypertoroidalDistribution.__init__(self, dim=1) - def cdf_numerical(self, xs: np.ndarray, starting_point: float = 0.0) -> np.ndarray: + def cdf_numerical(self, xs, starting_point: float = 0.0): """ Calculates the cumulative distribution function. Args: - xs (np.ndarray): The 1D array to calculate the CDF on. + xs (): The 1D array to calculate the CDF on. starting_point (float, optional): Defaults to 0. Returns: - np.ndarray: The computed CDF as a numpy array. + : The computed CDF as a numpy array. """ assert xs.ndim == 1, "xs must be a 1D array" @@ -33,9 +33,9 @@ def cdf_numerical(self, xs: np.ndarray, starting_point: float = 0.0) -> np.ndarr def _cdf_numerical_single( self, - x: np.number | numbers.Real, - starting_point: np.number | numbers.Real, - ) -> np.number | numbers.Real: + x, + starting_point, + ): """Helper method for cdf_numerical""" starting_point_mod = mod(starting_point, 2 * pi) x_mod = mod(x, 2 * pi) diff --git a/pyrecest/distributions/circle/circular_dirac_distribution.py b/pyrecest/distributions/circle/circular_dirac_distribution.py index 56f2e143..3805458a 100644 --- a/pyrecest/distributions/circle/circular_dirac_distribution.py +++ b/pyrecest/distributions/circle/circular_dirac_distribution.py @@ -1,4 +1,4 @@ -import numpy as np + from beartype import beartype from ..hypertorus.hypertoroidal_dirac_distribution import HypertoroidalDiracDistribution @@ -8,13 +8,13 @@ class CircularDiracDistribution( HypertoroidalDiracDistribution, AbstractCircularDistribution ): - def __init__(self, d: np.ndarray, w: np.ndarray | None = None): + def __init__(self, d, w: | None = None): """ Initializes a CircularDiracDistribution instance. Args: - d (np.ndarray): The Dirac locations. - w (Optional[np.ndarray]): The weights for each Dirac location. + d (): The Dirac locations. + w (Optional[]): The weights for each Dirac location. """ super().__init__( d, w, dim=1 diff --git a/pyrecest/distributions/circle/circular_fourier_distribution.py b/pyrecest/distributions/circle/circular_fourier_distribution.py index e42cfb3c..4b36cd86 100644 --- a/pyrecest/distributions/circle/circular_fourier_distribution.py +++ b/pyrecest/distributions/circle/circular_fourier_distribution.py @@ -13,10 +13,12 @@ from pyrecest.backend import arange from pyrecest.backend import int64 from pyrecest.backend import int32 +from pyrecest.backend import array +from pyrecest import warnings import matplotlib.pyplot as plt -import numpy as np + from beartype import beartype from numpy.fft import irfft, rfft @@ -33,9 +35,9 @@ class CircularFourierDistribution(AbstractCircularDistribution): def __init__( self, transformation: str = "sqrt", - c: np.ndarray | None = None, - a: np.ndarray | None = None, - b: np.ndarray | None = None, + c: | None = None, + a: | None = None, + b: | None = None, n: int | None = None, multiplied_by_n: bool = True, ): @@ -103,13 +105,13 @@ def __sub__( ) # The number should not change! We store it if we use a complex one now and set it to None if we falsely believe we know the number (it is not clear for complex ones) return fdNew - def pdf(self, xs: np.ndarray) -> np.ndarray: + def pdf(self, xs): assert xs.ndim <= 2, "xs should have at most 2 dimensions." xs = xs.reshape(-1, 1) a, b = self.get_a_b() - k_range = arange(1, a.shape[0]).astype(xs.dtype) - p = a[0] / 2 + sum( + k_range = arange(1, a.shape[0], dtype=xs.dtype) + p = a[0] / 2.0 + sum( a[1:].reshape(1, -1) * cos(xs * k_range) + b.reshape(1, -1) * sin(xs * k_range), axis=1, @@ -172,8 +174,8 @@ def integrate(self, integration_boundaries=None) -> float: integration_boundaries is None ), "Currently, only supported for entire domain." if self.a is not None and self.b is not None: - a: np.ndarray = self.a - b: np.ndarray = self.b + a: array = self.a + b: array = self.b if self.multiplied_by_n: a = a * (1 / self.n) b = b * (1 / self.n) @@ -193,7 +195,7 @@ def integrate(self, integration_boundaries=None) -> float: c0 = real(self.c[0]) * (1 / self.n) else: c0 = real(self.c[0]) - integral = 2 * pi * c0 + integral = 2.0 * pi * c0 elif self.transformation == "sqrt": if self.multiplied_by_n: c = self.c * (1 / self.n) @@ -230,7 +232,7 @@ def plot_grid(self): plt.show() def plot(self, resolution=128, **kwargs): - xs = linspace(0, 2 * pi, resolution) + xs = linspace(0.0, 2.0 * pi, resolution) if self.a is not None: xs = xs.astype(self.a.dtype) @@ -244,7 +246,7 @@ def plot(self, resolution=128, **kwargs): return p - def get_a_b(self) -> tuple[np.ndarray, np.ndarray]: + def get_a_b(self) -> tuple[, ]: if self.a is not None: a = self.a b = self.b @@ -256,7 +258,7 @@ def get_a_b(self) -> tuple[np.ndarray, np.ndarray]: ) # Other case not implemented yet! return a, b - def get_c(self) -> np.ndarray: + def get_c(self): if self.a is not None: c = (self.a[0] + 1j * hstack((0, self.b))) * 0.5 elif self.c is not None: @@ -279,7 +281,7 @@ def to_real_fd(self): def get_full_c(self): assert self.c is not None - neg_c = np.conj( + neg_c = conj( self.c[-1:0:-1] ) # Create array for negative-frequency components full_c = concatenate( @@ -321,7 +323,7 @@ def from_distribution( @staticmethod def from_function_values( - fvals: np.ndarray, + fvals: , transformation: str = "sqrt", store_values_multiplied_by_n: bool = True, ) -> "CircularFourierDistribution": @@ -332,7 +334,7 @@ def from_function_values( fd = CircularFourierDistribution( c=c, transformation=transformation, - n=np.size(fvals), + n=fvals.shape[0], multiplied_by_n=store_values_multiplied_by_n, ) diff --git a/pyrecest/distributions/circle/circular_mixture.py b/pyrecest/distributions/circle/circular_mixture.py index fdee9332..56f33358 100644 --- a/pyrecest/distributions/circle/circular_mixture.py +++ b/pyrecest/distributions/circle/circular_mixture.py @@ -3,7 +3,7 @@ import collections import warnings -import numpy as np + from beartype import beartype from ..hypertorus.hypertoroidal_mixture import HypertoroidalMixture @@ -16,7 +16,7 @@ class CircularMixture(AbstractCircularDistribution, HypertoroidalMixture): def __init__( self, dists: collections.abc.Sequence[AbstractCircularDistribution], - w: np.ndarray, + w: , ): """ Creates a new circular mixture. diff --git a/pyrecest/distributions/circle/circular_uniform_distribution.py b/pyrecest/distributions/circle/circular_uniform_distribution.py index 0fa1622d..f354f0c8 100644 --- a/pyrecest/distributions/circle/circular_uniform_distribution.py +++ b/pyrecest/distributions/circle/circular_uniform_distribution.py @@ -1,5 +1,5 @@ from math import pi -import numpy as np + from ..hypertorus.hypertoroidal_uniform_distribution import ( HypertoroidalUniformDistribution, diff --git a/pyrecest/distributions/circle/custom_circular_distribution.py b/pyrecest/distributions/circle/custom_circular_distribution.py index 97433dae..0d37a961 100644 --- a/pyrecest/distributions/circle/custom_circular_distribution.py +++ b/pyrecest/distributions/circle/custom_circular_distribution.py @@ -3,7 +3,7 @@ from pyrecest.backend import array from collections.abc import Callable -import numpy as np + from beartype import beartype from ..abstract_custom_distribution import AbstractCustomDistribution @@ -30,26 +30,26 @@ def __init__(self, f_: Callable, scale_by: float = 1, shift_by: float = 0): AbstractCustomDistribution.__init__(self, f_, scale_by) self.shift_by = shift_by - def pdf(self, xs: np.ndarray): + def pdf(self, xs): """ Computes the probability density function at xs. Args: - xs (np.ndarray): The values at which to evaluate the pdf. + xs (): The values at which to evaluate the pdf. Returns: - np.ndarray: The value of the pdf at xs. + : The value of the pdf at xs. """ return AbstractCustomDistribution.pdf( self, mod(xs + self.shift_by, 2 * pi) ) - def integrate(self, integration_boundaries: np.ndarray | None = None) -> float: + def integrate(self, integration_boundaries: | None = None) -> float: """ Computes the integral of the pdf over the given boundaries. Args: - integration_boundaries (np.ndarray, optional): The boundaries of the integral. + integration_boundaries (, optional): The boundaries of the integral. Defaults to [0, 2 * pi]. Returns: diff --git a/pyrecest/distributions/circle/von_mises_distribution.py b/pyrecest/distributions/circle/von_mises_distribution.py index aa2b963f..5b8b17e7 100644 --- a/pyrecest/distributions/circle/von_mises_distribution.py +++ b/pyrecest/distributions/circle/von_mises_distribution.py @@ -13,7 +13,7 @@ from pyrecest.backend import zeros_like import numbers -import numpy as np + from beartype import beartype from scipy.optimize import fsolve from scipy.special import iv @@ -25,7 +25,7 @@ class VonMisesDistribution(AbstractCircularDistribution): def __init__( self, - mu: np.number | numbers.Real, + mu: Any | numbers.Real, kappa, norm_const: float | None = None, ): @@ -50,8 +50,8 @@ def pdf(self, xs): @staticmethod def besselratio( - nu: np.number | numbers.Real, kappa: np.number | numbers.Real - ) -> np.number | numbers.Real: + nu: Any | numbers.Real, kappa: Any | numbers.Real + ) -> Any | numbers.Real: return iv(nu + 1, kappa) / iv(nu, kappa) def cdf(self, xs, starting_point=0): @@ -74,8 +74,8 @@ def cdf(self, xs, starting_point=0): r = zeros_like(xs) def to_minus_pi_to_pi_range( - angle: np.number | numbers.Real | np.ndarray, - ) -> np.number | numbers.Real | np.ndarray: + angle: Any | numbers.Real | , + ) -> Any | numbers.Real | : return mod(angle + pi, 2 * pi) - pi r = vonmises.cdf( @@ -97,8 +97,8 @@ def to_minus_pi_to_pi_range( @staticmethod def besselratio_inverse( - v: np.number | numbers.Real, x: np.number | numbers.Real - ) -> np.number | numbers.Real: + v: Any | numbers.Real, x: Any | numbers.Real + ) -> Any | numbers.Real: def f(t: float) -> float: return VonMisesDistribution.besselratio(v, t) - x diff --git a/pyrecest/distributions/circle/wrapped_cauchy_distribution.py b/pyrecest/distributions/circle/wrapped_cauchy_distribution.py index 2ab8c10c..e5b82c2a 100644 --- a/pyrecest/distributions/circle/wrapped_cauchy_distribution.py +++ b/pyrecest/distributions/circle/wrapped_cauchy_distribution.py @@ -7,7 +7,7 @@ from pyrecest.backend import exp from pyrecest.backend import cosh from pyrecest.backend import cos -import numpy as np + from .abstract_circular_distribution import AbstractCircularDistribution diff --git a/pyrecest/distributions/circle/wrapped_laplace_distribution.py b/pyrecest/distributions/circle/wrapped_laplace_distribution.py index bc01453a..d785f752 100644 --- a/pyrecest/distributions/circle/wrapped_laplace_distribution.py +++ b/pyrecest/distributions/circle/wrapped_laplace_distribution.py @@ -2,7 +2,7 @@ from pyrecest.backend import ndim from pyrecest.backend import mod from pyrecest.backend import exp -import numpy as np + from .abstract_circular_distribution import AbstractCircularDistribution diff --git a/pyrecest/distributions/circle/wrapped_normal_distribution.py b/pyrecest/distributions/circle/wrapped_normal_distribution.py index 79ab683e..b6e5d679 100644 --- a/pyrecest/distributions/circle/wrapped_normal_distribution.py +++ b/pyrecest/distributions/circle/wrapped_normal_distribution.py @@ -15,7 +15,7 @@ from pyrecest.backend import zeros import numbers -import numpy as np + from beartype import beartype from scipy.special import erf # pylint: disable=no-name-in-module @@ -37,8 +37,8 @@ class WrappedNormalDistribution( def __init__( self, - mu: np.number | numbers.Real | np.ndarray, - sigma: np.number | numbers.Real | np.ndarray, + mu: Any | numbers.Real | , + sigma: Any | numbers.Real | , ): """ Initialize a wrapped normal distribution with mean mu and standard deviation sigma. @@ -50,7 +50,7 @@ def __init__( def sigma(self): return sqrt(self.C) - def pdf(self, xs: np.ndarray | np.number | numbers.Real): + def pdf(self, xs: | Any | numbers.Real): if self.sigma <= 0: raise ValueError(f"sigma must be >0, but received {self.sigma}.") @@ -95,10 +95,10 @@ def pdf(self, xs: np.ndarray | np.number | numbers.Real): def cdf( self, - xs: np.ndarray, + xs: , startingPoint: float = 0, n_wraps: Union[int, int32, int64] = 10, - ) -> np.ndarray: + ): startingPoint = mod(startingPoint, 2 * pi) xs = mod(xs, 2 * pi) @@ -125,7 +125,7 @@ def ncdf(from_, to): def trigonometric_moment( self, n: Union[int, int32, int64] - ) -> complex | np.ndarray: + ) -> complex | : return exp(1j * n * self.mu - n**2 * self.sigma**2 / 2) def multiply( @@ -140,7 +140,7 @@ def multiply_vm(self, other): wn = vm.to_wn() return wn - def sample(self, n: Union[int, int32, int64]) -> np.ndarray: + def sample(self, n: Union[int, int32, int64]): return mod(self.mu + self.sigma * random.randn(1, n), 2 * pi) def shift(self, shift_by): diff --git a/pyrecest/distributions/custom_hyperrectangular_distribution.py b/pyrecest/distributions/custom_hyperrectangular_distribution.py index c47fe883..6855f2d5 100644 --- a/pyrecest/distributions/custom_hyperrectangular_distribution.py +++ b/pyrecest/distributions/custom_hyperrectangular_distribution.py @@ -1,6 +1,6 @@ from collections.abc import Callable -import numpy as np + from beartype import beartype from .abstract_custom_nonperiodic_distribution import ( @@ -14,9 +14,9 @@ class CustomHyperrectangularDistribution( AbstractHyperrectangularDistribution, AbstractCustomNonPeriodicDistribution ): - def __init__(self, f: Callable, bounds: np.ndarray): + def __init__(self, f: Callable, bounds): AbstractHyperrectangularDistribution.__init__(self, bounds) AbstractCustomNonPeriodicDistribution.__init__(self, f) - def pdf(self, xs: np.ndarray) -> np.ndarray: + def pdf(self, xs): return AbstractCustomNonPeriodicDistribution.pdf(self, xs) \ No newline at end of file diff --git a/pyrecest/distributions/disk_uniform_distribution.py b/pyrecest/distributions/disk_uniform_distribution.py index 0c2eb702..15c2bf26 100644 --- a/pyrecest/distributions/disk_uniform_distribution.py +++ b/pyrecest/distributions/disk_uniform_distribution.py @@ -1,6 +1,6 @@ from pyrecest.backend import eye from pyrecest.backend import array -import numpy as np + from .abstract_disk_distribution import AbstractDiskDistribution from .ellipsoidal_ball_uniform_distribution import EllipsoidalBallUniformDistribution diff --git a/pyrecest/distributions/ellipsoidal_ball_uniform_distribution.py b/pyrecest/distributions/ellipsoidal_ball_uniform_distribution.py index da921d89..6ffe05e1 100644 --- a/pyrecest/distributions/ellipsoidal_ball_uniform_distribution.py +++ b/pyrecest/distributions/ellipsoidal_ball_uniform_distribution.py @@ -8,7 +8,7 @@ from pyrecest.backend import int64 from pyrecest.backend import int32 from pyrecest.backend import zeros -import numpy as np + from beartype import beartype from .abstract_ellipsoidal_ball_distribution import AbstractEllipsoidalBallDistribution @@ -38,7 +38,7 @@ def input_dim(self) -> int: def mean(self): raise NotImplementedError() - def pdf(self, xs: np.ndarray): + def pdf(self, xs): """ Compute the probability density function at given points. @@ -67,7 +67,7 @@ def pdf(self, xs: np.ndarray): return results - def sample(self, n: Union[int, int32, int64]) -> np.ndarray: + def sample(self, n: Union[int, int32, int64]): """ Generate samples from the distribution. diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py index 18bf029e..dc1acdc7 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py @@ -15,7 +15,7 @@ from collections.abc import Callable import matplotlib.pyplot as plt -import numpy as np + from beartype import beartype from scipy.optimize import minimize @@ -25,13 +25,13 @@ class AbstractHyperhemisphericalDistribution(AbstractHypersphereSubsetDistribution): - def mean(self) -> np.ndarray: + def mean(self): """ Convenient access to axis to have a consistent interface throughout manifolds. :return: The mean of the distribution. - :rtype: np.ndarray + :rtype: """ return self.mean_axis() @@ -42,8 +42,8 @@ def sample_metropolis_hastings( burn_in: Union[int, int32, int64] = 10, skipping: Union[int, int32, int64] = 5, proposal: Callable | None = None, - start_point: np.ndarray | None = None, - ) -> np.ndarray: + start_point: | None = None, + ): # jscpd:ignore-end if proposal is None: # For unimodal densities, other proposals may be far better. @@ -61,7 +61,7 @@ def proposal(_): n, burn_in, skipping, proposal=proposal, start_point=start_point ) - def mean_direction_numerical(self) -> np.ndarray: + def mean_direction_numerical(self): warning_msg = ( "The result is the mean direction on the upper hemisphere along the last dimension. " "It is not a mean of a symmetric distribution, which would not have a proper mean. " @@ -99,7 +99,7 @@ def mean_direction_numerical(self) -> np.ndarray: return mu @staticmethod - def get_full_integration_boundaries(dim: Union[int, int32, int64]) -> np.ndarray: + def get_full_integration_boundaries(dim: Union[int, int32, int64]): if dim == 1: integration_boundaries = [0, pi] else: @@ -113,7 +113,7 @@ def get_full_integration_boundaries(dim: Union[int, int32, int64]) -> np.ndarray ).T return integration_boundaries - def integrate(self, integration_boundaries: np.ndarray | None = None) -> float: + def integrate(self, integration_boundaries: | None = None) -> float: if integration_boundaries is None: integration_boundaries = ( AbstractHyperhemisphericalDistribution.get_full_integration_boundaries( @@ -123,7 +123,7 @@ def integrate(self, integration_boundaries: np.ndarray | None = None) -> float: return super().integrate(integration_boundaries) def integrate_numerically( - self, integration_boundaries: np.ndarray | None = None + self, integration_boundaries: | None = None ) -> float: if integration_boundaries is None: integration_boundaries = ( @@ -144,7 +144,7 @@ def integrate_fun_over_domain( f_hypersph_coords, dim, integration_boundaries ) - def mode_numerical(self) -> np.ndarray: + def mode_numerical(self): def objective_function_2d(s): return -self.pdf(AbstractHypersphereSubsetDistribution.polar_to_cart(s)) diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_dirac_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_dirac_distribution.py index 2a059dee..8312e2b6 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_dirac_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_dirac_distribution.py @@ -1,6 +1,6 @@ from pyrecest.backend import sum from pyrecest.backend import log -import numpy as np + from ..abstract_dirac_distribution import AbstractDiracDistribution from .abstract_hypersphere_subset_distribution import ( diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py index 382abc7d..a9848989 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py @@ -15,7 +15,7 @@ from abc import abstractmethod from collections.abc import Callable -import numpy as np + from beartype import beartype from scipy.integrate import nquad, quad from scipy.special import gamma @@ -171,7 +171,7 @@ def g_3d(phi1, phi2, phi3): return m @staticmethod - def _compute_mean_axis_from_moment(moment_matrix: np.ndarray) -> np.ndarray: + def _compute_mean_axis_from_moment(moment_matrix): D, V = linalg.eig(moment_matrix) Dsorted = sort(D) Vsorted = V[:, D.argsort()] @@ -183,15 +183,15 @@ def _compute_mean_axis_from_moment(moment_matrix: np.ndarray) -> np.ndarray: m = -Vsorted[:, -1] return m - def mean_axis(self) -> np.ndarray: + def mean_axis(self): mom = self.moment() return AbstractHypersphereSubsetDistribution._compute_mean_axis_from_moment(mom) - def mean_axis_numerical(self) -> np.ndarray: + def mean_axis_numerical(self): mom = self.moment_numerical() return AbstractHypersphereSubsetDistribution._compute_mean_axis_from_moment(mom) - def integrate(self, integration_boundaries: np.ndarray | None = None): + def integrate(self, integration_boundaries: | None = None): if integration_boundaries is None: integration_boundaries = self.__class__.get_full_integration_boundaries( self.dim @@ -342,7 +342,7 @@ def total_variation_distance(pdf1, pdf2): return 0.5 * distance_integral @staticmethod - def polar_to_cart(polar_coords: np.ndarray) -> np.ndarray: + def polar_to_cart(polar_coords): polar_coords = np.atleast_2d(polar_coords) coords = zeros( diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_uniform_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_uniform_distribution.py index c281c320..d4004c5b 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_uniform_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_uniform_distribution.py @@ -1,5 +1,5 @@ from pyrecest.backend import ones -import numpy as np + from beartype import beartype from ..abstract_uniform_distribution import AbstractUniformDistribution @@ -15,15 +15,15 @@ class AbstractHypersphereSubsetUniformDistribution( This is an abstract class for a uniform distribution over a subset of a hypersphere. """ - def pdf(self, xs: np.ndarray) -> np.ndarray: + def pdf(self, xs): """ Calculates the probability density function over the subset of the hypersphere. Args: - xs (np.ndarray): Input data points. + xs (): Input data points. Returns: - np.ndarray: Probability density at the given data points. + : Probability density at the given data points. """ if xs.shape[-1] != self.input_dim: raise ValueError("Invalid shape of input data points.") diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py index 055f67c6..b5bb6c17 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py @@ -15,7 +15,7 @@ from collections.abc import Callable import matplotlib.pyplot as plt -import numpy as np + from beartype import beartype from scipy.optimize import minimize @@ -35,7 +35,7 @@ def mean(self): throughout manifolds. :return: The mean of the distribution. - :rtype: np.ndarray + :rtype: """ return self.mean_direction() @@ -46,8 +46,8 @@ def sample_metropolis_hastings( burn_in: Union[int, int32, int64] = 10, skipping: Union[int, int32, int64] = 5, proposal: Callable | None = None, - start_point: np.ndarray | None = None, - ) -> np.ndarray: + start_point: | None = None, + ): # jscpd:ignore-end """ Sample from the distribution using Metropolis-Hastings algorithm. @@ -57,10 +57,10 @@ def sample_metropolis_hastings( burn_in (int, optional): Number of samples to discard at the start. Defaults to 10. skipping (int, optional): Number of samples to skip between each kept sample. Defaults to 5. proposal (function, optional): Proposal distribution for the Metropolis-Hastings algorithm. Defaults to None. - start_point (np.ndarray, optional): Starting point for the Metropolis-Hastings algorithm. Defaults to None. + start_point (, optional): Starting point for the Metropolis-Hastings algorithm. Defaults to None. Returns: - np.ndarray: Sampled points. + : Sampled points. """ if proposal is None: # For unimodal densities, other proposals may be far better. @@ -152,7 +152,7 @@ def plot( "Cannot plot hyperspherical distribution with this number of dimensions." ) - def moment(self) -> np.ndarray: + def moment(self): return self.moment_numerical() @staticmethod @@ -186,7 +186,7 @@ def integrate_numerically(self, integration_boundaries=None): def entropy(self): return super().entropy_numerical() - def mode_numerical(self) -> np.ndarray: + def mode_numerical(self): def fun(s): return -self.pdf(AbstractHypersphereSubsetDistribution.polar_to_cart(s)) diff --git a/pyrecest/distributions/hypersphere_subset/abstract_sphere_subset_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_sphere_subset_distribution.py index ad113bda..abbed88e 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_sphere_subset_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_sphere_subset_distribution.py @@ -5,7 +5,7 @@ from pyrecest.backend import cos from pyrecest.backend import arctan2 from pyrecest.backend import arccos -import numpy as np + from beartype import beartype from .abstract_hypersphere_subset_distribution import ( @@ -25,13 +25,13 @@ def __init__(self): super().__init__(2) @staticmethod - def sph_to_cart(phi: np.ndarray, theta: np.ndarray, mode="colatitude") -> tuple: + def sph_to_cart(phi, theta, mode="colatitude") -> tuple: """ Convert spherical coordinates to Cartesian coordinates. Args: - phi (np.ndarray): Azimuth angles. - theta (np.ndarray): Colatitude angles or elevation angles based on the mode. + phi (): Azimuth angles. + theta (): Colatitude angles or elevation angles based on the mode. mode (str): Either 'colatitude' or 'elevation'. Returns: @@ -53,15 +53,15 @@ def sph_to_cart(phi: np.ndarray, theta: np.ndarray, mode="colatitude") -> tuple: @staticmethod def cart_to_sph( - x: np.ndarray, y: np.ndarray, z: np.ndarray, mode="colatitude" + x, y, z, mode="colatitude" ) -> tuple: """ Convert Cartesian coordinates to spherical coordinates. Args: - x (np.ndarray): X coordinates. - y (np.ndarray): Y coordinates. - z (np.ndarray): Z coordinates. + x (): X coordinates. + y (): Y coordinates. + z (): Z coordinates. Returns: tuple: Spherical coordinates. @@ -83,7 +83,7 @@ def cart_to_sph( return phi, theta @staticmethod - def _sph_to_cart_colatitude(azimuth: np.ndarray, colatitude: np.ndarray) -> tuple: + def _sph_to_cart_colatitude(azimuth, colatitude: ) -> tuple: assert ndim(azimuth) == 1 and ndim( colatitude ), "Inputs must be 1-dimensional" @@ -93,14 +93,14 @@ def _sph_to_cart_colatitude(azimuth: np.ndarray, colatitude: np.ndarray) -> tupl return x, y, z @staticmethod - def _sph_to_cart_elevation(azimuth: np.ndarray, elevation: np.ndarray) -> tuple: + def _sph_to_cart_elevation(azimuth, elevation: ) -> tuple: """ Convert spherical coordinates (using elevation) to Cartesian coordinates. Assumes a radius of 1. Args: - azimuth (np.ndarray): Azimuth angles. - elevation (np.ndarray): Elevation angles. + azimuth (): Azimuth angles. + elevation (): Elevation angles. Returns: tuple: Cartesian coordinates. @@ -116,7 +116,7 @@ def _sph_to_cart_elevation(azimuth: np.ndarray, elevation: np.ndarray) -> tuple: return x, y, z @staticmethod - def _cart_to_sph_colatitude(x: np.ndarray, y: np.ndarray, z: np.ndarray) -> tuple: + def _cart_to_sph_colatitude(x, y, z: ) -> tuple: assert ndim(x) == 1 and ndim(y) == 1 and ndim(z) radius = 1 azimuth = arctan2(y, x) @@ -125,7 +125,7 @@ def _cart_to_sph_colatitude(x: np.ndarray, y: np.ndarray, z: np.ndarray) -> tupl return azimuth, colatitude @staticmethod - def _cart_to_sph_elevation(x: np.ndarray, y: np.ndarray, z: np.ndarray) -> tuple: + def _cart_to_sph_elevation(x, y, z: ) -> tuple: assert ndim(x) == 1 and ndim(y) == 1 and ndim(z) == 1 radius = 1 azimuth = arctan2(y, x) diff --git a/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py index 1c9f6b4e..6ad4581e 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py @@ -9,7 +9,7 @@ import copy import warnings -import numpy as np + from scipy.linalg import norm from ..abstract_orthogonal_basis_distribution import AbstractOrthogonalBasisDistribution diff --git a/pyrecest/distributions/hypersphere_subset/bingham_distribution.py b/pyrecest/distributions/hypersphere_subset/bingham_distribution.py index 651cf8ef..83683332 100644 --- a/pyrecest/distributions/hypersphere_subset/bingham_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/bingham_distribution.py @@ -7,7 +7,7 @@ from pyrecest.backend import all from pyrecest.backend import abs from pyrecest.backend import amax -import numpy as np + from scipy.integrate import quad from scipy.special import iv @@ -15,7 +15,7 @@ class BinghamDistribution(AbstractHypersphericalDistribution): - def __init__(self, Z: np.ndarray, M: np.ndarray): + def __init__(self, Z, M): AbstractHypersphericalDistribution.__init__(self, M.shape[0] - 1) assert M.shape[1] == self.input_dim, "M is not square" diff --git a/pyrecest/distributions/hypersphere_subset/custom_hyperhemispherical_distribution.py b/pyrecest/distributions/hypersphere_subset/custom_hyperhemispherical_distribution.py index 932c9a93..c2b66506 100644 --- a/pyrecest/distributions/hypersphere_subset/custom_hyperhemispherical_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/custom_hyperhemispherical_distribution.py @@ -3,7 +3,7 @@ from pyrecest.backend import int32 from collections.abc import Callable -import numpy as np + from beartype import beartype from ..abstract_custom_distribution import AbstractCustomDistribution diff --git a/pyrecest/distributions/hypersphere_subset/hyperhemispherical_uniform_distribution.py b/pyrecest/distributions/hypersphere_subset/hyperhemispherical_uniform_distribution.py index 025d36d4..443afa33 100644 --- a/pyrecest/distributions/hypersphere_subset/hyperhemispherical_uniform_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/hyperhemispherical_uniform_distribution.py @@ -1,7 +1,7 @@ from typing import Union from pyrecest.backend import int64 from pyrecest.backend import int32 -import numpy as np + from beartype import beartype from .abstract_hyperhemispherical_distribution import ( @@ -19,7 +19,7 @@ class HyperhemisphericalUniformDistribution( AbstractHyperhemisphericalDistribution, AbstractHypersphereSubsetUniformDistribution ): - def sample(self, n: Union[int, int32, int64]) -> np.ndarray: + def sample(self, n: Union[int, int32, int64]): """ Sample n points from the hyperhemispherical distribution. diff --git a/pyrecest/distributions/hypersphere_subset/hyperhemispherical_watson_distribution.py b/pyrecest/distributions/hypersphere_subset/hyperhemispherical_watson_distribution.py index 854136ab..928f8ea8 100644 --- a/pyrecest/distributions/hypersphere_subset/hyperhemispherical_watson_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/hyperhemispherical_watson_distribution.py @@ -6,7 +6,7 @@ from pyrecest.backend import zeros import numbers -import numpy as np + from beartype import beartype from .abstract_hyperhemispherical_distribution import ( @@ -16,7 +16,7 @@ class HyperhemisphericalWatsonDistribution(AbstractHyperhemisphericalDistribution): - def __init__(self, mu: np.ndarray, kappa: np.number | numbers.Real): + def __init__(self, mu, kappa: Any | numbers.Real): assert mu[-1] >= 0 self.dist_full_sphere = WatsonDistribution(mu, kappa) AbstractHyperhemisphericalDistribution.__init__( @@ -26,22 +26,22 @@ def __init__(self, mu: np.ndarray, kappa: np.number | numbers.Real): def pdf(self, xs): return 2 * self.dist_full_sphere.pdf(xs) - def set_mode(self, mu: np.ndarray) -> "HyperhemisphericalWatsonDistribution": + def set_mode(self, mu: ) -> "HyperhemisphericalWatsonDistribution": w = self w.mu = mu return w - def sample(self, n: Union[int, int32, int64]) -> np.ndarray: + def sample(self, n: Union[int, int32, int64]): s_full = self.dist_full_sphere.sample(n) s = s_full * (-1) ** (s_full[-1] < 0) # Mirror to upper hemisphere return s @property - def mu(self) -> np.ndarray: + def mu(self): return self.dist_full_sphere.mu @mu.setter - def mu(self, mu: np.ndarray): + def mu(self, mu): self.dist_full_sphere.mu = mu @property @@ -52,7 +52,7 @@ def kappa(self) -> float: def kappa(self, kappa: float): self.dist_full_sphere.kappa = kappa - def mode(self) -> np.ndarray: + def mode(self): return self.mu def shift(self, shift_by) -> "HyperhemisphericalWatsonDistribution": diff --git a/pyrecest/distributions/hypersphere_subset/hyperspherical_dirac_distribution.py b/pyrecest/distributions/hypersphere_subset/hyperspherical_dirac_distribution.py index dd373b29..a8b6bbc2 100644 --- a/pyrecest/distributions/hypersphere_subset/hyperspherical_dirac_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/hyperspherical_dirac_distribution.py @@ -2,7 +2,7 @@ from pyrecest.backend import sum from pyrecest.backend import reshape import matplotlib.pyplot as plt -import numpy as np + from ..circle.circular_dirac_distribution import CircularDiracDistribution from .abstract_hypersphere_subset_dirac_distribution import ( diff --git a/pyrecest/distributions/hypersphere_subset/hyperspherical_mixture.py b/pyrecest/distributions/hypersphere_subset/hyperspherical_mixture.py index fa35eb79..529f906c 100644 --- a/pyrecest/distributions/hypersphere_subset/hyperspherical_mixture.py +++ b/pyrecest/distributions/hypersphere_subset/hyperspherical_mixture.py @@ -1,4 +1,4 @@ -import numpy as np + from beartype import beartype from ..abstract_mixture import AbstractMixture diff --git a/pyrecest/distributions/hypersphere_subset/hyperspherical_uniform_distribution.py b/pyrecest/distributions/hypersphere_subset/hyperspherical_uniform_distribution.py index 7f2e979c..03e7999a 100644 --- a/pyrecest/distributions/hypersphere_subset/hyperspherical_uniform_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/hyperspherical_uniform_distribution.py @@ -8,7 +8,7 @@ from pyrecest.backend import int64 from pyrecest.backend import int32 from pyrecest.backend import empty -import numpy as np + from beartype import beartype from .abstract_hypersphere_subset_uniform_distribution import ( @@ -23,7 +23,7 @@ class HypersphericalUniformDistribution( def __init__(self, dim: Union[int, int32, int64]): AbstractHypersphereSubsetUniformDistribution.__init__(self, dim) - def pdf(self, xs: np.ndarray): + def pdf(self, xs): return AbstractHypersphereSubsetUniformDistribution.pdf(self, xs) def sample(self, n: Union[int, int32, int64]): diff --git a/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py b/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py index 4d3141f2..2d772296 100644 --- a/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py +++ b/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py @@ -13,7 +13,7 @@ from pyrecest.backend import abs from pyrecest.backend import empty from pyrecest.backend import zeros -import numpy as np + import scipy # pylint: disable=E0611 diff --git a/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_real.py b/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_real.py index 3803b655..71d62c73 100644 --- a/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_real.py +++ b/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_real.py @@ -3,7 +3,7 @@ from pyrecest.backend import imag from pyrecest.backend import all from pyrecest.backend import zeros -import numpy as np + # pylint: disable=E0611 from scipy.special import sph_harm diff --git a/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py b/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py index bf18fbbc..cde696c6 100644 --- a/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py @@ -15,7 +15,7 @@ from pyrecest.backend import int32 import numbers -import numpy as np + from beartype import beartype from scipy.linalg import qr from scipy.special import iv @@ -24,7 +24,7 @@ class VonMisesFisherDistribution(AbstractHypersphericalDistribution): - def __init__(self, mu: np.ndarray, kappa: np.number | numbers.Real): + def __init__(self, mu, kappa: Any | numbers.Real): AbstractHypersphericalDistribution.__init__(self, dim=mu.shape[0] - 1) epsilon = 1e-6 assert ( @@ -42,7 +42,7 @@ def __init__(self, mu: np.ndarray, kappa: np.number | numbers.Real): (2.0 * pi) ** ((self.dim + 1) / 2.0) * iv((self.dim + 1) / 2 - 1, kappa) ) - def pdf(self, xs: np.ndarray | np.number) -> np.ndarray | np.number: + def pdf(self, xs: | Any) -> | Any: assert xs.shape[-1] == self.input_dim return self.C * exp(self.kappa * self.mu.T @ xs.T) @@ -95,7 +95,7 @@ def get_rotation_matrix(self): Q = -Q return Q - def moment(self) -> np.ndarray: + def moment(self): """ Returns the mean resultant vector. """ @@ -110,7 +110,7 @@ def from_distribution(d: AbstractHypersphericalDistribution): return VonMisesFisherDistribution.from_moment(m) @staticmethod - def from_moment(m: np.ndarray): + def from_moment(m): assert ndim(m) == 1, "mu must be a vector" assert len(m) >= 2, "mu must be at least 2 for the circular case" @@ -124,7 +124,7 @@ def from_moment(m: np.ndarray): def mode(self): return self.mu - def set_mode(self, new_mode: np.ndarray): + def set_mode(self, new_mode): assert new_mode.shape == self.mu.shape dist = self dist.mu = new_mode @@ -152,7 +152,7 @@ def convolve(self, other: "VonMisesFisherDistribution"): return VonMisesFisherDistribution(mu_, kappa_) @staticmethod - def a_d(d: Union[int, int32, int64], kappa: np.number | numbers.Real): + def a_d(d: Union[int, int32, int64], kappa: Any | numbers.Real): bessel1 = iv(d / 2, kappa) bessel2 = iv(d / 2 - 1, kappa) if isnan(bessel1) or isnan(bessel2): diff --git a/pyrecest/distributions/hypersphere_subset/watson_distribution.py b/pyrecest/distributions/hypersphere_subset/watson_distribution.py index 45a9de0a..c436bb04 100644 --- a/pyrecest/distributions/hypersphere_subset/watson_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/watson_distribution.py @@ -12,7 +12,7 @@ import numbers import mpmath -import numpy as np + from beartype import beartype from scipy.linalg import qr @@ -23,12 +23,12 @@ class WatsonDistribution(AbstractHypersphericalDistribution): EPSILON = 1e-6 - def __init__(self, mu: np.ndarray, kappa: np.number | numbers.Real): + def __init__(self, mu, kappa: Any | numbers.Real): """ Initializes a new instance of the WatsonDistribution class. Args: - mu (np.ndarray): The mean direction of the distribution. + mu (): The mean direction of the distribution. kappa (float): The concentration parameter of the distribution. """ AbstractHypersphericalDistribution.__init__(self, dim=mu.shape[0] - 1) diff --git a/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py b/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py index 5a4aa69a..8253a37d 100644 --- a/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py +++ b/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py @@ -23,7 +23,7 @@ from collections.abc import Callable import matplotlib.pyplot as plt -import numpy as np + from beartype import beartype from scipy.integrate import nquad @@ -87,7 +87,7 @@ def integrate_fun_over_domain_part( def integrate_numerically( self, integration_boundaries=None - ) -> np.number | numbers.Real: + ): assert pyrecest.backend.__name__ == 'pyrecest.numpy', "Only supported for numpy backend" if integration_boundaries is None: integration_boundaries = vstack( @@ -104,7 +104,7 @@ def integrate_numerically( def trigonometric_moment_numerical( self, n: Union[int, int32, int64] - ) -> np.ndarray: + ): """Calculates the complex trignometric moments. Since nquad does not support complex functions, the calculation is split up (as used in the alternative representation of trigonometric polonymials involving the two real numbers alpha and beta""" @@ -218,35 +218,35 @@ def plot(self, resolution=128, **kwargs): plt.show() return p - def mean(self) -> np.ndarray: + def mean(self): """ Convenient access to mean_direction to have a consistent interface throughout manifolds. :return: The mean of the distribution. - :rtype: np.ndarray + :rtype: """ return self.mean_direction() - def mean_direction(self) -> np.ndarray: + def mean_direction(self): a = self.trigonometric_moment(1) m = mod(np.angle(a), 2.0 * pi) return m - def mode(self) -> np.ndarray: + def mode(self): return self.mode_numerical() - def mode_numerical(self) -> np.ndarray: + def mode_numerical(self): # Implement the optimization function fminunc equivalent in Python (e.g., using scipy.optimize.minimize) raise NotImplementedError("Mode calculation is not implemented") - def trigonometric_moment(self, n: Union[int, int32, int64]) -> np.ndarray: + def trigonometric_moment(self, n: Union[int, int32, int64]): return self.trigonometric_moment_numerical(n) def integrate(self, integration_boundaries=None): return self.integrate_numerically(integration_boundaries) - def mean_2dimD(self) -> np.ndarray: + def mean_2dimD(self): m = self.trigonometric_moment_numerical(1) mu = vstack((m.real, m.imag)) return mu @@ -258,8 +258,8 @@ def sample_metropolis_hastings( burn_in: Union[int, int32, int64] = 10, skipping: Union[int, int32, int64] = 5, proposal: Callable | None = None, - start_point: np.number | numbers.Real | np.ndarray | None = None, - ) -> np.ndarray: + start_point = None, + ): # jscpd:ignore-end if proposal is None: diff --git a/pyrecest/distributions/hypertorus/abstract_toroidal_distribution.py b/pyrecest/distributions/hypertorus/abstract_toroidal_distribution.py index 900f3190..112b441f 100644 --- a/pyrecest/distributions/hypertorus/abstract_toroidal_distribution.py +++ b/pyrecest/distributions/hypertorus/abstract_toroidal_distribution.py @@ -7,7 +7,7 @@ from pyrecest.backend import int64 from pyrecest.backend import int32 from pyrecest.backend import zeros -import numpy as np + from scipy.integrate import dblquad from .abstract_hypertoroidal_distribution import AbstractHypertoroidalDistribution @@ -17,7 +17,7 @@ class AbstractToroidalDistribution(AbstractHypertoroidalDistribution): def __init__(self): AbstractHypertoroidalDistribution.__init__(self, 2) - def covariance_4D_numerical(self) -> np.ndarray: + def covariance_4D_numerical(self): m = self.mean_4D() def f( @@ -66,7 +66,7 @@ def fsinBsquared(x, y): rhoc = EsinAsinB / sqrt(EsinAsquared * EsinBsquared) return rhoc - def mean_4D(self) -> np.ndarray: + def mean_4D(self): """ Calculates the 4D mean of [cos(x1), sin(x1), cos(x2), sin(x2)] diff --git a/pyrecest/distributions/hypertorus/custom_hypertoroidal_distribution.py b/pyrecest/distributions/hypertorus/custom_hypertoroidal_distribution.py index 1b6fbd42..af6d61c1 100644 --- a/pyrecest/distributions/hypertorus/custom_hypertoroidal_distribution.py +++ b/pyrecest/distributions/hypertorus/custom_hypertoroidal_distribution.py @@ -1,10 +1,10 @@ from math import pi from pyrecest.backend import mod from pyrecest.backend import zeros -import numpy as np + from ..abstract_custom_distribution import AbstractCustomDistribution -from ..circle.custom_circular_distribution import CustomCircularDistribution + from .abstract_hypertoroidal_distribution import AbstractHypertoroidalDistribution diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py b/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py index edb2e218..fa263620 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py @@ -13,7 +13,7 @@ import copy from collections.abc import Callable -import numpy as np + from beartype import beartype from ..abstract_dirac_distribution import AbstractDiracDistribution @@ -24,7 +24,7 @@ class HypertoroidalDiracDistribution( AbstractDiracDistribution, AbstractHypertoroidalDistribution ): def __init__( - self, d: np.ndarray, w: np.ndarray | None = None, dim: int | None = None + self, d, w=None, dim: int | None = None ): """Can set dim manually to tell apart number of samples vs dimension for 1-D arrays.""" if dim is None: @@ -43,7 +43,7 @@ def __init__( def plot(self, *args, **kwargs): raise NotImplementedError("Plotting is not implemented") - def mean_direction(self) -> np.ndarray: + def mean_direction(self): """ Calculate the mean direction of the HypertoroidalDiracDistribution. @@ -54,7 +54,7 @@ def mean_direction(self) -> np.ndarray: m = mod(arctan2(imag(a), real(a)), 2 * pi) return m - def trigonometric_moment(self, n: Union[int, int32, int64]) -> np.ndarray: + def trigonometric_moment(self, n: Union[int, int32, int64]): """ Calculate the trigonometric moment of the HypertoroidalDiracDistribution. diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_mixture.py b/pyrecest/distributions/hypertorus/hypertoroidal_mixture.py index 9a1f43db..ee5730ee 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_mixture.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_mixture.py @@ -6,7 +6,7 @@ import collections import copy -import numpy as np + from beartype import beartype from ..abstract_mixture import AbstractMixture @@ -17,7 +17,7 @@ class HypertoroidalMixture(AbstractMixture, AbstractHypertoroidalDistribution): def __init__( self, dists: collections.abc.Sequence[AbstractHypertoroidalDistribution], - w: np.ndarray | None = None, + w: | None = None, ): """ Constructor @@ -32,7 +32,7 @@ def __init__( AbstractHypertoroidalDistribution ] = self.dists - def trigonometric_moment(self, n: Union[int, int32, int64]) -> np.ndarray: + def trigonometric_moment(self, n: Union[int, int32, int64]): """ Calculate n-th trigonometric moment diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_uniform_distribution.py b/pyrecest/distributions/hypertorus/hypertoroidal_uniform_distribution.py index 0b0d7dbf..4144ff5a 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_uniform_distribution.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_uniform_distribution.py @@ -8,7 +8,7 @@ from pyrecest.backend import int64 from pyrecest.backend import int32 from pyrecest.backend import zeros -import numpy as np + from ..abstract_uniform_distribution import AbstractUniformDistribution from .abstract_hypertoroidal_distribution import AbstractHypertoroidalDistribution @@ -17,7 +17,7 @@ class HypertoroidalUniformDistribution( AbstractUniformDistribution, AbstractHypertoroidalDistribution ): - def pdf(self, xs: np.ndarray) -> np.ndarray: + def pdf(self, xs): """ Returns the Probability Density Function evaluated at xs @@ -26,7 +26,7 @@ def pdf(self, xs: np.ndarray) -> np.ndarray: """ return 1 / self.get_manifold_size() * ones(xs.shape[0]) - def trigonometric_moment(self, n: Union[int, int32, int64]) -> np.ndarray: + def trigonometric_moment(self, n: Union[int, int32, int64]): """ Returns the n-th trigonometric moment @@ -57,7 +57,7 @@ def mean_direction(self): "Hypertoroidal uniform distributions do not have a unique mean" ) - def sample(self, n: Union[int, int32, int64]) -> np.ndarray: + def sample(self, n: Union[int, int32, int64]): """ Returns a sample of size n from the distribution @@ -78,7 +78,7 @@ def shift(self, shift_by) -> "HypertoroidalUniformDistribution": return self def integrate( - self, integration_boundaries: tuple[np.ndarray, np.ndarray] | None = None + self, integration_boundaries: tuple[, ] | None = None ) -> float: """ Returns the integral of the distribution over the specified boundaries diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py b/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py index ef817d85..ff257f4f 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py @@ -15,7 +15,7 @@ from pyrecest.backend import zeros import copy -import numpy as np + from beartype import beartype from scipy.stats import multivariate_normal @@ -23,7 +23,7 @@ class HypertoroidalWrappedNormalDistribution(AbstractHypertoroidalDistribution): - def __init__(self, mu: np.ndarray, C: np.ndarray): + def __init__(self, mu, C): """ Initialize HypertoroidalWrappedNormalDistribution. @@ -44,7 +44,7 @@ def __init__(self, mu: np.ndarray, C: np.ndarray): self.mu = mod(mu, 2.0 * pi) self.C = C - def pdf(self, xs: np.ndarray, m: Union[int, int32, int64] = 3) -> np.ndarray: + def pdf(self, xs, m: Union[int, int32, int64] = 3): """ Compute the PDF at given points. diff --git a/pyrecest/distributions/hypertorus/toroidal_dirac_distribution.py b/pyrecest/distributions/hypertorus/toroidal_dirac_distribution.py index 0f2800b5..5812dac4 100644 --- a/pyrecest/distributions/hypertorus/toroidal_dirac_distribution.py +++ b/pyrecest/distributions/hypertorus/toroidal_dirac_distribution.py @@ -5,7 +5,7 @@ from pyrecest.backend import sin from pyrecest.backend import dot from pyrecest.backend import cos -import numpy as np + from .abstract_toroidal_distribution import AbstractToroidalDistribution from .hypertoroidal_dirac_distribution import HypertoroidalDiracDistribution @@ -14,7 +14,7 @@ class ToroidalDiracDistribution( HypertoroidalDiracDistribution, AbstractToroidalDistribution ): - def __init__(self, d: np.ndarray, w: np.ndarray | None = None): + def __init__(self, d, w: | None = None): """ Initialize ToroidalDiracDistribution. @@ -40,7 +40,7 @@ def circular_correlation_jammalamadaka(self) -> float: rhoc = x / y return rhoc - def covariance_4D(self) -> np.ndarray: + def covariance_4D(self): """ Compute the 4D covariance matrix. diff --git a/pyrecest/distributions/hypertorus/toroidal_mixture.py b/pyrecest/distributions/hypertorus/toroidal_mixture.py index d09c69c6..daa953c9 100644 --- a/pyrecest/distributions/hypertorus/toroidal_mixture.py +++ b/pyrecest/distributions/hypertorus/toroidal_mixture.py @@ -1,11 +1,11 @@ -import numpy as np + from .abstract_toroidal_distribution import AbstractToroidalDistribution from .hypertoroidal_mixture import HypertoroidalMixture class ToroidalMixture(HypertoroidalMixture, AbstractToroidalDistribution): - def __init__(self, hds: list[AbstractToroidalDistribution], w: np.ndarray): + def __init__(self, hds: list[AbstractToroidalDistribution], w): """ Constructor diff --git a/pyrecest/distributions/hypertorus/toroidal_von_mises_sine_distribution.py b/pyrecest/distributions/hypertorus/toroidal_von_mises_sine_distribution.py index 7ac03f6f..9f95baf4 100644 --- a/pyrecest/distributions/hypertorus/toroidal_von_mises_sine_distribution.py +++ b/pyrecest/distributions/hypertorus/toroidal_von_mises_sine_distribution.py @@ -5,7 +5,7 @@ from pyrecest.backend import exp from pyrecest.backend import cos from pyrecest.backend import all -import numpy as np + from scipy.special import comb, iv from .abstract_toroidal_distribution import AbstractToroidalDistribution diff --git a/pyrecest/distributions/hypertorus/toroidal_wrapped_normal_distribution.py b/pyrecest/distributions/hypertorus/toroidal_wrapped_normal_distribution.py index 44807c57..a8aaa235 100644 --- a/pyrecest/distributions/hypertorus/toroidal_wrapped_normal_distribution.py +++ b/pyrecest/distributions/hypertorus/toroidal_wrapped_normal_distribution.py @@ -1,5 +1,5 @@ from pyrecest.backend import array -import numpy as np + from numpy import cos, exp, sin from .abstract_toroidal_distribution import AbstractToroidalDistribution @@ -15,7 +15,7 @@ class ToroidalWrappedNormalDistribution( Toroidal Wrapped Normal Distribution. """ - def mean_4D(self) -> np.ndarray: + def mean_4D(self): """ Compute the 4D mean of the distribution. @@ -33,7 +33,7 @@ def mean_4D(self) -> np.ndarray: ) return mu - def covariance_4D(self) -> np.ndarray: + def covariance_4D(self): """ Compute the 4D covariance of the distribution. diff --git a/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py b/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py index 8f062dd5..fc3f647b 100644 --- a/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py +++ b/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py @@ -15,7 +15,7 @@ from collections.abc import Callable import matplotlib.pyplot as plt -import numpy as np + from pyrecest.utils.plotting import plot_ellipsoid from scipy.integrate import dblquad, nquad, quad from scipy.optimize import minimize @@ -39,7 +39,7 @@ def covariance(self): return self.covariance_numerical() def get_manifold_size(self): - return np.inf + return float('inf') def mode(self, starting_point=None): return self.mode_numerical(starting_point) @@ -67,8 +67,8 @@ def sample_metropolis_hastings( burn_in: Union[int, int32, int64] = 10, skipping: Union[int, int32, int64] = 5, proposal: Callable | None = None, - start_point: np.number | numbers.Real | np.ndarray | None = None, - ) -> np.ndarray: + start_point = None, + ): if proposal is None: def proposal(x): @@ -96,17 +96,17 @@ def mean_numerical(self): elif self.dim == 2: mu[0] = dblquad( lambda x, y: x * self.pdf(array([x, y])), - -np.inf, - np.inf, - lambda _: -np.inf, - lambda _: np.inf, + -float('inf'), + float('inf'), + lambda _: -float('inf'), + lambda _: float('inf'), )[0] mu[1] = dblquad( lambda x, y: y * self.pdf(array([x, y])), - -np.inf, - np.inf, - lambda _: -np.inf, - lambda _: np.inf, + -float('inf'), + float('inf'), + lambda _: -float('inf'), + lambda _: float('inf'), )[0] elif self.dim == 3: def integrand1(x, y, z): @@ -119,13 +119,13 @@ def integrand3(x, y, z): return z * self.pdf(array([x, y, z])) mu[0] = nquad( - integrand1, [[-np.inf, np.inf], [-np.inf, np.inf], [-np.inf, np.inf]] + integrand1, [[-float('inf'), float('inf')], [-float('inf'), float('inf')], [-float('inf'), float('inf')]] )[0] mu[1] = nquad( - integrand2, [[-np.inf, np.inf], [-np.inf, np.inf], [-np.inf, np.inf]] + integrand2, [[-float('inf'), float('inf')], [-float('inf'), float('inf')], [-float('inf'), float('inf')]] )[0] mu[2] = nquad( - integrand3, [[-np.inf, np.inf], [-np.inf, np.inf], [-np.inf, np.inf]] + integrand3, [[-float('inf'), float('inf')], [-float('inf'), float('inf')], [-float('inf'), float('inf')]] )[0] else: raise ValueError( @@ -136,7 +136,7 @@ def integrand3(x, y, z): def covariance_numerical(self): mu = self.mean() if self.dim == 1: - C = quad(lambda x: (x - mu) ** 2 * self.pdf(x), -np.inf, np.inf)[0] + C = quad(lambda x: (x - mu) ** 2 * self.pdf(x), -float('inf'), float('inf'))[0] elif self.dim == 2: C = empty((2, 2)) @@ -149,10 +149,10 @@ def integrand2(x, y): def integrand3(x, y): return (y - mu[1]) ** 2 * self.pdf(array([x, y])) - C[0, 0] = nquad(integrand1, [[-np.inf, np.inf], [-np.inf, np.inf]])[0] - C[0, 1] = nquad(integrand2, [[-np.inf, np.inf], [-np.inf, np.inf]])[0] + C[0, 0] = nquad(integrand1, [[-float('inf'), float('inf')], [-float('inf'), float('inf')]])[0] + C[0, 1] = nquad(integrand2, [[-float('inf'), float('inf')], [-float('inf'), float('inf')]])[0] C[1, 0] = C[0, 1] - C[1, 1] = nquad(integrand3, [[-np.inf, np.inf], [-np.inf, np.inf]])[0] + C[1, 1] = nquad(integrand3, [[-float('inf'), float('inf')], [-float('inf'), float('inf')]])[0] else: raise NotImplementedError( "Covariance numerical not supported for this dimension." @@ -161,9 +161,9 @@ def integrand3(x, y): def integrate(self, left=None, right=None): if left is None: - left = -np.inf * ones(self.dim) + left = -float('inf') * ones(self.dim) if right is None: - right = np.inf * ones(self.dim) + right = float('inf') * ones(self.dim) result = self.integrate_numerically(left, right) return result diff --git a/pyrecest/distributions/nonperiodic/custom_linear_distribution.py b/pyrecest/distributions/nonperiodic/custom_linear_distribution.py index 70b61042..1966ec16 100644 --- a/pyrecest/distributions/nonperiodic/custom_linear_distribution.py +++ b/pyrecest/distributions/nonperiodic/custom_linear_distribution.py @@ -2,7 +2,7 @@ from pyrecest.backend import ndim import copy -import numpy as np + from ..abstract_custom_nonperiodic_distribution import ( AbstractCustomNonPeriodicDistribution, diff --git a/pyrecest/distributions/nonperiodic/gaussian_distribution.py b/pyrecest/distributions/nonperiodic/gaussian_distribution.py index 7ca73daf..26af2395 100644 --- a/pyrecest/distributions/nonperiodic/gaussian_distribution.py +++ b/pyrecest/distributions/nonperiodic/gaussian_distribution.py @@ -4,7 +4,7 @@ from pyrecest.backend import dot import copy -import numpy as np + from beartype import beartype from scipy.linalg import cholesky from scipy.stats import multivariate_normal as mvn @@ -13,7 +13,7 @@ class GaussianDistribution(AbstractLinearDistribution): - def __init__(self, mu: np.ndarray, C: np.ndarray, check_validity=True): + def __init__(self, mu, C, check_validity=True): AbstractLinearDistribution.__init__(self, dim=mu.shape[0]) assert ndim(mu) <= 1 assert ( diff --git a/pyrecest/distributions/nonperiodic/gaussian_mixture.py b/pyrecest/distributions/nonperiodic/gaussian_mixture.py index 332b4e43..2f23e5a6 100644 --- a/pyrecest/distributions/nonperiodic/gaussian_mixture.py +++ b/pyrecest/distributions/nonperiodic/gaussian_mixture.py @@ -5,7 +5,7 @@ from pyrecest.backend import array import numbers -import numpy as np + from beartype import beartype from .abstract_linear_distribution import AbstractLinearDistribution @@ -15,7 +15,7 @@ class GaussianMixture(LinearMixture, AbstractLinearDistribution): - def __init__(self, dists: list[GaussianDistribution], w: np.ndarray): + def __init__(self, dists: list[GaussianDistribution], w): AbstractLinearDistribution.__init__(self, dim=dists[0].dim) LinearMixture.__init__(self, dists, w) @@ -23,7 +23,7 @@ def mean(self): gauss_array = self.dists return dot(array([g.mu for g in gauss_array]), self.w) - def set_mean(self, new_mean: np.ndarray | numbers.Real): + def set_mean(self, new_mean: | numbers.Real): mean_offset = new_mean - self.mean() for dist in self.dists: dist.mu += mean_offset # type: ignore diff --git a/pyrecest/distributions/nonperiodic/linear_dirac_distribution.py b/pyrecest/distributions/nonperiodic/linear_dirac_distribution.py index 890bae55..c2dba437 100644 --- a/pyrecest/distributions/nonperiodic/linear_dirac_distribution.py +++ b/pyrecest/distributions/nonperiodic/linear_dirac_distribution.py @@ -1,7 +1,7 @@ from pyrecest.backend import reshape from pyrecest.backend import ones import matplotlib.pyplot as plt -import numpy as np + from ..abstract_dirac_distribution import AbstractDiracDistribution from .abstract_linear_distribution import AbstractLinearDistribution diff --git a/pyrecest/distributions/nonperiodic/linear_mixture.py b/pyrecest/distributions/nonperiodic/linear_mixture.py index 5b50e2bb..acc27974 100644 --- a/pyrecest/distributions/nonperiodic/linear_mixture.py +++ b/pyrecest/distributions/nonperiodic/linear_mixture.py @@ -1,6 +1,6 @@ import warnings -import numpy as np + from beartype import beartype from ..abstract_mixture import AbstractMixture @@ -9,7 +9,7 @@ class LinearMixture(AbstractMixture, AbstractLinearDistribution): - def __init__(self, dists: list[AbstractLinearDistribution], w: np.ndarray): + def __init__(self, dists: list[AbstractLinearDistribution], w): from .gaussian_mixture import GaussianMixture assert all( diff --git a/pyrecest/distributions/se3_cart_prod_stacked_distribution.py b/pyrecest/distributions/se3_cart_prod_stacked_distribution.py index 71fe68dc..88951093 100644 --- a/pyrecest/distributions/se3_cart_prod_stacked_distribution.py +++ b/pyrecest/distributions/se3_cart_prod_stacked_distribution.py @@ -1,4 +1,4 @@ -import numpy as np + from .abstract_se3_distribution import AbstractSE3Distribution from .cart_prod.cart_prod_stacked_distribution import CartProdStackedDistribution @@ -18,7 +18,7 @@ def marginalize_periodic(self): return self.dists[1] def get_manifold_size(self): - return np.inf + return float('inf') def pdf(self, xs): return CartProdStackedDistribution.pdf(self, xs) \ No newline at end of file diff --git a/pyrecest/distributions/se3_dirac_distribution.py b/pyrecest/distributions/se3_dirac_distribution.py index ea5776af..6beeecec 100644 --- a/pyrecest/distributions/se3_dirac_distribution.py +++ b/pyrecest/distributions/se3_dirac_distribution.py @@ -1,5 +1,5 @@ from pyrecest.backend import ones -import numpy as np + from .abstract_se3_distribution import AbstractSE3Distribution from .cart_prod.lin_hypersphere_cart_prod_dirac_distribution import ( @@ -27,7 +27,7 @@ def mean(self): throughout manifolds. :return: The mean of the distribution. - :rtype: np.ndarray + :rtype: """ m = self.hybrid_mean() return m diff --git a/pyrecest/evaluation/determine_all_deviations.py b/pyrecest/evaluation/determine_all_deviations.py index 691f3a80..3276ef3a 100644 --- a/pyrecest/evaluation/determine_all_deviations.py +++ b/pyrecest/evaluation/determine_all_deviations.py @@ -5,7 +5,7 @@ import warnings from typing import Callable -import numpy as np + from beartype import beartype @@ -13,15 +13,15 @@ def determine_all_deviations( results, extract_mean, distance_function: Callable, - groundtruths: np.ndarray, + groundtruths: , mean_calculation_symm: str = "", -) -> np.ndarray: +): if mean_calculation_symm != "": raise NotImplementedError("Not implemented yet") assert ( ndim(groundtruths) == 2 - and isinstance(groundtruths[0, 0], np.ndarray) + and isinstance(groundtruths[0, 0], ) and ndim(groundtruths[0, 0]) in ( 1, @@ -33,7 +33,7 @@ def determine_all_deviations( for config_no, result_curr_config in enumerate(results): for run in range(len(groundtruths)): - if isinstance(result_curr_config[run], np.ndarray): + if isinstance(result_curr_config[run], ): # If estimates are already given as numpy array, use it final_estimate = result_curr_config[run] elif callable(extract_mean): @@ -48,7 +48,7 @@ def determine_all_deviations( ) else: warnings.warn("No estimate for this filter, setting error to inf.") - all_deviations_last_mat[config_no][run] = np.inf + all_deviations_last_mat[config_no][run] = float('inf') if any(np.isinf(all_deviations_last_mat[config_no])): print( diff --git a/pyrecest/evaluation/eot_shape_database.py b/pyrecest/evaluation/eot_shape_database.py index efc7a5ed..4934caa6 100644 --- a/pyrecest/evaluation/eot_shape_database.py +++ b/pyrecest/evaluation/eot_shape_database.py @@ -5,7 +5,7 @@ from pyrecest.backend import cos from pyrecest.backend import array from pyrecest.backend import empty -import numpy as np + from shapely.geometry import LineString, MultiLineString, Point, Polygon from shapely.ops import unary_union @@ -18,7 +18,7 @@ def __new__(cls, shell=None, holes=None): # nosec polygon.__class__ = cls return polygon - def sample_on_boundary(self, num_points: int) -> np.ndarray: + def sample_on_boundary(self, num_points: int): points = empty((num_points,), dtype=Point) if isinstance(self.boundary, LineString): @@ -42,7 +42,7 @@ def sample_on_boundary(self, num_points: int) -> np.ndarray: return array([(point.x, point.y) for point in points]) - def sample_within(self, num_points: int) -> np.ndarray: + def sample_within(self, num_points: int): min_x, min_y, max_x, max_y = self.bounds points = empty((num_points,), dtype=Point) diff --git a/pyrecest/evaluation/evaluate_for_file.py b/pyrecest/evaluation/evaluate_for_file.py index 681786f8..6aa6656f 100644 --- a/pyrecest/evaluation/evaluate_for_file.py +++ b/pyrecest/evaluation/evaluate_for_file.py @@ -4,7 +4,7 @@ import os from typing import Any -import numpy as np + from .evaluate_for_variables import evaluate_for_variables @@ -25,11 +25,11 @@ def evaluate_for_file( ) -> tuple[ dict, list[dict], - np.ndarray, - np.ndarray, - np.ndarray, - np.ndarray, - np.ndarray[np.ndarray], + , + , + , + , + [], ]: data = np.load(input_file_name, allow_pickle=True).item() diff --git a/pyrecest/evaluation/evaluate_for_simulation_config.py b/pyrecest/evaluation/evaluate_for_simulation_config.py index e0e4b913..9f37729c 100644 --- a/pyrecest/evaluation/evaluate_for_simulation_config.py +++ b/pyrecest/evaluation/evaluate_for_simulation_config.py @@ -1,7 +1,7 @@ import random from typing import Any, Optional -import numpy as np + from beartype import beartype from .evaluate_for_variables import evaluate_for_variables @@ -29,11 +29,11 @@ def evaluate_for_simulation_config( ) -> tuple[ dict, list[dict], - np.ndarray, - np.ndarray, - np.ndarray, - np.ndarray, - np.ndarray[np.ndarray], + , + , + , + , + [], ]: if isinstance(simulation_config, str): simulation_name = simulation_config diff --git a/pyrecest/evaluation/evaluate_for_variables.py b/pyrecest/evaluation/evaluate_for_variables.py index 1604dbdf..ce21762e 100644 --- a/pyrecest/evaluation/evaluate_for_variables.py +++ b/pyrecest/evaluation/evaluate_for_variables.py @@ -2,7 +2,7 @@ import os from typing import Any -import numpy as np + from .iterate_configs_and_runs import iterate_configs_and_runs diff --git a/pyrecest/evaluation/generate_groundtruth.py b/pyrecest/evaluation/generate_groundtruth.py index 9815fa49..edade1d8 100644 --- a/pyrecest/evaluation/generate_groundtruth.py +++ b/pyrecest/evaluation/generate_groundtruth.py @@ -2,7 +2,7 @@ from pyrecest.backend import ndim from pyrecest.backend import empty from pyrecest.backend import empty_like -import numpy as np + # pylint: disable=too-many-branches @@ -15,7 +15,7 @@ def generate_groundtruth(simulation_param, x0=None): x0 (ndarray): Starting point (optional). Returns: - groundtruth (np.ndarray[np.ndarray]): Generated ground truth as an + groundtruth ([]): Generated ground truth as an array of arrays (!) because the size of the ground truth is not necessarily the same over time (e.g., if the number of targets changes) """ @@ -29,7 +29,7 @@ def generate_groundtruth(simulation_param, x0=None): ), "Mismatch in number of targets." # Initialize ground truth - groundtruth = empty(simulation_param["n_timesteps"], dtype=np.ndarray) + groundtruth = empty(simulation_param["n_timesteps"], dtype=) if "inputs" in simulation_param: assert ( diff --git a/pyrecest/evaluation/generate_measurements.py b/pyrecest/evaluation/generate_measurements.py index b1968a1e..d7511f4b 100644 --- a/pyrecest/evaluation/generate_measurements.py +++ b/pyrecest/evaluation/generate_measurements.py @@ -8,7 +8,7 @@ from pyrecest.backend import dot from pyrecest.backend import empty from pyrecest.backend import zeros -import numpy as np + from beartype import beartype from pyrecest.distributions import ( AbstractHypertoroidalDistribution, @@ -40,7 +40,7 @@ def generate_measurements(groundtruth, simulation_config): assert "n_meas_at_individual_time_step" not in simulation_config or shape( simulation_config["n_meas_at_individual_time_step"] ) == (simulation_config["n_timesteps"],) - measurements = empty(simulation_config["n_timesteps"], dtype=np.ndarray) + measurements = empty(simulation_config["n_timesteps"], dtype=) if simulation_config.get("mtt", False) and simulation_config.get("eot", False): raise NotImplementedError( diff --git a/pyrecest/evaluation/generate_simulated_scenarios.py b/pyrecest/evaluation/generate_simulated_scenarios.py index c1150c63..44662bae 100644 --- a/pyrecest/evaluation/generate_simulated_scenarios.py +++ b/pyrecest/evaluation/generate_simulated_scenarios.py @@ -1,6 +1,6 @@ from pyrecest.backend import random from pyrecest.backend import empty -import numpy as np + from .check_and_fix_config import check_and_fix_config from .generate_groundtruth import generate_groundtruth @@ -25,11 +25,11 @@ def generate_simulated_scenarios( groundtruths = empty( (np.size(simulation_params["all_seeds"]), simulation_params["n_timesteps"]), - dtype=np.ndarray, + dtype=, ) measurements = empty( (np.size(simulation_params["all_seeds"]), simulation_params["n_timesteps"]), - dtype=np.ndarray, + dtype=, ) for run, seed in enumerate(simulation_params["all_seeds"]): diff --git a/pyrecest/evaluation/get_distance_function.py b/pyrecest/evaluation/get_distance_function.py index 8fbe83cb..2b0ba634 100644 --- a/pyrecest/evaluation/get_distance_function.py +++ b/pyrecest/evaluation/get_distance_function.py @@ -1,6 +1,6 @@ from pyrecest.backend import dot from pyrecest.backend import arccos -import numpy as np + from numpy.linalg import norm from pyrecest.distributions import AbstractHypertoroidalDistribution diff --git a/pyrecest/evaluation/iterate_configs_and_runs.py b/pyrecest/evaluation/iterate_configs_and_runs.py index efdf00ae..94aa0ad1 100644 --- a/pyrecest/evaluation/iterate_configs_and_runs.py +++ b/pyrecest/evaluation/iterate_configs_and_runs.py @@ -3,7 +3,7 @@ import warnings from typing import Any, Dict -import numpy as np + from .perform_predict_update_cycles import perform_predict_update_cycles diff --git a/pyrecest/evaluation/perform_predict_update_cycles.py b/pyrecest/evaluation/perform_predict_update_cycles.py index 161d66d9..fe667ffe 100644 --- a/pyrecest/evaluation/perform_predict_update_cycles.py +++ b/pyrecest/evaluation/perform_predict_update_cycles.py @@ -4,7 +4,7 @@ import time import warnings -import numpy as np + from .configure_for_filter import configure_for_filter diff --git a/pyrecest/evaluation/plot_results.py b/pyrecest/evaluation/plot_results.py index 7a986502..8ef3301c 100644 --- a/pyrecest/evaluation/plot_results.py +++ b/pyrecest/evaluation/plot_results.py @@ -6,7 +6,7 @@ import warnings import matplotlib.pyplot as plt -import numpy as np + from beartype import beartype from .get_axis_label import get_axis_label diff --git a/pyrecest/evaluation/simulation_database.py b/pyrecest/evaluation/simulation_database.py index dffddc2c..cad29c8b 100644 --- a/pyrecest/evaluation/simulation_database.py +++ b/pyrecest/evaluation/simulation_database.py @@ -2,7 +2,7 @@ import warnings from typing import Optional -import numpy as np + from beartype import beartype from pyrecest.distributions import GaussianDistribution diff --git a/pyrecest/evaluation/summarize_filter_results.py b/pyrecest/evaluation/summarize_filter_results.py index 8ee28ae9..5b400ec1 100644 --- a/pyrecest/evaluation/summarize_filter_results.py +++ b/pyrecest/evaluation/summarize_filter_results.py @@ -3,7 +3,7 @@ from pyrecest.backend import mean import warnings -import numpy as np + from .determine_all_deviations import determine_all_deviations from .get_distance_function import get_distance_function diff --git a/pyrecest/filters/abstract_hypertoroidal_filter.py b/pyrecest/filters/abstract_hypertoroidal_filter.py index 7911fee0..f0815bc7 100644 --- a/pyrecest/filters/abstract_hypertoroidal_filter.py +++ b/pyrecest/filters/abstract_hypertoroidal_filter.py @@ -1,6 +1,6 @@ import copy -import numpy as np + from .abstract_manifold_specific_filter import AbstractManifoldSpecificFilter @@ -16,7 +16,7 @@ class AbstractHypertoroidalFilter(AbstractManifoldSpecificFilter): def __init__(self, filter_state=None): self._filter_state = copy.deepcopy(filter_state) - def get_point_estimate(self) -> np.ndarray: + def get_point_estimate(self): """ Get the point estimate. diff --git a/pyrecest/filters/abstract_nearest_neighbor_tracker.py b/pyrecest/filters/abstract_nearest_neighbor_tracker.py index c4fc23f4..39b1cd61 100644 --- a/pyrecest/filters/abstract_nearest_neighbor_tracker.py +++ b/pyrecest/filters/abstract_nearest_neighbor_tracker.py @@ -4,7 +4,7 @@ import warnings from abc import abstractmethod -import numpy as np + from pyrecest.distributions import GaussianDistribution from .abstract_euclidean_filter import AbstractEuclideanFilter diff --git a/pyrecest/filters/abstract_particle_filter.py b/pyrecest/filters/abstract_particle_filter.py index 1988a7e5..02f34475 100644 --- a/pyrecest/filters/abstract_particle_filter.py +++ b/pyrecest/filters/abstract_particle_filter.py @@ -6,7 +6,7 @@ from collections.abc import Callable from pyrecest.backend import zeros -import numpy as np + from beartype import beartype from pyrecest.distributions.abstract_manifold_specific_distribution import ( AbstractManifoldSpecificDistribution, diff --git a/pyrecest/filters/abstract_tracker_with_logging.py b/pyrecest/filters/abstract_tracker_with_logging.py index 27044e57..f8ed3c8d 100644 --- a/pyrecest/filters/abstract_tracker_with_logging.py +++ b/pyrecest/filters/abstract_tracker_with_logging.py @@ -2,7 +2,7 @@ from pyrecest.backend import array from abc import ABC -import numpy as np + class AbstractTrackerWithLogging(ABC): diff --git a/pyrecest/filters/circular_particle_filter.py b/pyrecest/filters/circular_particle_filter.py index addb7a03..eac07c2e 100644 --- a/pyrecest/filters/circular_particle_filter.py +++ b/pyrecest/filters/circular_particle_filter.py @@ -3,7 +3,7 @@ from pyrecest.backend import float64 from pyrecest.backend import int64 from pyrecest.backend import int32 -import numpy as np + from .hypertoroidal_particle_filter import HypertoroidalParticleFilter diff --git a/pyrecest/filters/euclidean_particle_filter.py b/pyrecest/filters/euclidean_particle_filter.py index dda22c6f..8cf955e8 100644 --- a/pyrecest/filters/euclidean_particle_filter.py +++ b/pyrecest/filters/euclidean_particle_filter.py @@ -5,7 +5,7 @@ import copy from collections.abc import Callable -import numpy as np + from beartype import beartype from ..distributions.nonperiodic.abstract_linear_distribution import ( diff --git a/pyrecest/filters/global_nearest_neighbor.py b/pyrecest/filters/global_nearest_neighbor.py index 5c44832e..0e84c805 100644 --- a/pyrecest/filters/global_nearest_neighbor.py +++ b/pyrecest/filters/global_nearest_neighbor.py @@ -4,7 +4,7 @@ from pyrecest.backend import any from pyrecest.backend import all from pyrecest.backend import empty -import numpy as np + from scipy.optimize import linear_sum_assignment from scipy.spatial.distance import cdist from scipy.stats import chi2 diff --git a/pyrecest/filters/hypertoroidal_particle_filter.py b/pyrecest/filters/hypertoroidal_particle_filter.py index b0b289fd..6602db8c 100644 --- a/pyrecest/filters/hypertoroidal_particle_filter.py +++ b/pyrecest/filters/hypertoroidal_particle_filter.py @@ -14,7 +14,7 @@ import copy from collections.abc import Callable -import numpy as np + from beartype import beartype from pyrecest.distributions import ( AbstractHypertoroidalDistribution, @@ -76,7 +76,7 @@ def predict_nonlinear( self.filter_state.d = mod(self.filter_state.d, 2.0 * pi) def predict_nonlinear_nonadditive( - self, f: Callable, samples: np.ndarray, weights: np.ndarray + self, f: Callable, samples, weights: ): assert ( samples.shape[0] == weights.size diff --git a/pyrecest/filters/kalman_filter.py b/pyrecest/filters/kalman_filter.py index c49e0db9..abed790d 100644 --- a/pyrecest/filters/kalman_filter.py +++ b/pyrecest/filters/kalman_filter.py @@ -1,5 +1,5 @@ from pyrecest.backend import eye -import numpy as np + from beartype import beartype from filterpy.kalman import KalmanFilter as FilterPyKalmanFilter from pyrecest.distributions import GaussianDistribution @@ -9,7 +9,7 @@ class KalmanFilter(AbstractEuclideanFilter): def __init__( - self, initial_state: GaussianDistribution | tuple[np.ndarray, np.ndarray] + self, initial_state: GaussianDistribution | tuple[, ] ): """ Initialize the Kalman filter with the initial state. @@ -36,7 +36,7 @@ def filter_state( @filter_state.setter def filter_state( - self, new_state: GaussianDistribution | tuple[np.ndarray, np.ndarray] + self, new_state: GaussianDistribution | tuple[, ] ): """ Set the filter state. @@ -54,7 +54,7 @@ def filter_state( "new_state must be a GaussianDistribution or a tuple of (mean, covariance)" ) - def predict_identity(self, sys_noise_cov: np.ndarray, sys_input: np.ndarray = None): + def predict_identity(self, sys_noise_cov, sys_input: = None): """ Predicts the next state assuming identity transition matrix. @@ -67,9 +67,9 @@ def predict_identity(self, sys_noise_cov: np.ndarray, sys_input: np.ndarray = No def predict_linear( self, - system_matrix: np.ndarray, - sys_noise_cov: np.ndarray, - sys_input: np.ndarray | None = None, + system_matrix: , + sys_noise_cov: , + sys_input: | None = None, ): """ Predicts the next state assuming a linear system model. @@ -86,7 +86,7 @@ def predict_linear( B = eye(system_matrix.shape[0]) if sys_input is not None else None self._filter_state.predict(F=system_matrix, Q=sys_noise_cov, B=B, u=sys_input) - def update_identity(self, meas_noise: np.ndarray, measurement: np.ndarray): + def update_identity(self, meas_noise, measurement): """ Update the filter state with measurement, assuming identity measurement matrix. @@ -101,9 +101,9 @@ def update_identity(self, meas_noise: np.ndarray, measurement: np.ndarray): def update_linear( self, - measurement: np.ndarray, - measurement_matrix: np.ndarray, - meas_noise: np.ndarray, + measurement: , + measurement_matrix: , + meas_noise: , ): """ Update the filter state with measurement, assuming a linear measurement model. @@ -115,6 +115,6 @@ def update_linear( self._filter_state.dim_z = measurement_matrix.shape[0] self._filter_state.update(z=measurement, R=meas_noise, H=measurement_matrix) - def get_point_estimate(self) -> np.ndarray: + def get_point_estimate(self): """Returns the mean of the current filter state.""" return self._filter_state.x \ No newline at end of file diff --git a/pyrecest/filters/random_matrix_tracker.py b/pyrecest/filters/random_matrix_tracker.py index 36f80280..da34432d 100644 --- a/pyrecest/filters/random_matrix_tracker.py +++ b/pyrecest/filters/random_matrix_tracker.py @@ -3,7 +3,7 @@ from pyrecest.backend import eye from pyrecest.backend import exp from pyrecest.backend import concatenate -import numpy as np + from pyrecest.utils.plotting import plot_ellipsoid from .abstract_extended_object_tracker import AbstractExtendedObjectTracker diff --git a/pyrecest/filters/toroidal_particle_filter.py b/pyrecest/filters/toroidal_particle_filter.py index dd0cdf72..8e96646d 100644 --- a/pyrecest/filters/toroidal_particle_filter.py +++ b/pyrecest/filters/toroidal_particle_filter.py @@ -1,7 +1,7 @@ from typing import Union from pyrecest.backend import int64 from pyrecest.backend import int32 -import numpy as np + from beartype import beartype from .hypertoroidal_particle_filter import HypertoroidalParticleFilter diff --git a/pyrecest/filters/toroidal_wrapped_normal_filter.py b/pyrecest/filters/toroidal_wrapped_normal_filter.py index 29f34815..f58b40b3 100644 --- a/pyrecest/filters/toroidal_wrapped_normal_filter.py +++ b/pyrecest/filters/toroidal_wrapped_normal_filter.py @@ -1,6 +1,6 @@ from pyrecest.backend import eye from pyrecest.backend import array -import numpy as np + from pyrecest.distributions.hypertorus.toroidal_wrapped_normal_distribution import ( ToroidalWrappedNormalDistribution, ) diff --git a/pyrecest/filters/von_mises_filter.py b/pyrecest/filters/von_mises_filter.py index 5c142f59..9ba0bdae 100644 --- a/pyrecest/filters/von_mises_filter.py +++ b/pyrecest/filters/von_mises_filter.py @@ -3,7 +3,7 @@ import copy import warnings -import numpy as np + from beartype import beartype from pyrecest.distributions import VonMisesDistribution diff --git a/pyrecest/filters/von_mises_fisher_filter.py b/pyrecest/filters/von_mises_fisher_filter.py index fa0570db..c8f3df5f 100644 --- a/pyrecest/filters/von_mises_fisher_filter.py +++ b/pyrecest/filters/von_mises_fisher_filter.py @@ -1,6 +1,6 @@ from pyrecest.backend import ndim from pyrecest.backend import array -import numpy as np + from pyrecest.distributions import VonMisesFisherDistribution from .abstract_hyperspherical_filter import AbstractHypersphericalFilter diff --git a/pyrecest/filters/wrapped_normal_filter.py b/pyrecest/filters/wrapped_normal_filter.py index f10f1843..f36bece3 100644 --- a/pyrecest/filters/wrapped_normal_filter.py +++ b/pyrecest/filters/wrapped_normal_filter.py @@ -5,7 +5,7 @@ from collections.abc import Callable from functools import partial -import numpy as np + from pyrecest.distributions import CircularDiracDistribution, WrappedNormalDistribution from pyrecest.filters.abstract_circular_filter import AbstractCircularFilter @@ -46,16 +46,16 @@ def update_nonlinear_progressive( while lambda_ > 0: wd = self.filter_state.to_dirac5() likelihood_vals = array([likelihood(z, x) for x in wd.d]) - likelihood_vals_min: np.number = np.min(likelihood_vals) - likelihood_vals_max: np.number = np.max(likelihood_vals) + likelihood_vals_min: Any = np.min(likelihood_vals) + likelihood_vals_max: Any = np.max(likelihood_vals) if likelihood_vals_max == 0: raise ValueError( "Progressive update failed because likelihood is 0 everywhere" ) - w_min: np.number = np.min(wd.w) - w_max: np.number = np.max(wd.w) + w_min: Any = np.min(wd.w) + w_max: Any = np.max(wd.w) if likelihood_vals_min == 0 or w_min == 0: raise ZeroDivisionError("Cannot perform division by zero") diff --git a/pyrecest/sampling/abstract_sampler.py b/pyrecest/sampling/abstract_sampler.py index b55366da..ee00a570 100644 --- a/pyrecest/sampling/abstract_sampler.py +++ b/pyrecest/sampling/abstract_sampler.py @@ -1,9 +1,9 @@ from abc import ABC, abstractmethod -import numpy as np + class AbstractSampler(ABC): @abstractmethod - def sample_stochastic(self, n_samples: int, dim: int) -> np.ndarray: + def sample_stochastic(self, n_samples: int, dim: int): raise NotImplementedError("Abstract method not implemented!") \ No newline at end of file diff --git a/pyrecest/sampling/euclidean_sampler.py b/pyrecest/sampling/euclidean_sampler.py index 97ec56b2..77138d31 100644 --- a/pyrecest/sampling/euclidean_sampler.py +++ b/pyrecest/sampling/euclidean_sampler.py @@ -1,6 +1,6 @@ from pyrecest.backend import eye from pyrecest.backend import zeros -import numpy as np + from pyrecest.distributions import GaussianDistribution from .abstract_sampler import AbstractSampler @@ -11,5 +11,5 @@ class AbstractEuclideanSampler(AbstractSampler): class GaussianSampler(AbstractEuclideanSampler): - def sample_stochastic(self, n_samples: int, dim: int) -> np.ndarray: + def sample_stochastic(self, n_samples: int, dim: int): return GaussianDistribution(zeros(dim), eye(dim)).sample(n_samples) \ No newline at end of file diff --git a/pyrecest/sampling/hyperspherical_sampler.py b/pyrecest/sampling/hyperspherical_sampler.py index fe30e8e8..7f379cf0 100644 --- a/pyrecest/sampling/hyperspherical_sampler.py +++ b/pyrecest/sampling/hyperspherical_sampler.py @@ -8,10 +8,11 @@ from pyrecest.backend import arccos from pyrecest.backend import arange from pyrecest.backend import empty +from pyrecest.backend import column_stack import itertools from abc import abstractmethod -import numpy as np + from beartype import beartype from pyrecest.distributions import ( AbstractSphericalDistribution, @@ -49,7 +50,7 @@ def get_grid_hypersphere(method: str, grid_density_parameter: int): class AbstractHypersphericalUniformSampler(AbstractSampler): - def sample_stochastic(self, n_samples: int, dim: int) -> np.ndarray: + def sample_stochastic(self, n_samples: int, dim: int): return HypersphericalUniformDistribution(dim).sample(n_samples) @abstractmethod @@ -69,27 +70,27 @@ class AbstractSphericalCoordinatesBasedSampler(AbstractSphericalUniformSampler): @abstractmethod def get_grid_spherical_coordinates( self, grid_density_parameter: int - ) -> tuple[np.ndarray, np.ndarray, dict]: + ): raise NotImplementedError() - def get_grid(self, grid_density_parameter: int) -> tuple[np.ndarray, dict]: + def get_grid(self, grid_density_parameter: int): phi, theta, grid_specific_description = self.get_grid_spherical_coordinates( grid_density_parameter ) x, y, z = AbstractSphericalDistribution.sph_to_cart(phi, theta) - grid = np.column_stack((x, y, z)) + grid = column_stack((x, y, z)) return grid, grid_specific_description class HealpixSampler(AbstractHypersphericalUniformSampler): - def get_grid(self, grid_density_parameter: int) -> tuple[np.ndarray, dict]: + def get_grid(self, grid_density_parameter: int): import healpy as hp n_side = grid_density_parameter n_areas = hp.nside2npix(n_side) x, y, z = hp.pix2vec(n_side, arange(n_areas)) - grid = np.column_stack((x, y, z)) + grid = column_stack((x, y, z)) grid_specific_description = { "scheme": "healpix", @@ -102,7 +103,7 @@ def get_grid(self, grid_density_parameter: int) -> tuple[np.ndarray, dict]: class DriscollHealySampler(AbstractSphericalCoordinatesBasedSampler): def get_grid_spherical_coordinates( self, grid_density_parameter: int - ) -> tuple[np.ndarray, np.ndarray, dict]: + ): import pyshtools as pysh grid = pysh.SHGrid.from_zeros(grid_density_parameter) @@ -132,7 +133,7 @@ def get_grid_spherical_coordinates( class SphericalFibonacciSampler(AbstractSphericalCoordinatesBasedSampler): def get_grid_spherical_coordinates( self, grid_density_parameter: int - ) -> tuple[np.ndarray, np.ndarray, dict]: + ): indices = arange(0, grid_density_parameter, dtype=float) + 0.5 phi = pi * (1 + 5**0.5) * indices theta = arccos(1 - 2 * indices / grid_density_parameter) @@ -145,9 +146,7 @@ def get_grid_spherical_coordinates( class AbstractHopfBasedS3Sampler(AbstractHypersphericalUniformSampler): @staticmethod - def hopf_coordinates_to_quaterion_yershova( - θ: np.ndarray, ϕ: np.ndarray, ψ: np.ndarray - ): + def hopf_coordinates_to_quaterion_yershova(θ, ϕ, ψ): """ One possible way to index the S3-sphere via the hopf fibration. Using the convention from @@ -165,7 +164,7 @@ def hopf_coordinates_to_quaterion_yershova( return quaterions @staticmethod - def quaternion_to_hopf_yershova(q: np.ndarray): + def quaternion_to_hopf_yershova(q): θ = 2 * arccos(sqrt(q[:, 0] ** 2 + q[:, 1] ** 2)) ϕ = arctan2(q[:, 3], q[:, 2]) - arctan2(q[:, 1], q[:, 0]) ψ = 2 * arctan2(q[:, 1], q[:, 0]) @@ -187,7 +186,7 @@ def get_grid(self, grid_density_parameter: int | list[int]): s3_points_list = [] for i in range(grid_density_parameter[0] + 1): - if np.size(grid_density_parameter) == 2: + if grid_density_parameter.shape[0] == 2: n_sample_circle = grid_density_parameter[1] else: n_sample_circle = 2**i * 6 diff --git a/pyrecest/sampling/hypertoroidal_sampler.py b/pyrecest/sampling/hypertoroidal_sampler.py index a32e04e7..fac6ba77 100644 --- a/pyrecest/sampling/hypertoroidal_sampler.py +++ b/pyrecest/sampling/hypertoroidal_sampler.py @@ -1,6 +1,6 @@ from math import pi from pyrecest.backend import linspace -import numpy as np + from beartype import beartype from pyrecest.distributions import CircularUniformDistribution @@ -19,7 +19,7 @@ class CircularUniformSampler(AbstractCircularSampler): def sample_stochastic(self, n_samples: int): return CircularUniformDistribution().sample(n_samples) - def get_grid(self, grid_density_parameter: int) -> np.ndarray: + def get_grid(self, grid_density_parameter: int): """ Returns an equidistant grid of points on the circle [0,2*pi). """ diff --git a/pyrecest/tests/distributions/test_abstract_circular_distribution.py b/pyrecest/tests/distributions/test_abstract_circular_distribution.py index c8286142..a29fd46e 100644 --- a/pyrecest/tests/distributions/test_abstract_circular_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_circular_distribution.py @@ -6,7 +6,7 @@ import pyrecest.backend import unittest -import numpy as np + from pyrecest.distributions import VonMisesDistribution, WrappedNormalDistribution diff --git a/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py b/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py index 8012bfb2..1cd6b62d 100644 --- a/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py @@ -8,7 +8,7 @@ import unittest import pyrecest.backend -import numpy as np + from pyrecest.distributions.cart_prod.partially_wrapped_normal_distribution import ( PartiallyWrappedNormalDistribution, ) diff --git a/pyrecest/tests/distributions/test_abstract_hyperhemispherical_distribution.py b/pyrecest/tests/distributions/test_abstract_hyperhemispherical_distribution.py index 43039647..47ff7fef 100644 --- a/pyrecest/tests/distributions/test_abstract_hyperhemispherical_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hyperhemispherical_distribution.py @@ -5,7 +5,7 @@ from pyrecest.backend import array import unittest -import numpy as np + from pyrecest.distributions import ( HyperhemisphericalWatsonDistribution, VonMisesFisherDistribution, diff --git a/pyrecest/tests/distributions/test_abstract_hypersphere_subset_distribution.py b/pyrecest/tests/distributions/test_abstract_hypersphere_subset_distribution.py index 63deb3b6..b75ae991 100644 --- a/pyrecest/tests/distributions/test_abstract_hypersphere_subset_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hypersphere_subset_distribution.py @@ -4,7 +4,7 @@ from pyrecest.backend import array import unittest -import numpy as np + from pyrecest.distributions import VonMisesFisherDistribution diff --git a/pyrecest/tests/distributions/test_abstract_hyperspherical_distribution.py b/pyrecest/tests/distributions/test_abstract_hyperspherical_distribution.py index f8318567..6245c68d 100644 --- a/pyrecest/tests/distributions/test_abstract_hyperspherical_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hyperspherical_distribution.py @@ -5,7 +5,7 @@ import unittest import matplotlib -import numpy as np + from pyrecest.distributions import ( AbstractHypersphericalDistribution, VonMisesFisherDistribution, diff --git a/pyrecest/tests/distributions/test_abstract_hypertoroidal_distribution.py b/pyrecest/tests/distributions/test_abstract_hypertoroidal_distribution.py index 84faaac3..b7069ffd 100644 --- a/pyrecest/tests/distributions/test_abstract_hypertoroidal_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hypertoroidal_distribution.py @@ -1,7 +1,7 @@ from math import pi import unittest from pyrecest.backend import array -import numpy as np + from pyrecest.distributions import AbstractHypertoroidalDistribution diff --git a/pyrecest/tests/distributions/test_abstract_linear_distribution.py b/pyrecest/tests/distributions/test_abstract_linear_distribution.py index e171e0a7..796c0658 100644 --- a/pyrecest/tests/distributions/test_abstract_linear_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_linear_distribution.py @@ -6,7 +6,7 @@ import unittest import matplotlib -import numpy as np + from pyrecest.distributions import ( AbstractLinearDistribution, CustomLinearDistribution, @@ -39,8 +39,8 @@ def f(x): return 0.3 * dist.pdf(x) dim = 2 - left = [-np.inf, -np.inf] - right = [np.inf, np.inf] + left = [-float('inf'), -float('inf')] + right = [float('inf'), float('inf')] integration_result = AbstractLinearDistribution.integrate_fun_over_domain( f, dim, left, right diff --git a/pyrecest/tests/distributions/test_abstract_mixture.py b/pyrecest/tests/distributions/test_abstract_mixture.py index 04e88187..5fcebf27 100644 --- a/pyrecest/tests/distributions/test_abstract_mixture.py +++ b/pyrecest/tests/distributions/test_abstract_mixture.py @@ -7,7 +7,7 @@ import pyrecest.backend import unittest -import numpy as np + from pyrecest.distributions import VonMisesFisherDistribution from pyrecest.distributions.hypersphere_subset.custom_hyperhemispherical_distribution import ( CustomHyperhemisphericalDistribution, diff --git a/pyrecest/tests/distributions/test_bingham_distribution.py b/pyrecest/tests/distributions/test_bingham_distribution.py index 9819035c..69299bde 100644 --- a/pyrecest/tests/distributions/test_bingham_distribution.py +++ b/pyrecest/tests/distributions/test_bingham_distribution.py @@ -1,7 +1,7 @@ from pyrecest.backend import array import unittest -import numpy as np + from pyrecest.distributions import BinghamDistribution from .test_von_mises_fisher_distribution import vectors_to_test_2d diff --git a/pyrecest/tests/distributions/test_circular_fourier_distribution.py b/pyrecest/tests/distributions/test_circular_fourier_distribution.py index eeeb693d..512b07c6 100644 --- a/pyrecest/tests/distributions/test_circular_fourier_distribution.py +++ b/pyrecest/tests/distributions/test_circular_fourier_distribution.py @@ -6,10 +6,11 @@ from pyrecest.backend import arange from pyrecest.backend import allclose from pyrecest.backend import all +import pyrecest.backend import copy import unittest -import numpy as np + from parameterized import parameterized from pyrecest.distributions import ( CircularFourierDistribution, @@ -25,27 +26,24 @@ class TestCircularFourierDistribution(unittest.TestCase): ( "identity", VonMisesDistribution, - 0.4, + array(0.4), arange(0.1, 2.1, 0.1), 101, - 1e-8, ), ("sqrt", VonMisesDistribution, 0.5, arange(0.1, 2.1, 0.1), 101, 1e-8), ( "identity", WrappedNormalDistribution, - 0.8, + array(0.8), arange(0.2, 2.1, 0.1), 101, - 1e-8, ), ( "sqrt", WrappedNormalDistribution, - 0.8, + array(0.8), arange(0.2, 2.1, 0.1), 101, - 1e-8, ), ] ) @@ -58,17 +56,17 @@ def test_fourier_conversion( """ for param in param_range: dist = dist_class(mu, param) - xvals = arange(-2 * pi, 3 * pi, 0.01) + xvals = arange(-2.0 * pi, 3.0 * pi, 0.01) fd = CircularFourierDistribution.from_distribution( dist, coeffs, transformation ) self.assertEqual( fd.c.shape[0], - ceil(coeffs / 2), + ceil(coeffs / 2.0), "Length of Fourier Coefficients mismatch.", ) self.assertTrue( - allclose(fd.pdf(xvals), dist.pdf(xvals), atol=tolerance), + allclose(fd.pdf(xvals), dist.pdf(xvals)), "PDF values do not match.", ) @@ -101,8 +99,9 @@ def test_vm_to_fourier(self, mult_by_n, transformation): (False, "sqrt"), ] ) + @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") def test_integrate_numerically(self, mult_by_n, transformation): - scale_by = 2 / 5 + scale_by = 2.0 / 5.0 dist = VonMisesDistribution(2.9, 1.3) fd = CircularFourierDistribution.from_distribution( dist, @@ -148,11 +147,11 @@ def test_integrate(self, mult_by_n, transformation): fd_real = fd.to_real_fd() np.testing.assert_array_almost_equal(fd_real.integrate(), 1) fd_unnorm = copy.copy(fd) - fd_unnorm.c = fd.c * (scale_by) + fd_unnorm.c = fd.c * scale_by if transformation == "identity": expected_val = scale_by else: - expected_val = (scale_by) ** 2 + expected_val = scale_by ** 2 np.testing.assert_array_almost_equal(fd_unnorm.integrate(), expected_val) fd_unnorm_real = fd_unnorm.to_real_fd() np.testing.assert_array_almost_equal(fd_unnorm_real.integrate(), expected_val) diff --git a/pyrecest/tests/distributions/test_circular_uniform_distribution.py b/pyrecest/tests/distributions/test_circular_uniform_distribution.py index 673ced65..f482f2e9 100644 --- a/pyrecest/tests/distributions/test_circular_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_circular_uniform_distribution.py @@ -3,7 +3,7 @@ from pyrecest.backend import array import unittest -import numpy as np + from pyrecest.distributions.circle.circular_uniform_distribution import ( CircularUniformDistribution, ) diff --git a/pyrecest/tests/distributions/test_custom_hemispherical_distribution.py b/pyrecest/tests/distributions/test_custom_hemispherical_distribution.py index 265fab90..a6983e9d 100644 --- a/pyrecest/tests/distributions/test_custom_hemispherical_distribution.py +++ b/pyrecest/tests/distributions/test_custom_hemispherical_distribution.py @@ -8,7 +8,7 @@ import unittest import warnings -import numpy as np + from pyrecest.distributions import ( BinghamDistribution, CustomHemisphericalDistribution, diff --git a/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py b/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py index e0007db9..67e6161d 100644 --- a/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py +++ b/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py @@ -6,7 +6,7 @@ import pyrecest.backend import unittest -import numpy as np + from pyrecest.distributions import ( GaussianDistribution, PartiallyWrappedNormalDistribution, diff --git a/pyrecest/tests/distributions/test_custom_hyperrectangular_distribution.py b/pyrecest/tests/distributions/test_custom_hyperrectangular_distribution.py index acdc953e..3735d1d4 100644 --- a/pyrecest/tests/distributions/test_custom_hyperrectangular_distribution.py +++ b/pyrecest/tests/distributions/test_custom_hyperrectangular_distribution.py @@ -6,7 +6,7 @@ from pyrecest.backend import all import unittest -import numpy as np + from pyrecest.distributions.custom_hyperrectangular_distribution import ( CustomHyperrectangularDistribution, ) diff --git a/pyrecest/tests/distributions/test_custom_hyperspherical_distribution.py b/pyrecest/tests/distributions/test_custom_hyperspherical_distribution.py index 088fd088..3e4cef3d 100644 --- a/pyrecest/tests/distributions/test_custom_hyperspherical_distribution.py +++ b/pyrecest/tests/distributions/test_custom_hyperspherical_distribution.py @@ -5,7 +5,7 @@ from pyrecest.backend import all import unittest -import numpy as np + from pyrecest.distributions import VonMisesFisherDistribution from pyrecest.distributions.hypersphere_subset.custom_hyperspherical_distribution import ( CustomHypersphericalDistribution, diff --git a/pyrecest/tests/distributions/test_custom_linear_distribution.py b/pyrecest/tests/distributions/test_custom_linear_distribution.py index b53119de..869c8d1a 100644 --- a/pyrecest/tests/distributions/test_custom_linear_distribution.py +++ b/pyrecest/tests/distributions/test_custom_linear_distribution.py @@ -6,7 +6,7 @@ from pyrecest.backend import concatenate import unittest -import numpy as np + from pyrecest.distributions import CustomLinearDistribution, GaussianDistribution from pyrecest.distributions.nonperiodic.gaussian_mixture import GaussianMixture diff --git a/pyrecest/tests/distributions/test_disk_uniform_distribution.py b/pyrecest/tests/distributions/test_disk_uniform_distribution.py index 99ec71b8..71697e7d 100644 --- a/pyrecest/tests/distributions/test_disk_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_disk_uniform_distribution.py @@ -7,7 +7,7 @@ """ Test cases for DiskUniformDistribution""" import unittest -import numpy as np + from pyrecest.distributions import DiskUniformDistribution diff --git a/pyrecest/tests/distributions/test_ellipsoidal_ball_uniform_distribution.py b/pyrecest/tests/distributions/test_ellipsoidal_ball_uniform_distribution.py index 2b549cde..a960d44d 100644 --- a/pyrecest/tests/distributions/test_ellipsoidal_ball_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_ellipsoidal_ball_uniform_distribution.py @@ -2,7 +2,7 @@ from pyrecest.backend import array import unittest -import numpy as np + from pyrecest.distributions import EllipsoidalBallUniformDistribution diff --git a/pyrecest/tests/distributions/test_gaussian_distribution.py b/pyrecest/tests/distributions/test_gaussian_distribution.py index ac2d24bc..d6363df3 100644 --- a/pyrecest/tests/distributions/test_gaussian_distribution.py +++ b/pyrecest/tests/distributions/test_gaussian_distribution.py @@ -4,7 +4,7 @@ from pyrecest.backend import all import unittest -import numpy as np + import scipy from pyrecest.distributions import GaussianDistribution from scipy.stats import multivariate_normal @@ -69,7 +69,7 @@ def integrand(y, x): result = [] for x_curr in xs: integral_value, _ = scipy.integrate.quad( - integrand, -np.inf, np.inf, args=x_curr + integrand, -float('inf'), float('inf'), args=x_curr ) result.append(integral_value) return array(result) diff --git a/pyrecest/tests/distributions/test_hemispherical_uniform_distribution.py b/pyrecest/tests/distributions/test_hemispherical_uniform_distribution.py index 55b7d1f9..5e302ab2 100644 --- a/pyrecest/tests/distributions/test_hemispherical_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_hemispherical_uniform_distribution.py @@ -4,7 +4,7 @@ from pyrecest.backend import all import unittest -import numpy as np + from pyrecest.distributions.hypersphere_subset.hemispherical_uniform_distribution import ( HemisphericalUniformDistribution, ) diff --git a/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py b/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py index 453122c4..52862e1a 100644 --- a/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py @@ -11,7 +11,7 @@ from pyrecest.backend import zeros import unittest -import numpy as np + from pyrecest.distributions.cart_prod.hypercylindrical_dirac_distribution import ( HypercylindricalDiracDistribution, ) diff --git a/pyrecest/tests/distributions/test_hyperhemispherical_uniform_distribution.py b/pyrecest/tests/distributions/test_hyperhemispherical_uniform_distribution.py index fdef9ee0..bd1f571e 100644 --- a/pyrecest/tests/distributions/test_hyperhemispherical_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_hyperhemispherical_uniform_distribution.py @@ -8,7 +8,7 @@ """ Test for uniform distribution for hyperhemispheres """ import unittest -import numpy as np + from pyrecest.distributions import HyperhemisphericalUniformDistribution diff --git a/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py b/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py index e28e0f57..02543887 100644 --- a/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py @@ -9,7 +9,7 @@ import pyrecest.backend import unittest -import numpy as np + from pyrecest.distributions import VonMisesFisherDistribution from pyrecest.distributions.hypersphere_subset.hyperspherical_dirac_distribution import ( HypersphericalDiracDistribution, diff --git a/pyrecest/tests/distributions/test_hyperspherical_mixture.py b/pyrecest/tests/distributions/test_hyperspherical_mixture.py index 23a97720..1a1e6538 100644 --- a/pyrecest/tests/distributions/test_hyperspherical_mixture.py +++ b/pyrecest/tests/distributions/test_hyperspherical_mixture.py @@ -7,7 +7,7 @@ from pyrecest.backend import array import unittest -import numpy as np + from numpy.testing import assert_allclose from pyrecest.distributions import ( AbstractHypersphereSubsetDistribution, diff --git a/pyrecest/tests/distributions/test_hyperspherical_uniform_distribution.py b/pyrecest/tests/distributions/test_hyperspherical_uniform_distribution.py index f3415429..65d6b560 100644 --- a/pyrecest/tests/distributions/test_hyperspherical_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_hyperspherical_uniform_distribution.py @@ -6,7 +6,7 @@ """ Test for uniform distribution on the hypersphere """ import unittest -import numpy as np + from pyrecest.distributions import ( AbstractHypersphericalDistribution, HypersphericalUniformDistribution, diff --git a/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py b/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py index 48c2c1c5..848a5b81 100644 --- a/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py @@ -11,7 +11,7 @@ import copy import unittest -import numpy as np + from pyrecest.distributions import ( HypertoroidalDiracDistribution, ToroidalDiracDistribution, diff --git a/pyrecest/tests/distributions/test_hypertoroidal_wrapped_normal_distribution.py b/pyrecest/tests/distributions/test_hypertoroidal_wrapped_normal_distribution.py index 734885a0..96dfe2a0 100644 --- a/pyrecest/tests/distributions/test_hypertoroidal_wrapped_normal_distribution.py +++ b/pyrecest/tests/distributions/test_hypertoroidal_wrapped_normal_distribution.py @@ -1,7 +1,7 @@ from pyrecest.backend import array import unittest -import numpy as np + from pyrecest.distributions import HypertoroidalWNDistribution diff --git a/pyrecest/tests/distributions/test_linear_dirac_distribution.py b/pyrecest/tests/distributions/test_linear_dirac_distribution.py index 27e06278..506ca3c6 100644 --- a/pyrecest/tests/distributions/test_linear_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_linear_dirac_distribution.py @@ -5,7 +5,7 @@ from pyrecest.backend import all import unittest -import numpy as np + from pyrecest.distributions import GaussianDistribution from pyrecest.distributions.nonperiodic.linear_dirac_distribution import ( LinearDiracDistribution, diff --git a/pyrecest/tests/distributions/test_linear_mixture.py b/pyrecest/tests/distributions/test_linear_mixture.py index 7b441d78..41118ffe 100644 --- a/pyrecest/tests/distributions/test_linear_mixture.py +++ b/pyrecest/tests/distributions/test_linear_mixture.py @@ -5,7 +5,7 @@ import unittest from warnings import catch_warnings, simplefilter -import numpy as np + from pyrecest.distributions import GaussianDistribution from pyrecest.distributions.nonperiodic.linear_mixture import LinearMixture diff --git a/pyrecest/tests/distributions/test_partially_wrapped_normal_distribution.py b/pyrecest/tests/distributions/test_partially_wrapped_normal_distribution.py index 67936030..d271a08b 100644 --- a/pyrecest/tests/distributions/test_partially_wrapped_normal_distribution.py +++ b/pyrecest/tests/distributions/test_partially_wrapped_normal_distribution.py @@ -2,7 +2,7 @@ from pyrecest.backend import array import unittest -import numpy as np + import scipy.linalg from pyrecest.distributions.cart_prod.partially_wrapped_normal_distribution import ( PartiallyWrappedNormalDistribution, diff --git a/pyrecest/tests/distributions/test_se3_dirac_distribution.py b/pyrecest/tests/distributions/test_se3_dirac_distribution.py index ad395132..70975073 100644 --- a/pyrecest/tests/distributions/test_se3_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_se3_dirac_distribution.py @@ -6,7 +6,7 @@ from pyrecest.backend import array import unittest -import numpy as np + from pyrecest.distributions import ( GaussianDistribution, HyperhemisphericalUniformDistribution, diff --git a/pyrecest/tests/distributions/test_sphere_subset_distribution.py b/pyrecest/tests/distributions/test_sphere_subset_distribution.py index 44a0e8c6..631865e7 100644 --- a/pyrecest/tests/distributions/test_sphere_subset_distribution.py +++ b/pyrecest/tests/distributions/test_sphere_subset_distribution.py @@ -2,7 +2,7 @@ from pyrecest.backend import array import unittest -import numpy as np + from parameterized import parameterized from pyrecest.distributions.hypersphere_subset.abstract_sphere_subset_distribution import ( AbstractSphereSubsetDistribution, diff --git a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py index 9154d0db..7c9eed71 100644 --- a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py +++ b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py @@ -15,7 +15,7 @@ from pyrecest.backend import zeros import unittest -import numpy as np + from parameterized import parameterized from pyrecest.distributions import VonMisesFisherDistribution from pyrecest.distributions.hypersphere_subset.abstract_spherical_distribution import ( diff --git a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py index 4e1fb9ed..8de21916 100644 --- a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py +++ b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py @@ -10,7 +10,7 @@ import unittest import warnings -import numpy as np + from parameterized import parameterized from pyrecest.distributions.hypersphere_subset.abstract_spherical_distribution import ( AbstractSphericalDistribution, diff --git a/pyrecest/tests/distributions/test_toroidal_uniform_distribution.py b/pyrecest/tests/distributions/test_toroidal_uniform_distribution.py index 5dd369a7..f8b1aded 100644 --- a/pyrecest/tests/distributions/test_toroidal_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_toroidal_uniform_distribution.py @@ -7,7 +7,7 @@ from pyrecest.backend import zeros import unittest -import numpy as np + from pyrecest.distributions.hypertorus.toroidal_uniform_distribution import ( ToroidalUniformDistribution, ) diff --git a/pyrecest/tests/distributions/test_toroidal_von_mises_sine_distribution.py b/pyrecest/tests/distributions/test_toroidal_von_mises_sine_distribution.py index 85aabc20..2c357a63 100644 --- a/pyrecest/tests/distributions/test_toroidal_von_mises_sine_distribution.py +++ b/pyrecest/tests/distributions/test_toroidal_von_mises_sine_distribution.py @@ -6,7 +6,7 @@ from pyrecest.backend import arange import unittest -import numpy as np + from parameterized import parameterized from pyrecest.distributions.hypertorus.toroidal_von_mises_sine_distribution import ( ToroidalVonMisesSineDistribution, diff --git a/pyrecest/tests/distributions/test_toroidal_wrapped_normal_distribution.py b/pyrecest/tests/distributions/test_toroidal_wrapped_normal_distribution.py index 4cc20f14..f7b4f351 100644 --- a/pyrecest/tests/distributions/test_toroidal_wrapped_normal_distribution.py +++ b/pyrecest/tests/distributions/test_toroidal_wrapped_normal_distribution.py @@ -5,7 +5,7 @@ from pyrecest.backend import all import unittest -import numpy as np + from pyrecest.distributions.hypertorus.toroidal_wrapped_normal_distribution import ( ToroidalWrappedNormalDistribution, ) diff --git a/pyrecest/tests/distributions/test_von_mises_distribution.py b/pyrecest/tests/distributions/test_von_mises_distribution.py index 74694b00..e2d89b3a 100644 --- a/pyrecest/tests/distributions/test_von_mises_distribution.py +++ b/pyrecest/tests/distributions/test_von_mises_distribution.py @@ -4,7 +4,7 @@ import matplotlib import matplotlib.pyplot as plt -import numpy as np + from pyrecest.distributions import VonMisesDistribution matplotlib.use("Agg") diff --git a/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py b/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py index 1b6f9fb3..c2c60107 100644 --- a/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py +++ b/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py @@ -6,7 +6,7 @@ from pyrecest.backend import empty_like import unittest -import numpy as np + from parameterized import parameterized from pyrecest.distributions import VonMisesFisherDistribution from pyrecest.distributions.hypersphere_subset.hyperspherical_dirac_distribution import ( diff --git a/pyrecest/tests/distributions/test_watson_distribution.py b/pyrecest/tests/distributions/test_watson_distribution.py index 363b8b75..fdb9daa1 100644 --- a/pyrecest/tests/distributions/test_watson_distribution.py +++ b/pyrecest/tests/distributions/test_watson_distribution.py @@ -2,7 +2,7 @@ from pyrecest.backend import array import unittest -import numpy as np + from pyrecest.distributions import BinghamDistribution, WatsonDistribution diff --git a/pyrecest/tests/distributions/test_wrapped_cauchy_distribution.py b/pyrecest/tests/distributions/test_wrapped_cauchy_distribution.py index ef815ffa..b496b99e 100644 --- a/pyrecest/tests/distributions/test_wrapped_cauchy_distribution.py +++ b/pyrecest/tests/distributions/test_wrapped_cauchy_distribution.py @@ -3,7 +3,7 @@ from pyrecest.backend import arange import unittest -import numpy as np + from pyrecest.distributions.circle.custom_circular_distribution import ( CustomCircularDistribution, ) diff --git a/pyrecest/tests/distributions/test_wrapped_laplace_distribution.py b/pyrecest/tests/distributions/test_wrapped_laplace_distribution.py index 6ff82f28..eedb8b94 100644 --- a/pyrecest/tests/distributions/test_wrapped_laplace_distribution.py +++ b/pyrecest/tests/distributions/test_wrapped_laplace_distribution.py @@ -5,7 +5,7 @@ from pyrecest.backend import array import unittest -import numpy as np + from pyrecest.distributions.circle.wrapped_laplace_distribution import ( WrappedLaplaceDistribution, ) diff --git a/pyrecest/tests/distributions/test_wrapped_normal_distribution.py b/pyrecest/tests/distributions/test_wrapped_normal_distribution.py index 2613b250..a9d4d086 100644 --- a/pyrecest/tests/distributions/test_wrapped_normal_distribution.py +++ b/pyrecest/tests/distributions/test_wrapped_normal_distribution.py @@ -11,7 +11,7 @@ from pyrecest.backend import zeros import unittest -import numpy as np + from pyrecest.distributions import WrappedNormalDistribution diff --git a/pyrecest/tests/filters/test_circular_particle_filter.py b/pyrecest/tests/filters/test_circular_particle_filter.py index 334d93c1..e1161c11 100644 --- a/pyrecest/tests/filters/test_circular_particle_filter.py +++ b/pyrecest/tests/filters/test_circular_particle_filter.py @@ -6,7 +6,7 @@ from pyrecest.backend import all import unittest -import numpy as np + from pyrecest.distributions import ( HypertoroidalDiracDistribution, WrappedNormalDistribution, diff --git a/pyrecest/tests/filters/test_euclidean_particle_filter.py b/pyrecest/tests/filters/test_euclidean_particle_filter.py index eb0eb309..40a86928 100644 --- a/pyrecest/tests/filters/test_euclidean_particle_filter.py +++ b/pyrecest/tests/filters/test_euclidean_particle_filter.py @@ -7,7 +7,7 @@ from pyrecest.backend import zeros import unittest -import numpy as np + from pyrecest.distributions import GaussianDistribution from pyrecest.filters.euclidean_particle_filter import EuclideanParticleFilter diff --git a/pyrecest/tests/filters/test_global_nearest_neighbor.py b/pyrecest/tests/filters/test_global_nearest_neighbor.py index 84f304e4..426d6f71 100644 --- a/pyrecest/tests/filters/test_global_nearest_neighbor.py +++ b/pyrecest/tests/filters/test_global_nearest_neighbor.py @@ -9,7 +9,7 @@ import pyrecest.backend import unittest -import numpy as np + import scipy from parameterized import parameterized from pyrecest.distributions import GaussianDistribution diff --git a/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py b/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py index c1482f1c..d486558e 100644 --- a/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py +++ b/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py @@ -4,7 +4,7 @@ from pyrecest.backend import zeros import unittest -import numpy as np + from pyrecest.distributions import HypertoroidalWNDistribution from pyrecest.filters import HypertoroidalParticleFilter diff --git a/pyrecest/tests/filters/test_kalman_filter.py b/pyrecest/tests/filters/test_kalman_filter.py index c084f382..3c425ba2 100644 --- a/pyrecest/tests/filters/test_kalman_filter.py +++ b/pyrecest/tests/filters/test_kalman_filter.py @@ -6,7 +6,7 @@ import copy import unittest -import numpy as np + from pyrecest.distributions import GaussianDistribution from pyrecest.filters.kalman_filter import KalmanFilter diff --git a/pyrecest/tests/filters/test_random_matrix_tracker.py b/pyrecest/tests/filters/test_random_matrix_tracker.py index ee727f6f..d547098b 100644 --- a/pyrecest/tests/filters/test_random_matrix_tracker.py +++ b/pyrecest/tests/filters/test_random_matrix_tracker.py @@ -9,7 +9,7 @@ from unittest.mock import patch import matplotlib.pyplot as plt -import numpy as np + from parameterized import parameterized from pyrecest.distributions.nonperiodic.gaussian_distribution import ( GaussianDistribution, diff --git a/pyrecest/tests/filters/test_toroidal_particle_filter.py b/pyrecest/tests/filters/test_toroidal_particle_filter.py index d77faddf..ffba8314 100644 --- a/pyrecest/tests/filters/test_toroidal_particle_filter.py +++ b/pyrecest/tests/filters/test_toroidal_particle_filter.py @@ -5,7 +5,7 @@ from pyrecest.backend import all import unittest -import numpy as np + from pyrecest.distributions.hypertorus.hypertoroidal_wrapped_normal_distribution import ( HypertoroidalWrappedNormalDistribution, ) diff --git a/pyrecest/tests/filters/test_toroidal_wrapped_normal_filter.py b/pyrecest/tests/filters/test_toroidal_wrapped_normal_filter.py index dc50cfd2..a4d5ea22 100644 --- a/pyrecest/tests/filters/test_toroidal_wrapped_normal_filter.py +++ b/pyrecest/tests/filters/test_toroidal_wrapped_normal_filter.py @@ -3,7 +3,7 @@ from pyrecest.backend import array import unittest -import numpy as np + from pyrecest.distributions.hypertorus.toroidal_wrapped_normal_distribution import ( ToroidalWrappedNormalDistribution, ) diff --git a/pyrecest/tests/filters/test_von_mises_filter.py b/pyrecest/tests/filters/test_von_mises_filter.py index 38c4229d..8ad64cf8 100644 --- a/pyrecest/tests/filters/test_von_mises_filter.py +++ b/pyrecest/tests/filters/test_von_mises_filter.py @@ -1,6 +1,6 @@ import unittest -import numpy as np + from pyrecest.distributions import VonMisesDistribution from pyrecest.filters.von_mises_filter import VonMisesFilter diff --git a/pyrecest/tests/filters/test_von_mises_fisher_filter.py b/pyrecest/tests/filters/test_von_mises_fisher_filter.py index 2d2ab614..5dff8f43 100644 --- a/pyrecest/tests/filters/test_von_mises_fisher_filter.py +++ b/pyrecest/tests/filters/test_von_mises_fisher_filter.py @@ -5,7 +5,7 @@ from pyrecest.backend import all import unittest -import numpy as np + from pyrecest.distributions import VonMisesFisherDistribution from pyrecest.filters.von_mises_fisher_filter import VonMisesFisherFilter diff --git a/pyrecest/tests/filters/test_wrapped_normal_filter.py b/pyrecest/tests/filters/test_wrapped_normal_filter.py index 5deab62e..01a3e3a2 100644 --- a/pyrecest/tests/filters/test_wrapped_normal_filter.py +++ b/pyrecest/tests/filters/test_wrapped_normal_filter.py @@ -1,6 +1,6 @@ import unittest from pyrecest.backend import array -import numpy as np + from pyrecest.distributions import WrappedNormalDistribution from pyrecest.filters.wrapped_normal_filter import WrappedNormalFilter diff --git a/pyrecest/tests/test_euclidean_sampler.py b/pyrecest/tests/test_euclidean_sampler.py index 088e115c..344ff2f0 100644 --- a/pyrecest/tests/test_euclidean_sampler.py +++ b/pyrecest/tests/test_euclidean_sampler.py @@ -7,7 +7,7 @@ from pyrecest.backend import zeros import unittest -import numpy as np + from pyrecest.sampling.euclidean_sampler import GaussianSampler diff --git a/pyrecest/tests/test_evaluation_basic.py b/pyrecest/tests/test_evaluation_basic.py index 140980ba..22d13938 100644 --- a/pyrecest/tests/test_evaluation_basic.py +++ b/pyrecest/tests/test_evaluation_basic.py @@ -15,7 +15,7 @@ import unittest from typing import Optional -import numpy as np + from parameterized import parameterized from pyrecest.distributions import ( GaussianDistribution, @@ -280,7 +280,7 @@ def test_perform_predict_update_cycles(self): self.assertIsInstance(time_elapsed, float) self.assertGreater(time_elapsed, 0) self.assertIsNotNone(last_filter_state) - self.assertIsInstance(last_estimate, np.ndarray) + self.assertIsInstance(last_estimate, ) self.assertEqual(last_estimate.shape, (2,)) self.assertIsNone(all_estimates) @@ -375,11 +375,11 @@ def _validate_eval_data( self.assertTrue(not any(run_failed)) self.assertEqual(ndim(groundtruths), 2) - self.assertIsInstance(groundtruths[0, 0], np.ndarray) + self.assertIsInstance(groundtruths[0, 0], ) self.assertIn(ndim(groundtruths[0, 0]), (1, 2)) self.assertEqual(ndim(measurements), 2) - self.assertIsInstance(measurements[0, 0], np.ndarray) + self.assertIsInstance(measurements[0, 0], ) self.assertIn(ndim(measurements[0, 0]), (1, 2)) def test_evaluate_for_simulation_config_R2_random_walk(self): diff --git a/pyrecest/tests/test_hyperspherical_sampler.py b/pyrecest/tests/test_hyperspherical_sampler.py index c0da5752..c2655518 100644 --- a/pyrecest/tests/test_hyperspherical_sampler.py +++ b/pyrecest/tests/test_hyperspherical_sampler.py @@ -7,7 +7,7 @@ import importlib.util healpy_installed = importlib.util.find_spec("healpy") is not None -import numpy as np + from parameterized import parameterized from pyrecest.sampling.hyperspherical_sampler import get_grid_hypersphere diff --git a/pyrecest/tests/test_hypertoroidal_sampler.py b/pyrecest/tests/test_hypertoroidal_sampler.py index c43efe27..66185e24 100644 --- a/pyrecest/tests/test_hypertoroidal_sampler.py +++ b/pyrecest/tests/test_hypertoroidal_sampler.py @@ -3,7 +3,7 @@ from pyrecest.backend import all import unittest -import numpy as np + from pyrecest.sampling.hypertoroidal_sampler import CircularUniformSampler diff --git a/pyrecest/tests/test_metrics.py b/pyrecest/tests/test_metrics.py index 47d701bd..cc57ebe4 100644 --- a/pyrecest/tests/test_metrics.py +++ b/pyrecest/tests/test_metrics.py @@ -3,7 +3,7 @@ from pyrecest.backend import array import unittest -import numpy as np + from pyrecest.utils.metrics import anees diff --git a/pyrecest/utils/metrics.py b/pyrecest/utils/metrics.py index 4b683379..ffa95afe 100644 --- a/pyrecest/utils/metrics.py +++ b/pyrecest/utils/metrics.py @@ -1,7 +1,7 @@ from pyrecest.backend import linalg from pyrecest.backend import mean from pyrecest.backend import zeros -import numpy as np + def anees(estimates, uncertainties, groundtruths): diff --git a/pyrecest/utils/plotting.py b/pyrecest/utils/plotting.py index ad9615d0..bd8db833 100644 --- a/pyrecest/utils/plotting.py +++ b/pyrecest/utils/plotting.py @@ -11,7 +11,7 @@ from pyrecest.backend import array from pyrecest.backend import complex64 import matplotlib.pyplot as plt -import numpy as np + def plot_ellipsoid(center, shape_matrix, scaling_factor=1, color="blue"): From 2a1c1fa0502e7ee47a9e10b69da4d01f2d2b1c75 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Sat, 21 Oct 2023 10:00:49 +0100 Subject: [PATCH 066/232] More --- .../distributions/circle/abstract_circular_distribution.py | 6 +++--- .../distributions/circle/circular_dirac_distribution.py | 2 +- .../abstract_hypersphere_subset_distribution.py | 2 +- .../distributions/hypertorus/toroidal_dirac_distribution.py | 5 +++-- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/pyrecest/distributions/circle/abstract_circular_distribution.py b/pyrecest/distributions/circle/abstract_circular_distribution.py index 8495fbc9..47eea95c 100644 --- a/pyrecest/distributions/circle/abstract_circular_distribution.py +++ b/pyrecest/distributions/circle/abstract_circular_distribution.py @@ -37,11 +37,11 @@ def _cdf_numerical_single( starting_point, ): """Helper method for cdf_numerical""" - starting_point_mod = mod(starting_point, 2 * pi) - x_mod = mod(x, 2 * pi) + starting_point_mod = mod(starting_point, 2.0 * pi) + x_mod = mod(x, 2.0 * pi) if x_mod < starting_point_mod: - return 1 - self.integrate_numerically(array([x_mod, starting_point_mod])) + return 1.0 - self.integrate_numerically(array([x_mod, starting_point_mod])) return self.integrate_numerically(array([starting_point_mod, x_mod])) diff --git a/pyrecest/distributions/circle/circular_dirac_distribution.py b/pyrecest/distributions/circle/circular_dirac_distribution.py index 3805458a..71820fb0 100644 --- a/pyrecest/distributions/circle/circular_dirac_distribution.py +++ b/pyrecest/distributions/circle/circular_dirac_distribution.py @@ -8,7 +8,7 @@ class CircularDiracDistribution( HypertoroidalDiracDistribution, AbstractCircularDistribution ): - def __init__(self, d, w: | None = None): + def __init__(self, d, w): """ Initializes a CircularDiracDistribution instance. diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py index a9848989..5d44a320 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py @@ -191,7 +191,7 @@ def mean_axis_numerical(self): mom = self.moment_numerical() return AbstractHypersphereSubsetDistribution._compute_mean_axis_from_moment(mom) - def integrate(self, integration_boundaries: | None = None): + def integrate(self, integration_boundaries): if integration_boundaries is None: integration_boundaries = self.__class__.get_full_integration_boundaries( self.dim diff --git a/pyrecest/distributions/hypertorus/toroidal_dirac_distribution.py b/pyrecest/distributions/hypertorus/toroidal_dirac_distribution.py index 5812dac4..4544e6f6 100644 --- a/pyrecest/distributions/hypertorus/toroidal_dirac_distribution.py +++ b/pyrecest/distributions/hypertorus/toroidal_dirac_distribution.py @@ -5,6 +5,7 @@ from pyrecest.backend import sin from pyrecest.backend import dot from pyrecest.backend import cos +from pyrecest.backend import column_stack from .abstract_toroidal_distribution import AbstractToroidalDistribution @@ -14,7 +15,7 @@ class ToroidalDiracDistribution( HypertoroidalDiracDistribution, AbstractToroidalDistribution ): - def __init__(self, d, w: | None = None): + def __init__(self, d, w): """ Initialize ToroidalDiracDistribution. @@ -46,7 +47,7 @@ def covariance_4D(self): :returns: 4D covariance matrix. """ - dbar = np.column_stack( + dbar = column_stack( [ cos(self.d[0, :]), sin(self.d[0, :]), From adecfb03e0879b196ac81c9190bdc80354ee7baf Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Sat, 21 Oct 2023 10:03:34 +0100 Subject: [PATCH 067/232] Yet more --- .../circle/circular_fourier_distribution.py | 16 ++++++++-------- .../distributions/circle/circular_mixture.py | 2 +- .../circle/wrapped_normal_distribution.py | 2 +- .../abstract_hyperhemispherical_distribution.py | 2 +- .../abstract_hyperspherical_distribution.py | 2 +- .../hypertorus/hypertoroidal_mixture.py | 2 +- pyrecest/evaluation/determine_all_deviations.py | 2 +- pyrecest/filters/kalman_filter.py | 12 ++++++------ 8 files changed, 20 insertions(+), 20 deletions(-) diff --git a/pyrecest/distributions/circle/circular_fourier_distribution.py b/pyrecest/distributions/circle/circular_fourier_distribution.py index 4b36cd86..f95b9f66 100644 --- a/pyrecest/distributions/circle/circular_fourier_distribution.py +++ b/pyrecest/distributions/circle/circular_fourier_distribution.py @@ -35,9 +35,9 @@ class CircularFourierDistribution(AbstractCircularDistribution): def __init__( self, transformation: str = "sqrt", - c: | None = None, - a: | None = None, - b: | None = None, + c = None, + a = None, + b = None, n: int | None = None, multiplied_by_n: bool = True, ): @@ -177,8 +177,8 @@ def integrate(self, integration_boundaries=None) -> float: a: array = self.a b: array = self.b if self.multiplied_by_n: - a = a * (1 / self.n) - b = b * (1 / self.n) + a = a * (1.0 / self.n) + b = b * (1.0 / self.n) if self.transformation == "identity": a0_non_rooted = a[0] @@ -192,7 +192,7 @@ def integrate(self, integration_boundaries=None) -> float: elif self.c is not None: if self.transformation == "identity": if self.multiplied_by_n: - c0 = real(self.c[0]) * (1 / self.n) + c0 = real(self.c[0]) * (1.0 / self.n) else: c0 = real(self.c[0]) integral = 2.0 * pi * c0 @@ -206,7 +206,7 @@ def integrate(self, integration_boundaries=None) -> float: (imag(c[1:])) ** 2 ) - a0_non_rooted = 2 * from_c0 + 4 * from_c1_to_end + a0_non_rooted = 2.0 * from_c0 + 4.0 * from_c1_to_end integral = a0_non_rooted * pi else: raise NotImplementedError("Transformation not supported.") @@ -323,7 +323,7 @@ def from_distribution( @staticmethod def from_function_values( - fvals: , + fvals, transformation: str = "sqrt", store_values_multiplied_by_n: bool = True, ) -> "CircularFourierDistribution": diff --git a/pyrecest/distributions/circle/circular_mixture.py b/pyrecest/distributions/circle/circular_mixture.py index 56f33358..4ad82bfe 100644 --- a/pyrecest/distributions/circle/circular_mixture.py +++ b/pyrecest/distributions/circle/circular_mixture.py @@ -16,7 +16,7 @@ class CircularMixture(AbstractCircularDistribution, HypertoroidalMixture): def __init__( self, dists: collections.abc.Sequence[AbstractCircularDistribution], - w: , + w, ): """ Creates a new circular mixture. diff --git a/pyrecest/distributions/circle/wrapped_normal_distribution.py b/pyrecest/distributions/circle/wrapped_normal_distribution.py index b6e5d679..2ccfa9c7 100644 --- a/pyrecest/distributions/circle/wrapped_normal_distribution.py +++ b/pyrecest/distributions/circle/wrapped_normal_distribution.py @@ -95,7 +95,7 @@ def pdf(self, xs: | Any | numbers.Real): def cdf( self, - xs: , + xs, startingPoint: float = 0, n_wraps: Union[int, int32, int64] = 10, ): diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py index dc1acdc7..b599b003 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py @@ -42,7 +42,7 @@ def sample_metropolis_hastings( burn_in: Union[int, int32, int64] = 10, skipping: Union[int, int32, int64] = 5, proposal: Callable | None = None, - start_point: | None = None, + start_point = None, ): # jscpd:ignore-end if proposal is None: diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py index b5bb6c17..1a23eef5 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py @@ -46,7 +46,7 @@ def sample_metropolis_hastings( burn_in: Union[int, int32, int64] = 10, skipping: Union[int, int32, int64] = 5, proposal: Callable | None = None, - start_point: | None = None, + start_point = None, ): # jscpd:ignore-end """ diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_mixture.py b/pyrecest/distributions/hypertorus/hypertoroidal_mixture.py index ee5730ee..a33bfc05 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_mixture.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_mixture.py @@ -17,7 +17,7 @@ class HypertoroidalMixture(AbstractMixture, AbstractHypertoroidalDistribution): def __init__( self, dists: collections.abc.Sequence[AbstractHypertoroidalDistribution], - w: | None = None, + w = None, ): """ Constructor diff --git a/pyrecest/evaluation/determine_all_deviations.py b/pyrecest/evaluation/determine_all_deviations.py index 3276ef3a..c95cff22 100644 --- a/pyrecest/evaluation/determine_all_deviations.py +++ b/pyrecest/evaluation/determine_all_deviations.py @@ -13,7 +13,7 @@ def determine_all_deviations( results, extract_mean, distance_function: Callable, - groundtruths: , + groundtruths, mean_calculation_symm: str = "", ): if mean_calculation_symm != "": diff --git a/pyrecest/filters/kalman_filter.py b/pyrecest/filters/kalman_filter.py index abed790d..743b56aa 100644 --- a/pyrecest/filters/kalman_filter.py +++ b/pyrecest/filters/kalman_filter.py @@ -67,9 +67,9 @@ def predict_identity(self, sys_noise_cov, sys_input: = None): def predict_linear( self, - system_matrix: , - sys_noise_cov: , - sys_input: | None = None, + system_matrix, + sys_noise_cov, + sys_input = None, ): """ Predicts the next state assuming a linear system model. @@ -101,9 +101,9 @@ def update_identity(self, meas_noise, measurement): def update_linear( self, - measurement: , - measurement_matrix: , - meas_noise: , + measurement, + measurement_matrix, + meas_noise, ): """ Update the filter state with measurement, assuming a linear measurement model. From 6a4c0b6777294b7303c7afefa9a77c898608a04e Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Sat, 21 Oct 2023 11:50:11 +0100 Subject: [PATCH 068/232] More....... --- .../circle/circular_fourier_distribution.py | 8 ++++---- .../circle/custom_circular_distribution.py | 4 ++-- .../circle/von_mises_distribution.py | 19 +++++++------------ .../circle/wrapped_normal_distribution.py | 16 ++++++++-------- ...bstract_hyperhemispherical_distribution.py | 4 ++-- .../abstract_sphere_subset_distribution.py | 8 ++++---- .../hyperhemispherical_watson_distribution.py | 4 ++-- .../von_mises_fisher_distribution.py | 5 +++-- .../hypersphere_subset/watson_distribution.py | 2 +- .../hypertoroidal_uniform_distribution.py | 10 +++++----- 10 files changed, 38 insertions(+), 42 deletions(-) diff --git a/pyrecest/distributions/circle/circular_fourier_distribution.py b/pyrecest/distributions/circle/circular_fourier_distribution.py index f95b9f66..1e2e5dce 100644 --- a/pyrecest/distributions/circle/circular_fourier_distribution.py +++ b/pyrecest/distributions/circle/circular_fourier_distribution.py @@ -14,7 +14,7 @@ from pyrecest.backend import int64 from pyrecest.backend import int32 from pyrecest.backend import array -from pyrecest +from pyrecest.backend import conj import warnings import matplotlib.pyplot as plt @@ -246,13 +246,13 @@ def plot(self, resolution=128, **kwargs): return p - def get_a_b(self) -> tuple[, ]: + def get_a_b(self): if self.a is not None: a = self.a b = self.b elif self.c is not None: - a = 2 * real(self.c) - b = -2 * imag(self.c[1:]) + a = 2.0 * real(self.c) + b = -2.0 * imag(self.c[1:]) assert ( self.n is None or (a.shape[0] + b.shape[0]) == self.n ) # Other case not implemented yet! diff --git a/pyrecest/distributions/circle/custom_circular_distribution.py b/pyrecest/distributions/circle/custom_circular_distribution.py index 0d37a961..f5ca8b5e 100644 --- a/pyrecest/distributions/circle/custom_circular_distribution.py +++ b/pyrecest/distributions/circle/custom_circular_distribution.py @@ -44,7 +44,7 @@ def pdf(self, xs): self, mod(xs + self.shift_by, 2 * pi) ) - def integrate(self, integration_boundaries: | None = None) -> float: + def integrate(self, integration_boundaries=None) -> float: """ Computes the integral of the pdf over the given boundaries. @@ -56,5 +56,5 @@ def integrate(self, integration_boundaries: | None = None) -> float: float: The value of the integral. """ if integration_boundaries is None: - integration_boundaries = array([0, 2 * pi]) + integration_boundaries = array([0.0, 2.0 * pi]) return AbstractCircularDistribution.integrate(self, integration_boundaries) \ No newline at end of file diff --git a/pyrecest/distributions/circle/von_mises_distribution.py b/pyrecest/distributions/circle/von_mises_distribution.py index 5b8b17e7..2e12b5fb 100644 --- a/pyrecest/distributions/circle/von_mises_distribution.py +++ b/pyrecest/distributions/circle/von_mises_distribution.py @@ -25,7 +25,7 @@ class VonMisesDistribution(AbstractCircularDistribution): def __init__( self, - mu: Any | numbers.Real, + mu, kappa, norm_const: float | None = None, ): @@ -50,8 +50,7 @@ def pdf(self, xs): @staticmethod def besselratio( - nu: Any | numbers.Real, kappa: Any | numbers.Real - ) -> Any | numbers.Real: + nu, kappa): return iv(nu + 1, kappa) / iv(nu, kappa) def cdf(self, xs, starting_point=0): @@ -73,9 +72,7 @@ def cdf(self, xs, starting_point=0): r = zeros_like(xs) - def to_minus_pi_to_pi_range( - angle: Any | numbers.Real | , - ) -> Any | numbers.Real | : + def to_minus_pi_to_pi_range(angle): return mod(angle + pi, 2 * pi) - pi r = vonmises.cdf( @@ -96,9 +93,7 @@ def to_minus_pi_to_pi_range( return r @staticmethod - def besselratio_inverse( - v: Any | numbers.Real, x: Any | numbers.Real - ) -> Any | numbers.Real: + def besselratio_inverse(v, x): def f(t: float) -> float: return VonMisesDistribution.besselratio(v, t) - x @@ -114,7 +109,7 @@ def multiply(self, vm2: "VonMisesDistribution") -> "VonMisesDistribution": return VonMisesDistribution(mu_, kappa_) def convolve(self, vm2: "VonMisesDistribution") -> "VonMisesDistribution": - mu_ = mod(self.mu + vm2.mu, 2 * pi) + mu_ = mod(self.mu + vm2.mu, 2.0 * pi) t = VonMisesDistribution.besselratio( 0, self.kappa ) * VonMisesDistribution.besselratio(0, vm2.kappa) @@ -123,7 +118,7 @@ def convolve(self, vm2: "VonMisesDistribution") -> "VonMisesDistribution": def entropy(self): result = -self.kappa * VonMisesDistribution.besselratio(0, self.kappa) + log( - 2 * pi * iv(0, self.kappa) + 2.0 * pi * iv(0, self.kappa) ) return result @@ -138,7 +133,7 @@ def from_moment(m): Returns: vm (VMDistribution): VM distribution obtained by moment matching. """ - mu_ = mod(arctan2(imag(m), real(m)), 2 * pi) + mu_ = mod(arctan2(imag(m), real(m)), 2.0 * pi) kappa_ = VonMisesDistribution.besselratio_inverse(0, abs(m)) vm = VonMisesDistribution(mu_, kappa_) return vm diff --git a/pyrecest/distributions/circle/wrapped_normal_distribution.py b/pyrecest/distributions/circle/wrapped_normal_distribution.py index 2ccfa9c7..4ab377a9 100644 --- a/pyrecest/distributions/circle/wrapped_normal_distribution.py +++ b/pyrecest/distributions/circle/wrapped_normal_distribution.py @@ -37,8 +37,8 @@ class WrappedNormalDistribution( def __init__( self, - mu: Any | numbers.Real | , - sigma: Any | numbers.Real | , + mu, + sigma, ): """ Initialize a wrapped normal distribution with mean mu and standard deviation sigma. @@ -50,7 +50,7 @@ def __init__( def sigma(self): return sqrt(self.C) - def pdf(self, xs: | Any | numbers.Real): + def pdf(self, xs): if self.sigma <= 0: raise ValueError(f"sigma must be >0, but received {self.sigma}.") @@ -65,14 +65,14 @@ def pdf(self, xs: | Any | numbers.Real): result[:] = 1.0 / (2 * pi) return result - x = mod(xs, 2 * pi) - x[x < 0] += 2 * pi + x = mod(xs, 2.0 * pi) + x[x < 0] += 2.0 * pi x -= self.mu max_iterations = 1000 - tmp = -1.0 / (2 * self.sigma**2) - nc = 1 / sqrt(2 * pi) / self.sigma + tmp = -1.0 / (2.0 * self.sigma**2) + nc = 1.0 / sqrt(2.0 * pi) / self.sigma for i in range(n_inputs): old_result = 0 @@ -125,7 +125,7 @@ def ncdf(from_, to): def trigonometric_moment( self, n: Union[int, int32, int64] - ) -> complex | : + ): return exp(1j * n * self.mu - n**2 * self.sigma**2 / 2) def multiply( diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py index b599b003..ca1b0caa 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py @@ -113,7 +113,7 @@ def get_full_integration_boundaries(dim: Union[int, int32, int64]): ).T return integration_boundaries - def integrate(self, integration_boundaries: | None = None) -> float: + def integrate(self, integration_boundaries = None) -> float: if integration_boundaries is None: integration_boundaries = ( AbstractHyperhemisphericalDistribution.get_full_integration_boundaries( @@ -123,7 +123,7 @@ def integrate(self, integration_boundaries: | None = None) -> float: return super().integrate(integration_boundaries) def integrate_numerically( - self, integration_boundaries: | None = None + self, integration_boundaries=None ) -> float: if integration_boundaries is None: integration_boundaries = ( diff --git a/pyrecest/distributions/hypersphere_subset/abstract_sphere_subset_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_sphere_subset_distribution.py index abbed88e..c30d250a 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_sphere_subset_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_sphere_subset_distribution.py @@ -83,7 +83,7 @@ def cart_to_sph( return phi, theta @staticmethod - def _sph_to_cart_colatitude(azimuth, colatitude: ) -> tuple: + def _sph_to_cart_colatitude(azimuth, colatitude) -> tuple: assert ndim(azimuth) == 1 and ndim( colatitude ), "Inputs must be 1-dimensional" @@ -93,7 +93,7 @@ def _sph_to_cart_colatitude(azimuth, colatitude: ) -> tuple: return x, y, z @staticmethod - def _sph_to_cart_elevation(azimuth, elevation: ) -> tuple: + def _sph_to_cart_elevation(azimuth, elevation) -> tuple: """ Convert spherical coordinates (using elevation) to Cartesian coordinates. Assumes a radius of 1. @@ -116,7 +116,7 @@ def _sph_to_cart_elevation(azimuth, elevation: ) -> tuple: return x, y, z @staticmethod - def _cart_to_sph_colatitude(x, y, z: ) -> tuple: + def _cart_to_sph_colatitude(x, y, z) -> tuple: assert ndim(x) == 1 and ndim(y) == 1 and ndim(z) radius = 1 azimuth = arctan2(y, x) @@ -125,7 +125,7 @@ def _cart_to_sph_colatitude(x, y, z: ) -> tuple: return azimuth, colatitude @staticmethod - def _cart_to_sph_elevation(x, y, z: ) -> tuple: + def _cart_to_sph_elevation(x, y, z) -> tuple: assert ndim(x) == 1 and ndim(y) == 1 and ndim(z) == 1 radius = 1 azimuth = arctan2(y, x) diff --git a/pyrecest/distributions/hypersphere_subset/hyperhemispherical_watson_distribution.py b/pyrecest/distributions/hypersphere_subset/hyperhemispherical_watson_distribution.py index 928f8ea8..a3f927ba 100644 --- a/pyrecest/distributions/hypersphere_subset/hyperhemispherical_watson_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/hyperhemispherical_watson_distribution.py @@ -16,7 +16,7 @@ class HyperhemisphericalWatsonDistribution(AbstractHyperhemisphericalDistribution): - def __init__(self, mu, kappa: Any | numbers.Real): + def __init__(self, mu, kappa): assert mu[-1] >= 0 self.dist_full_sphere = WatsonDistribution(mu, kappa) AbstractHyperhemisphericalDistribution.__init__( @@ -26,7 +26,7 @@ def __init__(self, mu, kappa: Any | numbers.Real): def pdf(self, xs): return 2 * self.dist_full_sphere.pdf(xs) - def set_mode(self, mu: ) -> "HyperhemisphericalWatsonDistribution": + def set_mode(self, mu) -> "HyperhemisphericalWatsonDistribution": w = self w.mu = mu return w diff --git a/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py b/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py index cde696c6..128e4c68 100644 --- a/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py @@ -13,6 +13,7 @@ from pyrecest.backend import abs from pyrecest.backend import int64 from pyrecest.backend import int32 +from pyrecest.backend import zeros import numbers @@ -24,7 +25,7 @@ class VonMisesFisherDistribution(AbstractHypersphericalDistribution): - def __init__(self, mu, kappa: Any | numbers.Real): + def __init__(self, mu, kappa): AbstractHypersphericalDistribution.__init__(self, dim=mu.shape[0] - 1) epsilon = 1e-6 assert ( @@ -42,7 +43,7 @@ def __init__(self, mu, kappa: Any | numbers.Real): (2.0 * pi) ** ((self.dim + 1) / 2.0) * iv((self.dim + 1) / 2 - 1, kappa) ) - def pdf(self, xs: | Any) -> | Any: + def pdf(self, xs): assert xs.shape[-1] == self.input_dim return self.C * exp(self.kappa * self.mu.T @ xs.T) diff --git a/pyrecest/distributions/hypersphere_subset/watson_distribution.py b/pyrecest/distributions/hypersphere_subset/watson_distribution.py index c436bb04..62865a8e 100644 --- a/pyrecest/distributions/hypersphere_subset/watson_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/watson_distribution.py @@ -23,7 +23,7 @@ class WatsonDistribution(AbstractHypersphericalDistribution): EPSILON = 1e-6 - def __init__(self, mu, kappa: Any | numbers.Real): + def __init__(self, mu, kappa): """ Initializes a new instance of the WatsonDistribution class. diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_uniform_distribution.py b/pyrecest/distributions/hypertorus/hypertoroidal_uniform_distribution.py index 4144ff5a..2a38092d 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_uniform_distribution.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_uniform_distribution.py @@ -44,7 +44,7 @@ def entropy(self) -> float: :returns: Entropy """ - return self.dim * log(2 * pi) + return self.dim * log(2.0 * pi) def mean_direction(self): """ @@ -64,7 +64,7 @@ def sample(self, n: Union[int, int32, int64]): :param n: Sample size :returns: Sample of size n """ - return 2 * pi * random.rand(n, self.dim) + return 2.0 * pi * random.rand(n, self.dim) def shift(self, shift_by) -> "HypertoroidalUniformDistribution": """ @@ -78,7 +78,7 @@ def shift(self, shift_by) -> "HypertoroidalUniformDistribution": return self def integrate( - self, integration_boundaries: tuple[, ] | None = None + self, integration_boundaries=None ) -> float: """ Returns the integral of the distribution over the specified boundaries @@ -89,11 +89,11 @@ def integrate( """ if integration_boundaries is None: left = zeros((self.dim,)) - right = 2 * pi * ones((self.dim,)) + right = 2.0 * pi * ones((self.dim,)) else: left, right = integration_boundaries assert ndim(left) == 0 and self.dim == 1 or left.shape == (self.dim,) assert ndim(right) == 0 and self.dim == 1 or right.shape == (self.dim,) volume = prod(right - left) - return 1 / (2 * pi) ** self.dim * volume \ No newline at end of file + return 1.0 / (2.0 * pi) ** self.dim * volume \ No newline at end of file From fe9a5daf5024615886ecafa07888f3923e221f80 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Sat, 21 Oct 2023 12:03:37 +0100 Subject: [PATCH 069/232] More --- .../abstract_hypercylindrical_distribution.py | 2 +- .../hypercylindrical_dirac_distribution.py | 2 +- ...bstract_hypersphere_subset_distribution.py | 2 +- ...stract_spherical_harmonics_distribution.py | 4 +- ...pherical_harmonics_distribution_complex.py | 2 +- .../spherical_harmonics_distribution_real.py | 2 +- .../von_mises_fisher_distribution.py | 2 +- .../abstract_linear_distribution.py | 4 +- .../nonperiodic/gaussian_mixture.py | 2 +- pyrecest/evaluation/generate_measurements.py | 2 +- .../abstract_nearest_neighbor_tracker.py | 2 +- .../filters/abstract_tracker_with_logging.py | 4 +- .../filters/hypertoroidal_particle_filter.py | 7 +- .../test_abstract_circular_distribution.py | 19 +- ...pherical_harmonics_distribution_complex.py | 278 +++++++++--------- ...t_spherical_harmonics_distribution_real.py | 114 +++---- 16 files changed, 223 insertions(+), 225 deletions(-) diff --git a/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py b/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py index 5375a5c5..8e304698 100644 --- a/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py +++ b/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py @@ -95,7 +95,7 @@ def linear_covariance(self, approximate_mean=None): The linear covariance. """ if approximate_mean is None: - approximate_mean = np.full((self.lin_dim,), np.nan) + approximate_mean = np.full((self.lin_dim,), float('NaN')) assert approximate_mean.shape[0] == self.lin_dim diff --git a/pyrecest/distributions/cart_prod/hypercylindrical_dirac_distribution.py b/pyrecest/distributions/cart_prod/hypercylindrical_dirac_distribution.py index c7999f1f..8da75262 100644 --- a/pyrecest/distributions/cart_prod/hypercylindrical_dirac_distribution.py +++ b/pyrecest/distributions/cart_prod/hypercylindrical_dirac_distribution.py @@ -36,7 +36,7 @@ def marginalize_linear(self): def hybrid_moment(self): # Specific for Cartesian products of hypertori and R^lin_dim - S = np.full((self.bound_dim * 2 + self.lin_dim, self.d.shape[0]), np.nan) + S = np.full((self.bound_dim * 2 + self.lin_dim, self.d.shape[0]), float('NaN')) S[2 * self.bound_dim :, :] = self.d[:, self.bound_dim :].T # noqa: E203 for i in range(self.bound_dim): diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py index 5d44a320..c45ae9bd 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py @@ -126,7 +126,7 @@ def moment_numerical(self): self.dim + 1, self.dim + 1, ), - np.nan, + float('NaN'), ) def f_gen(i, j): diff --git a/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py index 6ad4581e..bb3fd619 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py @@ -33,7 +33,7 @@ def __init__(self, coeff_mat, transformation="identity"): [ zeros((n - 1, 1)), np.kron( - np.triu(np.full((n - 1, n - 1), np.nan)), array([[1, 1]]) + np.triu(np.full((n - 1, n - 1), float('NaN'))), array([[1, 1]]) ), ], [zeros((1, 2 * n - 1))], @@ -99,7 +99,7 @@ def truncate(self, degree): : 2 * result.coeff_mat.shape[0] - 1, # noqa: E203 ] = result.coeff_mat for i in range(new_coeff_mat.shape[0] - 1): - new_coeff_mat[i, 2 * i + 1 :] = np.nan # noqa: E203 + new_coeff_mat[i, 2 * i + 1 :] = float('NaN') # noqa: E203 result.coeff_mat = new_coeff_mat return result \ No newline at end of file diff --git a/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py b/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py index 2d772296..83ee2f06 100644 --- a/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py +++ b/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py @@ -152,7 +152,7 @@ def from_function_via_integral_sph(fun, degree, transformation="identity"): else: raise ValueError("Transformation not supported") - coeff_mat = np.full((degree + 1, 2 * degree + 1), np.nan, dtype=complex) + coeff_mat = np.full((degree + 1, 2 * degree + 1), float('NaN'), dtype=complex) def real_part(phi, theta, n, m): return real( diff --git a/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_real.py b/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_real.py index 71d62c73..9806eda3 100644 --- a/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_real.py +++ b/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_real.py @@ -59,7 +59,7 @@ def to_spherical_harmonics_distribution_complex(self): raise NotImplementedError("Transformation currently not supported") real_coeff_mat = self.coeff_mat - complex_coeff_mat = np.full_like(real_coeff_mat, np.nan, dtype=complex) + complex_coeff_mat = np.full_like(real_coeff_mat, float('NaN'), dtype=complex) for n in range(real_coeff_mat.shape[0]): for m in range(-n, n + 1): diff --git a/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py b/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py index 128e4c68..b03b61cc 100644 --- a/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py @@ -153,7 +153,7 @@ def convolve(self, other: "VonMisesFisherDistribution"): return VonMisesFisherDistribution(mu_, kappa_) @staticmethod - def a_d(d: Union[int, int32, int64], kappa: Any | numbers.Real): + def a_d(d: Union[int, int32, int64], kappa): bessel1 = iv(d / 2, kappa) bessel2 = iv(d / 2 - 1, kappa) if isnan(bessel1) or isnan(bessel2): diff --git a/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py b/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py index fc3f647b..e49580af 100644 --- a/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py +++ b/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py @@ -215,8 +215,8 @@ def get_suggested_integration_limits(self, scaling_factor=10): """ C = self.covariance() m = self.mode() - left = np.full((self.dim,), np.nan) - right = np.full((self.dim,), np.nan) + left = np.full((self.dim,), float('NaN')) + right = np.full((self.dim,), float('NaN')) for i in range(self.dim): # Change for linear dimensions left[i] = m[i] - scaling_factor * sqrt(C[i, i]) diff --git a/pyrecest/distributions/nonperiodic/gaussian_mixture.py b/pyrecest/distributions/nonperiodic/gaussian_mixture.py index 2f23e5a6..60445173 100644 --- a/pyrecest/distributions/nonperiodic/gaussian_mixture.py +++ b/pyrecest/distributions/nonperiodic/gaussian_mixture.py @@ -23,7 +23,7 @@ def mean(self): gauss_array = self.dists return dot(array([g.mu for g in gauss_array]), self.w) - def set_mean(self, new_mean: | numbers.Real): + def set_mean(self, new_mean): mean_offset = new_mean - self.mean() for dist in self.dists: dist.mu += mean_offset # type: ignore diff --git a/pyrecest/evaluation/generate_measurements.py b/pyrecest/evaluation/generate_measurements.py index d7511f4b..a89aa55c 100644 --- a/pyrecest/evaluation/generate_measurements.py +++ b/pyrecest/evaluation/generate_measurements.py @@ -126,7 +126,7 @@ def generate_measurements(groundtruth, simulation_config): for t in range(simulation_config["n_timesteps"]): n_meas_at_t = sum(n_observations[t, :]) - measurements[t] = np.nan * zeros( + measurements[t] = float('NaN') * zeros( (simulation_config["meas_matrix_for_each_target"].shape[0], n_meas_at_t) ) diff --git a/pyrecest/filters/abstract_nearest_neighbor_tracker.py b/pyrecest/filters/abstract_nearest_neighbor_tracker.py index 39b1cd61..8d3dd354 100644 --- a/pyrecest/filters/abstract_nearest_neighbor_tracker.py +++ b/pyrecest/filters/abstract_nearest_neighbor_tracker.py @@ -143,7 +143,7 @@ def get_point_estimate(self, flatten_vector=False): point_ests = None else: point_ests = empty((self.dim, num_targets)) - point_ests[:] = np.nan + point_ests[:] = float('NaN') for i in range(num_targets): point_ests[:, i] = self.filter_bank[i].get_point_estimate() if flatten_vector: diff --git a/pyrecest/filters/abstract_tracker_with_logging.py b/pyrecest/filters/abstract_tracker_with_logging.py index f8ed3c8d..3a0a749b 100644 --- a/pyrecest/filters/abstract_tracker_with_logging.py +++ b/pyrecest/filters/abstract_tracker_with_logging.py @@ -24,11 +24,11 @@ def _store_estimates(self, curr_ests, estimates_over_time): if n <= m: curr_ests = np.pad( - curr_ests, ((0, m - n), (0, 0)), mode="constant", constant_values=np.nan + curr_ests, ((0, m - n), (0, 0)), mode="constant", constant_values=float('NaN') ) estimates_over_time = hstack((estimates_over_time, curr_ests)) else: - estimates_over_time_new = np.full((n, t + 1), np.nan) + estimates_over_time_new = np.full((n, t + 1), float('NaN')) estimates_over_time_new[:m, :t] = estimates_over_time estimates_over_time_new[:, -1] = curr_ests.flatten() estimates_over_time = estimates_over_time_new diff --git a/pyrecest/filters/hypertoroidal_particle_filter.py b/pyrecest/filters/hypertoroidal_particle_filter.py index 6602db8c..9bc1019f 100644 --- a/pyrecest/filters/hypertoroidal_particle_filter.py +++ b/pyrecest/filters/hypertoroidal_particle_filter.py @@ -37,9 +37,7 @@ def __init__( if dim == 1: # Prevents ambiguities if a vector is of size (dim,) or (n,) (for dim=1) - filter_state = CircularDiracDistribution( - linspace(0.0, 2.0 * pi, num = n_particles, endpoint=False) # Like linspace without endpoint but with compatbiility for pytroch - ) + filter_state = CircularDiracDistribution(linspace(0.0, 2.0 * pi, num = n_particles, endpoint=False) else: filter_state = HypertoroidalDiracDistribution( tile( @@ -76,8 +74,7 @@ def predict_nonlinear( self.filter_state.d = mod(self.filter_state.d, 2.0 * pi) def predict_nonlinear_nonadditive( - self, f: Callable, samples, weights: - ): + self, f: Callable, samples, weights): assert ( samples.shape[0] == weights.size ), "samples and weights must match in size" diff --git a/pyrecest/tests/distributions/test_abstract_circular_distribution.py b/pyrecest/tests/distributions/test_abstract_circular_distribution.py index a29fd46e..aa96af10 100644 --- a/pyrecest/tests/distributions/test_abstract_circular_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_circular_distribution.py @@ -50,19 +50,20 @@ def test_angular_moment_numerical(self): rtol=1e-10, ) ) - + + @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") def test_integral_numerical(self): """Tests if the numerical computation of integral matches the actual integral.""" intervals = [ - (2, 2), - (2, 3), - (5, 4), - (0, 4 * pi), + (2.0, 2.0), + (2.0, 3.0), + (5.0, 4.0), + (0.0, 4.0 * pi), (-pi, pi), - (0, 4 * pi), - (-3 * pi, 3 * pi), - (-1, 20), - (12, -3), + (0.0, 4.0 * pi), + (-3.0 * pi, 3.0 * pi), + (-1.0, 20.0), + (12.0, -3.0), ] for dist in self.distributions: diff --git a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py index 7c9eed71..29657137 100644 --- a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py +++ b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py @@ -35,13 +35,13 @@ def setUp(self): coeff_rand = random.rand(9) self.unnormalized_coeffs = array( [ - [coeff_rand[0], np.nan, np.nan, np.nan, np.nan], + [coeff_rand[0], float('NaN'), float('NaN'), float('NaN'), float('NaN')], [ coeff_rand[1] + 1j * coeff_rand[2], coeff_rand[3], -coeff_rand[1] + 1j * coeff_rand[2], - np.nan, - np.nan, + float('NaN'), + float('NaN'), ], [ coeff_rand[4] + 1j * coeff_rand[5], @@ -88,13 +88,13 @@ def test_integral_analytical(self, transformation): coeff_rand = random.rand(1, 9) unnormalized_coeffs = array( [ - [coeff_rand[0, 0], np.nan, np.nan, np.nan, np.nan], + [coeff_rand[0, 0], float('NaN'), float('NaN'), float('NaN'), float('NaN')], [ coeff_rand[0, 1] + 1j * coeff_rand[0, 2], coeff_rand[0, 3], -coeff_rand[0, 1] + 1j * coeff_rand[0, 2], - np.nan, - np.nan, + float('NaN'), + float('NaN'), ], [ coeff_rand[0, 4] + 1j * coeff_rand[0, 5], @@ -107,7 +107,7 @@ def test_integral_analytical(self, transformation): ) # First initialize and overwrite afterward to prevent normalization shd = SphericalHarmonicsDistributionComplex( - array([[1, np.nan, np.nan], [0, 0, 0]]) + array([[1, float('NaN'), float('NaN')], [0, 0, 0]]) ) shd.coeff_mat = unnormalized_coeffs shd.transformation = transformation @@ -175,8 +175,8 @@ def test_truncation(self): "testl0m0", array( [ - [1, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan], + [1, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN')], [0, 0, 0, 0, 0], ] ), @@ -186,8 +186,8 @@ def test_truncation(self): "testl1m0", array( [ - [0, np.nan, np.nan, np.nan, np.nan], - [0, 1, 0, np.nan, np.nan], + [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 1, 0, float('NaN'), float('NaN')], [0, 0, 0, 0, 0], ] ), @@ -197,8 +197,8 @@ def test_truncation(self): "testl2m0", array( [ - [0, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan], + [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN')], [0, 0, 1, 0, 0], ] ), @@ -211,9 +211,9 @@ def test_truncation(self): "testl3m0", array( [ - [0, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, 0, 0, np.nan, np.nan], + [0, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, 0, 0, float('NaN'), float('NaN')], [0, 0, 0, 1, 0, 0, 0], ] ), @@ -229,8 +229,8 @@ def test_truncation(self): "test_l1mneg1real", array( [ - [0, np.nan, np.nan, np.nan, np.nan], - [1j * sqrt(1 / 2), 0, 1j * sqrt(1 / 2), np.nan, np.nan], + [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [1j * sqrt(1 / 2), 0, 1j * sqrt(1 / 2), float('NaN'), float('NaN')], [0, 0, 0, 0, 0], ] ), @@ -240,8 +240,8 @@ def test_truncation(self): "test_l1m1real", array( [ - [0, np.nan, np.nan, np.nan, np.nan], - [sqrt(1 / 2), 0, -sqrt(1 / 2), np.nan, np.nan], + [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [sqrt(1 / 2), 0, -sqrt(1 / 2), float('NaN'), float('NaN')], [0, 0, 0, 0, 0], ] ), @@ -251,8 +251,8 @@ def test_truncation(self): "test_l2mneg2real", array( [ - [0, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan], + [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN')], [1j * sqrt(1 / 2), 0, 0, 0, -1j * sqrt(1 / 2)], ] ), @@ -262,8 +262,8 @@ def test_truncation(self): "test_l2mneg1real", array( [ - [0, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan], + [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN')], [0, 1j * sqrt(1 / 2), 0, 1j * sqrt(1 / 2), 0], ] ), @@ -273,8 +273,8 @@ def test_truncation(self): "test_l2m1real", array( [ - [0, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan], + [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN')], [0, sqrt(1 / 2), 0, -sqrt(1 / 2), 0], ] ), @@ -284,8 +284,8 @@ def test_truncation(self): "test_l2m2real", array( [ - [0, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan], + [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN')], [sqrt(1 / 2), 0, 0, 0, sqrt(1 / 2)], ] ), @@ -295,9 +295,9 @@ def test_truncation(self): "test_l3mneg3real", array( [ - [0, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, 0, 0, np.nan, np.nan], + [0, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, 0, 0, float('NaN'), float('NaN')], [1j / sqrt(2), 0, 0, 0, 0, 0, 1j / sqrt(2)], ] ), @@ -311,9 +311,9 @@ def test_truncation(self): "test_l3mneg2real", array( [ - [0, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, 0, 0, np.nan, np.nan], + [0, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, 0, 0, float('NaN'), float('NaN')], [0, 1j / sqrt(2), 0, 0, 0, -1j / sqrt(2), 0], ] ), @@ -323,9 +323,9 @@ def test_truncation(self): "test_l3mneg1real", array( [ - [0, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, 0, 0, np.nan, np.nan], + [0, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, 0, 0, float('NaN'), float('NaN')], [0, 0, 1j / sqrt(2), 0, 1j / sqrt(2), 0, 0], ] ), @@ -339,9 +339,9 @@ def test_truncation(self): "test_l3m1real", array( [ - [0, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, 0, 0, np.nan, np.nan], + [0, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, 0, 0, float('NaN'), float('NaN')], [0, 0, 1 / sqrt(2), 0, -1 / sqrt(2), 0, 0], ] ), @@ -355,9 +355,9 @@ def test_truncation(self): "test_l3m2real", array( [ - [0, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, 0, 0, np.nan, np.nan], + [0, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, 0, 0, float('NaN'), float('NaN')], [0, 1 / sqrt(2), 0, 0, 0, 1 / sqrt(2), 0], ] ), @@ -367,9 +367,9 @@ def test_truncation(self): "test_l3m3real", array( [ - [0, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, 0, 0, np.nan, np.nan], + [0, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, 0, 0, float('NaN'), float('NaN')], [1 / sqrt(2), 0, 0, 0, 0, 0, -1 / sqrt(2)], ] ), @@ -399,8 +399,8 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl1mneg1_cart", array( [ - [0, np.nan, np.nan, np.nan, np.nan], - [1, 0, 0, np.nan, np.nan], + [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [1, 0, 0, float('NaN'), float('NaN')], [0, 0, 0, 0, 0], ] ), @@ -410,8 +410,8 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl1m1_cart", array( [ - [0, np.nan, np.nan, np.nan, np.nan], - [0, 0, 1, np.nan, np.nan], + [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 1, float('NaN'), float('NaN')], [0, 0, 0, 0, 0], ] ), @@ -421,8 +421,8 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl2mneg2_cart", array( [ - [0, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan], + [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN')], [1, 0, 0, 0, 0], ] ), @@ -432,8 +432,8 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl2mneg1_cart", array( [ - [0, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan], + [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN')], [0, 1, 0, 0, 0], ] ), @@ -443,8 +443,8 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl2m1_cart", array( [ - [0, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan], + [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN')], [0, 0, 0, 1, 0], ] ), @@ -454,8 +454,8 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl2m2_cart", array( [ - [0, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan], + [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN')], [0, 0, 0, 0, 1], ] ), @@ -466,8 +466,8 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl1mneg1_sph", array( [ - [0, np.nan, np.nan, np.nan, np.nan], - [1, 0, 0, np.nan, np.nan], + [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [1, 0, 0, float('NaN'), float('NaN')], [0, 0, 0, 0, 0], ] ), @@ -480,8 +480,8 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl1m1_sph", array( [ - [0, np.nan, np.nan, np.nan, np.nan], - [0, 0, 1, np.nan, np.nan], + [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 1, float('NaN'), float('NaN')], [0, 0, 0, 0, 0], ] ), @@ -494,8 +494,8 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl2mneg2_sph", array( [ - [0, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan], + [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN')], [1, 0, 0, 0, 0], ] ), @@ -508,8 +508,8 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl2mneg1_sph", array( [ - [0, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan], + [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN')], [0, 1, 0, 0, 0], ] ), @@ -523,8 +523,8 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl2m1_sph", array( [ - [0, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan], + [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN')], [0, 0, 0, 1, 0], ] ), @@ -538,8 +538,8 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl2m2_sph", array( [ - [0, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan], + [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN')], [0, 0, 0, 0, 1], ] ), @@ -552,8 +552,8 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl1mneg1_sphconv_colatitude", array( [ - [0, np.nan, np.nan, np.nan, np.nan], - [1, 0, 0, np.nan, np.nan], + [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [1, 0, 0, float('NaN'), float('NaN')], [0, 0, 0, 0, 0], ] ), @@ -566,8 +566,8 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl1m1_sphconv_colatitude", array( [ - [0, np.nan, np.nan, np.nan, np.nan], - [0, 0, 1, np.nan, np.nan], + [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 1, float('NaN'), float('NaN')], [0, 0, 0, 0, 0], ] ), @@ -580,8 +580,8 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl2mneg2_sphconv_colatitude", array( [ - [0, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan], + [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN')], [1, 0, 0, 0, 0], ] ), @@ -594,8 +594,8 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl2mneg1_sphconv_colatitude", array( [ - [0, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan], + [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN')], [0, 1, 0, 0, 0], ] ), @@ -609,8 +609,8 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl2m1_sphconv_colatitude", array( [ - [0, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan], + [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN')], [0, 0, 0, 1, 0], ] ), @@ -624,8 +624,8 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl2m2_sphconv_colatitude", array( [ - [0, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan], + [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN')], [0, 0, 0, 0, 1], ] ), @@ -665,8 +665,8 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): "l0m0", array( [ - [1, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan], + [1, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN')], [0, 0, 0, 0, 0], ] ), @@ -675,8 +675,8 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): "l1mneg1", array( [ - [1, np.nan, np.nan, np.nan, np.nan], - [1j * sqrt(1 / 2), 0, 1j * sqrt(1 / 2), np.nan, np.nan], + [1, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [1j * sqrt(1 / 2), 0, 1j * sqrt(1 / 2), float('NaN'), float('NaN')], [0, 0, 0, 0, 0], ] ), @@ -685,8 +685,8 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): "l1m0", array( [ - [1, np.nan, np.nan, np.nan, np.nan], - [0, 1, 0, np.nan, np.nan], + [1, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 1, 0, float('NaN'), float('NaN')], [0, 0, 0, 0, 0], ] ), @@ -695,8 +695,8 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): "l1m1", array( [ - [1, np.nan, np.nan, np.nan, np.nan], - [sqrt(1 / 2), 0, -sqrt(1 / 2), np.nan, np.nan], + [1, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [sqrt(1 / 2), 0, -sqrt(1 / 2), float('NaN'), float('NaN')], [0, 0, 0, 0, 0], ] ), @@ -705,8 +705,8 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): "l2mneg2", array( [ - [1, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan], + [1, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN')], [1j * sqrt(1 / 2), 0, 0, 0, -1j * sqrt(1 / 2)], ] ), @@ -715,8 +715,8 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): "l2mneg1", array( [ - [1, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan], + [1, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN')], [0, 1j * sqrt(1 / 2), 0, 1j * sqrt(1 / 2), 0], ] ), @@ -725,8 +725,8 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): "l2m0", array( [ - [1, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan], + [1, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN')], [0, 0, 1, 0, 0], ] ), @@ -735,8 +735,8 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): "l2m1", array( [ - [1, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan], + [1, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN')], [0, sqrt(1 / 2), 0, -sqrt(1 / 2), 0], ] ), @@ -745,8 +745,8 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): "l2m2", array( [ - [1, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan], + [1, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN')], [sqrt(1 / 2), 0, 0, 0, sqrt(1 / 2)], ] ), @@ -755,9 +755,9 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): "l3mneg3", array( [ - [1, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, 0, 0, np.nan, np.nan], + [1, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, 0, 0, float('NaN'), float('NaN')], [1j / sqrt(2), 0, 0, 0, 0, 0, 1j / sqrt(2)], ] ), @@ -766,9 +766,9 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): "l3mneg2", array( [ - [1, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, 0, 0, np.nan, np.nan], + [1, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, 0, 0, float('NaN'), float('NaN')], [0, 1j / sqrt(2), 0, 0, 0, -1j / sqrt(2), 0], ] ), @@ -777,9 +777,9 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): "l3mneg1", array( [ - [1, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, 0, 0, np.nan, np.nan], + [1, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, 0, 0, float('NaN'), float('NaN')], [0, 0, 1j / sqrt(2), 0, 1j / sqrt(2), 0, 0], ] ), @@ -788,9 +788,9 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): "l3m0", array( [ - [1, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, 0, 0, np.nan, np.nan], + [1, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, 0, 0, float('NaN'), float('NaN')], [0, 0, 0, 1, 0, 0, 0], ] ), @@ -799,9 +799,9 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): "l3m1", array( [ - [1, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, 0, 0, np.nan, np.nan], + [1, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, 0, 0, float('NaN'), float('NaN')], [0, 0, 1 / sqrt(2), 0, -1 / sqrt(2), 0, 0], ] ), @@ -810,9 +810,9 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): "l3m2", array( [ - [1, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, 0, 0, np.nan, np.nan], + [1, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, 0, 0, float('NaN'), float('NaN')], [0, 1 / sqrt(2), 0, 0, 0, 1 / sqrt(2), 0], ] ), @@ -821,9 +821,9 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): "l3m3", array( [ - [1, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, 0, 0, np.nan, np.nan], + [1, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, 0, 0, float('NaN'), float('NaN')], [1 / sqrt(2), 0, 0, 0, 0, 0, -1 / sqrt(2)], ] ), @@ -847,21 +847,21 @@ def test_conversion(self, _, coeff_mat): [ ( "shd_x", - array([[1, np.nan, np.nan], [sqrt(1 / 2), 0, -sqrt(1 / 2)]]), + array([[1, float('NaN'), float('NaN')], [sqrt(1 / 2), 0, -sqrt(1 / 2)]]), array([1, 0, 0]), SphericalHarmonicsDistributionComplex.mean_direction, ), ( "shd_y", array( - [[1, np.nan, np.nan], [1j * sqrt(1 / 2), 0, 1j * sqrt(1 / 2)]] + [[1, float('NaN'), float('NaN')], [1j * sqrt(1 / 2), 0, 1j * sqrt(1 / 2)]] ), array([0, 1, 0]), SphericalHarmonicsDistributionComplex.mean_direction, ), ( "shd_z", - array([[1, np.nan, np.nan], [0, 1, 0]]), + array([[1, float('NaN'), float('NaN')], [0, 1, 0]]), array([0, 0, 1]), SphericalHarmonicsDistributionComplex.mean_direction, ), @@ -869,7 +869,7 @@ def test_conversion(self, _, coeff_mat): "shd_xy", array( [ - [1, np.nan, np.nan], + [1, float('NaN'), float('NaN')], [ sqrt(1 / 2) + 1j * sqrt(1 / 2), 0, @@ -882,35 +882,35 @@ def test_conversion(self, _, coeff_mat): ), ( "shd_xz", - array([[1, np.nan, np.nan], [sqrt(1 / 2), 1, -sqrt(1 / 2)]]), + array([[1, float('NaN'), float('NaN')], [sqrt(1 / 2), 1, -sqrt(1 / 2)]]), array([1, 0, 1]) / sqrt(2), SphericalHarmonicsDistributionComplex.mean_direction, ), ( "shd_yz", array( - [[1, np.nan, np.nan], [1j * sqrt(1 / 2), 1, 1j * sqrt(1 / 2)]] + [[1, float('NaN'), float('NaN')], [1j * sqrt(1 / 2), 1, 1j * sqrt(1 / 2)]] ), array([0, 1, 1]) / sqrt(2), SphericalHarmonicsDistributionComplex.mean_direction, ), ( "numerical_shd_x", - array([[1, np.nan, np.nan], [sqrt(1 / 2), 0, -sqrt(1 / 2)]]), + array([[1, float('NaN'), float('NaN')], [sqrt(1 / 2), 0, -sqrt(1 / 2)]]), array([1, 0, 0]), SphericalHarmonicsDistributionComplex.mean_direction_numerical, ), ( "numerical_shd_y", array( - [[1, np.nan, np.nan], [1j * sqrt(1 / 2), 0, 1j * sqrt(1 / 2)]] + [[1, float('NaN'), float('NaN')], [1j * sqrt(1 / 2), 0, 1j * sqrt(1 / 2)]] ), array([0, 1, 0]), SphericalHarmonicsDistributionComplex.mean_direction_numerical, ), ( "numerical_shd_z", - array([[1, np.nan, np.nan], [0, 1, 0]]), + array([[1, float('NaN'), float('NaN')], [0, 1, 0]]), array([0, 0, 1]), SphericalHarmonicsDistributionComplex.mean_direction_numerical, ), @@ -954,7 +954,7 @@ def test_from_distribution_via_integral_uniform(self): def test_transformation_via_integral_shd(self): # Test approximating a spherical harmonic distribution dist = SphericalHarmonicsDistributionComplex( - array([[1, np.nan, np.nan], [0, 1, 0]]) + array([[1, float('NaN'), float('NaN')], [0, 1, 0]]) ) shd = SphericalHarmonicsDistributionComplex.from_function_via_integral_cart( @@ -978,16 +978,16 @@ def test_convergence(self): @parameterized.expand( [ - ("zplus", [[1 / sqrt(4 * pi), np.nan, np.nan], [0, 1, 0]], [0, 0, 1]), + ("zplus", [[1 / sqrt(4 * pi), float('NaN'), float('NaN')], [0, 1, 0]], [0, 0, 1]), ( "zminus", - [[1 / sqrt(4 * pi), np.nan, np.nan], [0, -1, 0]], + [[1 / sqrt(4 * pi), float('NaN'), float('NaN')], [0, -1, 0]], [0, 0, -1], ), ( "yplus", [ - [1 / sqrt(4 * pi), np.nan, np.nan], + [1 / sqrt(4 * pi), float('NaN'), float('NaN')], [1j * sqrt(1 / 2), 0, 1j * sqrt(1 / 2)], ], [0, 1, 0], @@ -995,7 +995,7 @@ def test_convergence(self): ( "yminus", [ - [1 / sqrt(4 * pi), np.nan, np.nan], + [1 / sqrt(4 * pi), float('NaN'), float('NaN')], [-1j * sqrt(1 / 2), 0, -1j * sqrt(1 / 2)], ], [0, -1, 0], @@ -1003,7 +1003,7 @@ def test_convergence(self): ( "xplus", [ - [1 / sqrt(4 * pi), np.nan, np.nan], + [1 / sqrt(4 * pi), float('NaN'), float('NaN')], [sqrt(1 / 2), 0, -sqrt(1 / 2)], ], [1, 0, 0], @@ -1011,7 +1011,7 @@ def test_convergence(self): ( "xminus", [ - [1 / sqrt(4 * pi), np.nan, np.nan], + [1 / sqrt(4 * pi), float('NaN'), float('NaN')], [-sqrt(1 / 2), 0, sqrt(1 / 2)], ], [-1, 0, 0], @@ -1019,7 +1019,7 @@ def test_convergence(self): ( "xyplus", [ - [1 / sqrt(4 * pi), np.nan, np.nan], + [1 / sqrt(4 * pi), float('NaN'), float('NaN')], [ 1j * sqrt(1 / 2) + sqrt(1 / 2), 1, @@ -1031,7 +1031,7 @@ def test_convergence(self): ( "xyminus", [ - [1 / sqrt(4 * pi), np.nan, np.nan], + [1 / sqrt(4 * pi), float('NaN'), float('NaN')], [ -1j * sqrt(1 / 2) - sqrt(1 / 2), 0, diff --git a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py index 8de21916..70c65e0c 100644 --- a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py +++ b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py @@ -52,8 +52,8 @@ def testNormalization(self): ( "l0m0", [ - [1, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan], + [1, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN')], [0, 0, 0, 0, 0], ], lambda x, _, __: ones_like(x) * sqrt(1 / (4 * pi)), @@ -61,8 +61,8 @@ def testNormalization(self): ( "l1mneg1", [ - [0, np.nan, np.nan, np.nan, np.nan], - [1, 0, 0, np.nan, np.nan], + [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [1, 0, 0, float('NaN'), float('NaN')], [0, 0, 0, 0, 0], ], lambda _, y, __: sqrt(3 / (4 * pi)) * y, @@ -70,8 +70,8 @@ def testNormalization(self): ( "l1_m0", [ - [0, np.nan, np.nan, np.nan, np.nan], - [0, 1, 0, np.nan, np.nan], + [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 1, 0, float('NaN'), float('NaN')], [0, 0, 0, 0, 0], ], lambda _, __, z: sqrt(3 / (4 * pi)) * z, @@ -79,8 +79,8 @@ def testNormalization(self): ( "l1_m1", [ - [0, np.nan, np.nan, np.nan, np.nan], - [0, 0, 1, np.nan, np.nan], + [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 1, float('NaN'), float('NaN')], [0, 0, 0, 0, 0], ], lambda x, _, __: sqrt(3 / (4 * pi)) * x, @@ -88,8 +88,8 @@ def testNormalization(self): ( "l2_mneg2", [ - [0, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan], + [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN')], [1, 0, 0, 0, 0], ], lambda x, y, __: 1 / 2 * sqrt(15 / pi) * x * y, @@ -97,8 +97,8 @@ def testNormalization(self): ( "l2_mneg1", [ - [0, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan], + [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN')], [0, 1, 0, 0, 0], ], lambda _, y, z: 1 / 2 * sqrt(15 / pi) * y * z, @@ -106,8 +106,8 @@ def testNormalization(self): ( "l2_m0", [ - [0, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan], + [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN')], [0, 0, 1, 0, 0], ], lambda x, y, z: 1 @@ -118,8 +118,8 @@ def testNormalization(self): ( "l2_m1", [ - [0, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan], + [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN')], [0, 0, 0, 1, 0], ], lambda x, _, z: 1 / 2 * sqrt(15 / pi) * x * z, @@ -127,8 +127,8 @@ def testNormalization(self): ( "l2_m2", [ - [0, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan], + [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN')], [0, 0, 0, 0, 1], ], lambda x, y, _: 1 / 4 * sqrt(15 / pi) * (x**2 - y**2), @@ -159,8 +159,8 @@ def _gen_naive_grid(n_per_dim): "l0_m0", array( [ - [1, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan], + [1, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN')], [0, 0, 0, 0, 0], ] ), @@ -169,8 +169,8 @@ def _gen_naive_grid(n_per_dim): "l1_mneg1", array( [ - [1, np.nan, np.nan, np.nan, np.nan], - [1, 0, 0, np.nan, np.nan], + [1, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [1, 0, 0, float('NaN'), float('NaN')], [0, 0, 0, 0, 0], ] ), @@ -179,8 +179,8 @@ def _gen_naive_grid(n_per_dim): "l1_m0", array( [ - [1, np.nan, np.nan, np.nan, np.nan], - [0, 1, 0, np.nan, np.nan], + [1, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 1, 0, float('NaN'), float('NaN')], [0, 0, 0, 0, 0], ] ), @@ -189,8 +189,8 @@ def _gen_naive_grid(n_per_dim): "l1_m1", array( [ - [1, np.nan, np.nan, np.nan, np.nan], - [0, 0, 1, np.nan, np.nan], + [1, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 1, float('NaN'), float('NaN')], [0, 0, 0, 0, 0], ] ), @@ -199,8 +199,8 @@ def _gen_naive_grid(n_per_dim): "l2_mneg2", array( [ - [1, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan], + [1, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN')], [1, 0, 0, 0, 0], ] ), @@ -209,8 +209,8 @@ def _gen_naive_grid(n_per_dim): "l2_mneg1", array( [ - [1, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan], + [1, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN')], [0, 1, 0, 0, 0], ] ), @@ -219,8 +219,8 @@ def _gen_naive_grid(n_per_dim): "l2_m0", array( [ - [1, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan], + [1, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN')], [0, 0, 1, 0, 0], ] ), @@ -229,8 +229,8 @@ def _gen_naive_grid(n_per_dim): "l2_m1", array( [ - [1, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan], + [1, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN')], [0, 0, 0, 1, 0], ] ), @@ -239,8 +239,8 @@ def _gen_naive_grid(n_per_dim): "l2_m2", array( [ - [1, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan], + [1, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN')], [0, 0, 0, 0, 1], ] ), @@ -249,9 +249,9 @@ def _gen_naive_grid(n_per_dim): "l3_mneg3", array( [ - [1, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, 0, 0, np.nan, np.nan], + [1, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, 0, 0, float('NaN'), float('NaN')], [1, 0, 0, 0, 0, 0, 0], ] ), @@ -260,9 +260,9 @@ def _gen_naive_grid(n_per_dim): "l3_mneg2", array( [ - [1, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, 0, 0, np.nan, np.nan], + [1, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, 0, 0, float('NaN'), float('NaN')], [0, 1, 0, 0, 0, 0, 0], ] ), @@ -271,9 +271,9 @@ def _gen_naive_grid(n_per_dim): "l3_mneg1", array( [ - [1, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, 0, 0, np.nan, np.nan], + [1, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, 0, 0, float('NaN'), float('NaN')], [0, 0, 1, 0, 0, 0, 0], ] ), @@ -282,9 +282,9 @@ def _gen_naive_grid(n_per_dim): "l3_m0", array( [ - [1, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, 0, 0, np.nan, np.nan], + [1, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, 0, 0, float('NaN'), float('NaN')], [0, 0, 0, 1, 0, 0, 0], ] ), @@ -293,9 +293,9 @@ def _gen_naive_grid(n_per_dim): "l3_m1", array( [ - [1, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, 0, 0, np.nan, np.nan], + [1, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, 0, 0, float('NaN'), float('NaN')], [0, 0, 0, 0, 1, 0, 0], ] ), @@ -304,9 +304,9 @@ def _gen_naive_grid(n_per_dim): "l3_m2", array( [ - [1, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, 0, 0, np.nan, np.nan], + [1, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, 0, 0, float('NaN'), float('NaN')], [0, 0, 0, 0, 0, 1, 0], ] ), @@ -315,9 +315,9 @@ def _gen_naive_grid(n_per_dim): "l3_m3", array( [ - [1, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, np.nan, np.nan, np.nan, np.nan], - [0, 0, 0, 0, 0, np.nan, np.nan], + [1, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0, 0, 0, 0, 0, float('NaN'), float('NaN')], [0, 0, 0, 0, 0, 0, 1], ] ), From 14fcf2c8088d8426760a18e1c81cd7c6e70bd773 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Sat, 21 Oct 2023 12:10:58 +0100 Subject: [PATCH 070/232] More........... --- .../circle/circular_dirac_distribution.py | 2 +- pyrecest/filters/hypertoroidal_particle_filter.py | 2 +- pyrecest/filters/kalman_filter.py | 10 +++------- .../test_spherical_harmonics_distribution_real.py | 5 +++-- 4 files changed, 8 insertions(+), 11 deletions(-) diff --git a/pyrecest/distributions/circle/circular_dirac_distribution.py b/pyrecest/distributions/circle/circular_dirac_distribution.py index 71820fb0..5be161d3 100644 --- a/pyrecest/distributions/circle/circular_dirac_distribution.py +++ b/pyrecest/distributions/circle/circular_dirac_distribution.py @@ -8,7 +8,7 @@ class CircularDiracDistribution( HypertoroidalDiracDistribution, AbstractCircularDistribution ): - def __init__(self, d, w): + def __init__(self, d, w=None): """ Initializes a CircularDiracDistribution instance. diff --git a/pyrecest/filters/hypertoroidal_particle_filter.py b/pyrecest/filters/hypertoroidal_particle_filter.py index 9bc1019f..00daa84d 100644 --- a/pyrecest/filters/hypertoroidal_particle_filter.py +++ b/pyrecest/filters/hypertoroidal_particle_filter.py @@ -37,7 +37,7 @@ def __init__( if dim == 1: # Prevents ambiguities if a vector is of size (dim,) or (n,) (for dim=1) - filter_state = CircularDiracDistribution(linspace(0.0, 2.0 * pi, num = n_particles, endpoint=False) + filter_state = CircularDiracDistribution(linspace(0.0, 2.0 * pi, num = n_particles, endpoint=False)) else: filter_state = HypertoroidalDiracDistribution( tile( diff --git a/pyrecest/filters/kalman_filter.py b/pyrecest/filters/kalman_filter.py index 743b56aa..f7587af7 100644 --- a/pyrecest/filters/kalman_filter.py +++ b/pyrecest/filters/kalman_filter.py @@ -8,9 +8,7 @@ class KalmanFilter(AbstractEuclideanFilter): - def __init__( - self, initial_state: GaussianDistribution | tuple[, ] - ): + def __init__(self, initial_state): """ Initialize the Kalman filter with the initial state. @@ -35,9 +33,7 @@ def filter_state( return GaussianDistribution(self._filter_state.x, self._filter_state.P) @filter_state.setter - def filter_state( - self, new_state: GaussianDistribution | tuple[, ] - ): + def filter_state(self, new_state): """ Set the filter state. @@ -54,7 +50,7 @@ def filter_state( "new_state must be a GaussianDistribution or a tuple of (mean, covariance)" ) - def predict_identity(self, sys_noise_cov, sys_input: = None): + def predict_identity(self, sys_noise_cov, sys_input = None): """ Predicts the next state assuming identity transition matrix. diff --git a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py index 70c65e0c..0375ea26 100644 --- a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py +++ b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py @@ -7,6 +7,7 @@ from pyrecest.backend import allclose from pyrecest.backend import all from pyrecest.backend import zeros +from pyrecest.backend import column_stack import unittest import warnings @@ -36,9 +37,9 @@ def testNormalization(self): self.assertAlmostEqual(shd.integrate(), 1, delta=1e-6) x, y, z = SphericalHarmonicsDistributionRealTest._gen_naive_grid(10) - vals_normalized = shd.pdf(np.column_stack((x, y, z))) + vals_normalized = shd.pdf(column_stack((x, y, z))) shd.coeff_mat = unnormalized_coeffs - vals_unnormalized = shd.pdf(np.column_stack((x, y, z))) + vals_unnormalized = shd.pdf(column_stack((x, y, z))) self.assertTrue( allclose( np.diff(vals_normalized / vals_unnormalized), From 3859fb91980535baf0e39a1a33fec4651dcf1660 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Sat, 21 Oct 2023 13:11:49 +0100 Subject: [PATCH 071/232] More --- pyrecest/_backend/__init__.py | 3 +++ pyrecest/_backend/numpy/__init__.py | 3 +++ pyrecest/_backend/pytorch/__init__.py | 3 +++ .../hypertoroidal_dirac_distribution.py | 9 ++++---- pyrecest/evaluation/evaluate_for_file.py | 17 +++++---------- .../evaluate_for_simulation_config.py | 16 ++++---------- pyrecest/evaluation/generate_groundtruth.py | 15 ++++++------- pyrecest/evaluation/generate_measurements.py | 21 ++++++++++--------- .../generate_simulated_scenarios.py | 8 +++---- .../abstract_nearest_neighbor_tracker.py | 2 +- .../filters/test_global_nearest_neighbor.py | 19 +++++++++-------- pyrecest/tests/filters/test_kalman_filter.py | 15 ++++++------- .../test_toroidal_wrapped_normal_filter.py | 5 +++-- 13 files changed, 67 insertions(+), 69 deletions(-) diff --git a/pyrecest/_backend/__init__.py b/pyrecest/_backend/__init__.py index b45178d2..4a5d678e 100644 --- a/pyrecest/_backend/__init__.py +++ b/pyrecest/_backend/__init__.py @@ -172,6 +172,9 @@ def get_backend_name(): "nonzero", # Added for pyrecest "column_stack", # Added for pyrecest "conj", # Added for pyrecest + "atleast_1d", # Added for pyrecest + "atleast_2d", # Added for pyrecest + "dstack", # Added for pyrecest ], "autodiff": [ "custom_gradient", diff --git a/pyrecest/_backend/numpy/__init__.py b/pyrecest/_backend/numpy/__init__.py index cd865797..3a2fb022 100644 --- a/pyrecest/_backend/numpy/__init__.py +++ b/pyrecest/_backend/numpy/__init__.py @@ -77,6 +77,9 @@ nonzero, # For pyrecest column_stack, # For pyrecest conj, # For pyrecest + atleast_1d, # For pyrecest + atleast_2d, # For pyrecest + dstack, # For pyrecest ) from scipy.special import erf, gamma, polygamma # NOQA diff --git a/pyrecest/_backend/pytorch/__init__.py b/pyrecest/_backend/pytorch/__init__.py index e2465d7b..38b2938a 100644 --- a/pyrecest/_backend/pytorch/__init__.py +++ b/pyrecest/_backend/pytorch/__init__.py @@ -38,6 +38,9 @@ nonzero, # For pyrecest column_stack, # For pyrecest conj, # For pyrecest + atleast_1d, # For pyrecest + atleast_2d, # For pyrecest + dstack, # For pyrecest ) from torch import repeat_interleave as repeat from torch import ( diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py b/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py index fa263620..28ea3745 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py @@ -9,6 +9,7 @@ from pyrecest.backend import exp from pyrecest.backend import arctan2 from pyrecest.backend import int64 +from pyrecest.backend import atleast_1d from pyrecest.backend import int32 import copy from collections.abc import Callable @@ -30,14 +31,12 @@ def __init__( if dim is None: if d.ndim > 1: dim = d.shape[-1] - elif w is not None: - dim = np.size(d) // np.size(w) else: - raise ValueError("Cannot determine dimension.") + raise ValueError("Cannot automatically determine dimension.") AbstractHypertoroidalDistribution.__init__(self, dim) AbstractDiracDistribution.__init__( - self, np.atleast_1d(mod(d, 2 * pi)), w=w + self, atleast_1d(mod(d, 2.0 * pi)), w=w ) def plot(self, *args, **kwargs): @@ -51,7 +50,7 @@ def mean_direction(self): :return: Mean direction """ a = self.trigonometric_moment(1) - m = mod(arctan2(imag(a), real(a)), 2 * pi) + m = mod(arctan2(imag(a), real(a)), 2.0 * pi) return m def trigonometric_moment(self, n: Union[int, int32, int64]): diff --git a/pyrecest/evaluation/evaluate_for_file.py b/pyrecest/evaluation/evaluate_for_file.py index 6aa6656f..67f85f89 100644 --- a/pyrecest/evaluation/evaluate_for_file.py +++ b/pyrecest/evaluation/evaluate_for_file.py @@ -1,6 +1,7 @@ -from pyrecest.backend import ones -from pyrecest.backend import concatenate -from pyrecest.backend import zeros +from numpy import ones +from numpy import concatenate +from numpy import zeros +import numpy as np import os from typing import Any @@ -22,15 +23,7 @@ def evaluate_for_file( tolerate_failure: bool = False, auto_warning_on_off: bool = False, # jscpd:ignore-end -) -> tuple[ - dict, - list[dict], - , - , - , - , - [], -]: + ): data = np.load(input_file_name, allow_pickle=True).item() if "name" not in scenario_config: diff --git a/pyrecest/evaluation/evaluate_for_simulation_config.py b/pyrecest/evaluation/evaluate_for_simulation_config.py index 9f37729c..6b9972c7 100644 --- a/pyrecest/evaluation/evaluate_for_simulation_config.py +++ b/pyrecest/evaluation/evaluate_for_simulation_config.py @@ -16,7 +16,7 @@ def evaluate_for_simulation_config( filter_configs: list[dict[str, Any]], n_runs: int, n_timesteps: Optional[int] = None, - initial_seed: Optional[int | np.uint32] = None, + initial_seed=None, consecutive_seed: bool = False, save_folder: str = ".", scenario_customization_params: Optional[dict] = None, @@ -26,15 +26,7 @@ def evaluate_for_simulation_config( tolerate_failure: bool = False, auto_warning_on_off: bool = False, # jscpd:ignore-end -) -> tuple[ - dict, - list[dict], - , - , - , - , - [], -]: +): if isinstance(simulation_config, str): simulation_name = simulation_config simulation_config = simulation_database( @@ -74,9 +66,9 @@ def get_all_seeds(n_runs: int, seed_input=None, consecutive_seed: bool = True): if seed_input is None: seed_input = np.uint32(random.randint(1, 0xFFFFFFFF)) # nosec - if np.size(seed_input) == n_runs: + if seed_input.shape[0] == n_runs: all_seeds = seed_input - elif np.size(seed_input) == 1 and n_runs > 1: + elif seed_input.shape[0] == 1 and n_runs > 1: if consecutive_seed: all_seeds = list(range(seed_input, seed_input + n_runs)) else: diff --git a/pyrecest/evaluation/generate_groundtruth.py b/pyrecest/evaluation/generate_groundtruth.py index edade1d8..4da7193b 100644 --- a/pyrecest/evaluation/generate_groundtruth.py +++ b/pyrecest/evaluation/generate_groundtruth.py @@ -1,8 +1,9 @@ -from pyrecest.backend import squeeze -from pyrecest.backend import ndim -from pyrecest.backend import empty -from pyrecest.backend import empty_like - +from numpy import squeeze +from numpy import ndim +from numpy import empty +from numpy import empty_like +from numpy import atleast_2d +import numpy as np # pylint: disable=too-many-branches @@ -29,14 +30,14 @@ def generate_groundtruth(simulation_param, x0=None): ), "Mismatch in number of targets." # Initialize ground truth - groundtruth = empty(simulation_param["n_timesteps"], dtype=) + groundtruth = empty(simulation_param["n_timesteps"], dtype=np.ndarray) if "inputs" in simulation_param: assert ( simulation_param["inputs"].shape[1] == simulation_param["n_timesteps"] - 1 ), "Mismatch in number of timesteps." - groundtruth[0] = np.atleast_2d(x0) + groundtruth[0] = atleast_2d(x0) for t in range(1, simulation_param["n_timesteps"]): groundtruth[t] = empty_like(groundtruth[0]) diff --git a/pyrecest/evaluation/generate_measurements.py b/pyrecest/evaluation/generate_measurements.py index a89aa55c..440734b8 100644 --- a/pyrecest/evaluation/generate_measurements.py +++ b/pyrecest/evaluation/generate_measurements.py @@ -1,13 +1,14 @@ from math import pi -from pyrecest.backend import random -from pyrecest.backend import tile -from pyrecest.backend import sum -from pyrecest.backend import squeeze -from pyrecest.backend import shape -from pyrecest.backend import mod -from pyrecest.backend import dot -from pyrecest.backend import empty -from pyrecest.backend import zeros +from numpy import random +from numpy import tile +from numpy import sum +from numpy import squeeze +from numpy import shape +from numpy import mod +from numpy import dot +from numpy import empty +from numpy import zeros +import numpy as np from beartype import beartype from pyrecest.distributions import ( @@ -40,7 +41,7 @@ def generate_measurements(groundtruth, simulation_config): assert "n_meas_at_individual_time_step" not in simulation_config or shape( simulation_config["n_meas_at_individual_time_step"] ) == (simulation_config["n_timesteps"],) - measurements = empty(simulation_config["n_timesteps"], dtype=) + measurements = empty(simulation_config["n_timesteps"], dtype=np.ndarray) if simulation_config.get("mtt", False) and simulation_config.get("eot", False): raise NotImplementedError( diff --git a/pyrecest/evaluation/generate_simulated_scenarios.py b/pyrecest/evaluation/generate_simulated_scenarios.py index 44662bae..c372cd11 100644 --- a/pyrecest/evaluation/generate_simulated_scenarios.py +++ b/pyrecest/evaluation/generate_simulated_scenarios.py @@ -1,5 +1,5 @@ -from pyrecest.backend import random -from pyrecest.backend import empty +from numpy import random, empty +import numpy as np from .check_and_fix_config import check_and_fix_config @@ -25,11 +25,11 @@ def generate_simulated_scenarios( groundtruths = empty( (np.size(simulation_params["all_seeds"]), simulation_params["n_timesteps"]), - dtype=, + dtype=np.ndarray, ) measurements = empty( (np.size(simulation_params["all_seeds"]), simulation_params["n_timesteps"]), - dtype=, + dtype=np.ndarray, ) for run, seed in enumerate(simulation_params["all_seeds"]): diff --git a/pyrecest/filters/abstract_nearest_neighbor_tracker.py b/pyrecest/filters/abstract_nearest_neighbor_tracker.py index 8d3dd354..788e6a87 100644 --- a/pyrecest/filters/abstract_nearest_neighbor_tracker.py +++ b/pyrecest/filters/abstract_nearest_neighbor_tracker.py @@ -88,7 +88,7 @@ def predict_linear(self, system_matrices, sys_noises, inputs=None): if isinstance(sys_noises, GaussianDistribution): assert all(sys_noises.mu == 0) - sys_noises = np.dstack(sys_noises.C) + sys_noises = dstack(sys_noises.C) curr_sys_matrix = system_matrices curr_sys_noise = sys_noises diff --git a/pyrecest/tests/filters/test_global_nearest_neighbor.py b/pyrecest/tests/filters/test_global_nearest_neighbor.py index 426d6f71..6e746578 100644 --- a/pyrecest/tests/filters/test_global_nearest_neighbor.py +++ b/pyrecest/tests/filters/test_global_nearest_neighbor.py @@ -6,6 +6,7 @@ from pyrecest.backend import all from pyrecest.backend import zeros from pyrecest.backend import diag +from pyrecest.backend import dstack import pyrecest.backend import unittest @@ -33,14 +34,14 @@ def setUp(self): ] self.meas_mat = array([[1.0, 0.0, 0.0, 0.0], [0.0, 0.0, 1.0, 0.0]]) self.sys_mat = array(scipy.linalg.block_diag(array([[1.0, 1.0], [0.0, 1.0]]), array([[1.0, 1.0], [0.0, 1.0]]))) - self.all_different_meas_covs = np.dstack( + self.all_different_meas_covs = dstack( [ diag(array([1.0, 2.0])), array([[5.0, 0.1], [0.1, 3.0]]), array([[2.0, -0.5], [-0.5, 0.5]]), ] ) - self.all_different_meas_covs_4 = np.dstack( + self.all_different_meas_covs_4 = dstack( (self.all_different_meas_covs, array([[2.0, -0.5], [-0.5, 0.5]])) ) @@ -93,14 +94,14 @@ def test_predict_linear_different_mats_and_inputs(self): tracker = GlobalNearestNeighbor() tracker.filter_state = self.kfs_init - sys_mats = np.dstack( + sys_mats = dstack( ( scipy.linalg.block_diag([[1.0, 1.0], [0.0, 1.0]], [[1.0, 1.0], [0.0, 1.0]]), eye(4), array([[0.0, 0.0, 1.0, 1.0], [0.0, 0.0, 0.0, 1.0], [1.0, 1.0, 0.0, 0.0], [0.0, 1.0, 0.0, 0.0]]), ) ) - sys_noises = np.dstack( + sys_noises = dstack( (eye(4), diag([10.0, 11.0, 12.0, 13.0]), diag([1.0, 5.0, 3.0, 5.0])) ) sys_inputs = array([[-1.0, 1.0, -1.0, 1.0], [1.0, 2.0, 3.0, 4.0], -array([4.0, 3.0, 2.0, 1.0])]).T @@ -232,9 +233,9 @@ def test_update_with_and_without_clutter(self): [dist.mu for dist in all_gaussians], ) ) - curr_covs = np.dstack([dist.C for dist in tracker_no_clut.filter_state]) + curr_covs = dstack([dist.C for dist in tracker_no_clut.filter_state]) self.assertTrue( - all(curr_covs <= np.dstack([dist.C for dist in all_gaussians])) + all(curr_covs <= dstack([dist.C for dist in all_gaussians])) ) measurements_clut = np.column_stack( @@ -256,7 +257,7 @@ def test_update_with_and_without_clutter(self): ) ) previous_covs = curr_covs - curr_covs = np.dstack([dist.C for dist in tracker_no_clut.filter_state]) + curr_covs = dstack([dist.C for dist in tracker_no_clut.filter_state]) self.assertTrue(all(curr_covs <= previous_covs)) measurements_clut = np.column_stack( @@ -278,7 +279,7 @@ def test_update_with_and_without_clutter(self): curr_means = [dist.mu for dist in tracker_no_clut.filter_state] self.assertFalse(allclose(curr_means, [dist.mu for dist in all_gaussians])) previous_covs = curr_covs - curr_covs = np.dstack([dist.C for dist in tracker_no_clut.filter_state]) + curr_covs = dstack([dist.C for dist in tracker_no_clut.filter_state]) self.assertTrue(all(curr_covs <= previous_covs)) measurements_clut += 0.1 @@ -299,7 +300,7 @@ def test_update_with_and_without_clutter(self): ) ) previous_covs = curr_covs - curr_covs = np.dstack([dist.C for dist in tracker_no_clut.filter_state]) + curr_covs = dstack([dist.C for dist in tracker_no_clut.filter_state]) for i in range(curr_covs.shape[2]): self.assertTrue( all( diff --git a/pyrecest/tests/filters/test_kalman_filter.py b/pyrecest/tests/filters/test_kalman_filter.py index 3c425ba2..e023d84a 100644 --- a/pyrecest/tests/filters/test_kalman_filter.py +++ b/pyrecest/tests/filters/test_kalman_filter.py @@ -3,6 +3,7 @@ from pyrecest.backend import array from pyrecest.backend import allclose from pyrecest.backend import all +import numpy.testing as npt import copy import unittest @@ -14,24 +15,24 @@ class KalmanFilterTest(unittest.TestCase): def test_initialization_mean_cov(self): filter_custom = KalmanFilter((array([1]), array([[10000]]))) - self.assertEqual(filter_custom.get_point_estimate(), [1]) + npt.assert_equal(filter_custom.get_point_estimate(), array([1])) def test_initialization_gauss(self): filter_custom = KalmanFilter( initial_state=GaussianDistribution(array([4]), array([[10000]])) ) - self.assertEqual(filter_custom.get_point_estimate(), [4]) + npt.assert_equal(filter_custom.get_point_estimate(), array([4])) def test_update_with_likelihood_1d(self): kf = KalmanFilter((array([0]), array([[1]]))) kf.update_identity(array(1), array(3)) - self.assertEqual(kf.get_point_estimate(), 1.5) + npt.assert_equal(kf.get_point_estimate(), 1.5) def test_update_with_meas_noise_and_meas_1d(self): kf = KalmanFilter((array([0]), array([[1]]))) kf.update_identity(array(1), array(4)) - self.assertEqual(kf.filter_state.C, 0.5) - self.assertEqual(kf.get_point_estimate(), 2) + npt.assert_equal(kf.filter_state.C, 0.5) + npt.assert_equal(kf.get_point_estimate(), 2) def test_update_linear_2d(self): filter_add = KalmanFilter((array([0, 1]), diag([1, 2]))) @@ -49,8 +50,8 @@ def test_update_linear_2d(self): def test_predict_identity_1d(self): kf = KalmanFilter((array([0]), array([[1]]))) kf.predict_identity(array([[3]]), array([1])) - self.assertEqual(kf.get_point_estimate(), 1) - self.assertEqual(kf.filter_state.C, 4) + npt.assert_equal(kf.get_point_estimate(), array(1)) + npt.assert_equal(kf.filter_state.C, array(4)) def test_predict_linear_2d(self): kf = KalmanFilter((array([0, 1]), diag([1, 2]))) diff --git a/pyrecest/tests/filters/test_toroidal_wrapped_normal_filter.py b/pyrecest/tests/filters/test_toroidal_wrapped_normal_filter.py index a4d5ea22..9a0f44aa 100644 --- a/pyrecest/tests/filters/test_toroidal_wrapped_normal_filter.py +++ b/pyrecest/tests/filters/test_toroidal_wrapped_normal_filter.py @@ -2,6 +2,7 @@ from pyrecest.backend import mod from pyrecest.backend import array import unittest +import numpy as np from pyrecest.distributions.hypertorus.toroidal_wrapped_normal_distribution import ( @@ -13,8 +14,8 @@ class ToroidalWrappedNormalFilterTest(unittest.TestCase): def setUp(self): """Initial setup for each test.""" - self.mu = array([5, 2.5]) - self.C = array([[1.3, 1.4], [1.4, 2]]) + self.mu = array([5.0, 2.5]) + self.C = array([[1.3, 1.4], [1.4, 2.0]]) self.twn = ToroidalWrappedNormalDistribution(self.mu, self.C) def test_sanity_check(self): From 84caa99d6084a8f2e2c2a0951b8a5c4a14d173ed Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Sat, 21 Oct 2023 21:39:57 +0100 Subject: [PATCH 072/232] More...... --- pyrecest/_backend/__init__.py | 1 + pyrecest/_backend/numpy/__init__.py | 1 + pyrecest/_backend/pytorch/__init__.py | 1 + .../abstract_se3_distribution.py | 3 +- .../abstract_hypercylindrical_distribution.py | 8 ++-- .../hypercylindrical_dirac_distribution.py | 3 +- .../partially_wrapped_normal_distribution.py | 3 +- .../circle/circular_fourier_distribution.py | 2 +- ...bstract_hypersphere_subset_distribution.py | 9 +++-- ...stract_spherical_harmonics_distribution.py | 6 ++- ...pherical_harmonics_distribution_complex.py | 14 ++++--- .../spherical_harmonics_distribution_real.py | 6 ++- .../hypersphere_subset/watson_distribution.py | 3 +- ...pertoroidal_wrapped_normal_distribution.py | 4 +- .../abstract_linear_distribution.py | 8 ++-- .../perform_predict_update_cycles.py | 3 +- pyrecest/filters/abstract_particle_filter.py | 4 +- .../filters/abstract_tracker_with_logging.py | 3 +- pyrecest/filters/global_nearest_neighbor.py | 3 +- .../filters/hypertoroidal_particle_filter.py | 4 +- pyrecest/sampling/hyperspherical_sampler.py | 2 +- ..._abstract_hypercylindrical_distribution.py | 18 +++++---- ...st_custom_hyperrectangular_distribution.py | 3 +- .../distributions/test_linear_mixture.py | 3 +- ...pherical_harmonics_distribution_complex.py | 38 ++++++++++--------- ...t_spherical_harmonics_distribution_real.py | 9 +++-- ...st_toroidal_von_mises_sine_distribution.py | 3 +- .../filters/test_global_nearest_neighbor.py | 13 ++++--- .../test_hypertoroidal_particle_filter.py | 3 +- pyrecest/tests/test_evaluation_basic.py | 3 +- pyrecest/tests/test_hypertoroidal_sampler.py | 3 +- pyrecest/utils/plotting.py | 3 +- 32 files changed, 114 insertions(+), 76 deletions(-) diff --git a/pyrecest/_backend/__init__.py b/pyrecest/_backend/__init__.py index 4a5d678e..62613e8b 100644 --- a/pyrecest/_backend/__init__.py +++ b/pyrecest/_backend/__init__.py @@ -175,6 +175,7 @@ def get_backend_name(): "atleast_1d", # Added for pyrecest "atleast_2d", # Added for pyrecest "dstack", # Added for pyrecest + "full", # Added for pyrecest ], "autodiff": [ "custom_gradient", diff --git a/pyrecest/_backend/numpy/__init__.py b/pyrecest/_backend/numpy/__init__.py index 3a2fb022..68aa655a 100644 --- a/pyrecest/_backend/numpy/__init__.py +++ b/pyrecest/_backend/numpy/__init__.py @@ -80,6 +80,7 @@ atleast_1d, # For pyrecest atleast_2d, # For pyrecest dstack, # For pyrecest + full, # For pyrecest ) from scipy.special import erf, gamma, polygamma # NOQA diff --git a/pyrecest/_backend/pytorch/__init__.py b/pyrecest/_backend/pytorch/__init__.py index 38b2938a..b43f91c0 100644 --- a/pyrecest/_backend/pytorch/__init__.py +++ b/pyrecest/_backend/pytorch/__init__.py @@ -41,6 +41,7 @@ atleast_1d, # For pyrecest atleast_2d, # For pyrecest dstack, # For pyrecest + full, # For pyrecest ) from torch import repeat_interleave as repeat from torch import ( diff --git a/pyrecest/distributions/abstract_se3_distribution.py b/pyrecest/distributions/abstract_se3_distribution.py index 6b7db59b..af4fffa3 100644 --- a/pyrecest/distributions/abstract_se3_distribution.py +++ b/pyrecest/distributions/abstract_se3_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import column_stack from typing import Union from pyrecest.backend import concatenate from pyrecest.backend import int64 @@ -73,7 +74,7 @@ def plot_point(se3point): # pylint: disable=too-many-locals ) h = [h1, h2, h3] relevant_coords = concatenate((pos.reshape(-1, 1), pos + rotMat), axis=1) - needed_boundaries = np.column_stack( + needed_boundaries = column_stack( (np.min(relevant_coords, axis=1), np.max(relevant_coords, axis=1)) ) diff --git a/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py b/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py index 8e304698..c433b170 100644 --- a/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py +++ b/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py @@ -1,3 +1,5 @@ +from pyrecest.backend import full +from pyrecest.backend import column_stack from math import pi from typing import Union from pyrecest.backend import vstack @@ -95,7 +97,7 @@ def linear_covariance(self, approximate_mean=None): The linear covariance. """ if approximate_mean is None: - approximate_mean = np.full((self.lin_dim,), float('NaN')) + approximate_mean = full((self.lin_dim,), float('NaN')) assert approximate_mean.shape[0] == self.lin_dim @@ -169,7 +171,7 @@ def condition_on_linear(self, input_lin, normalize=True): def f_cond_unnorm(x, input_lin=input_lin): n_inputs = np.size(x) // x.shape[-1] if ndim(x) > 1 else x.shape[0] input_repeated = tile(input_lin, (n_inputs, 1)) - return self.pdf(np.column_stack((x, input_repeated))) + return self.pdf(column_stack((x, input_repeated))) dist = CustomHypertoroidalDistribution(f_cond_unnorm, self.bound_dim) @@ -201,7 +203,7 @@ def condition_on_periodic(self, input_periodic, normalize=True): def f_cond_unnorm(x, input_periodic=input_periodic): n_inputs = np.size(x) // x.shape[-1] if ndim(x) > 1 else np.size(x) input_repeated = tile(input_periodic, (n_inputs, 1)) - return self.pdf(np.column_stack((input_repeated, x))) + return self.pdf(column_stack((input_repeated, x))) dist = CustomLinearDistribution(f_cond_unnorm, self.lin_dim) diff --git a/pyrecest/distributions/cart_prod/hypercylindrical_dirac_distribution.py b/pyrecest/distributions/cart_prod/hypercylindrical_dirac_distribution.py index 8da75262..d9afafe6 100644 --- a/pyrecest/distributions/cart_prod/hypercylindrical_dirac_distribution.py +++ b/pyrecest/distributions/cart_prod/hypercylindrical_dirac_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import full from typing import Union from pyrecest.backend import tile from pyrecest.backend import sum @@ -36,7 +37,7 @@ def marginalize_linear(self): def hybrid_moment(self): # Specific for Cartesian products of hypertori and R^lin_dim - S = np.full((self.bound_dim * 2 + self.lin_dim, self.d.shape[0]), float('NaN')) + S = full((self.bound_dim * 2 + self.lin_dim, self.d.shape[0]), float('NaN')) S[2 * self.bound_dim :, :] = self.d[:, self.bound_dim :].T # noqa: E203 for i in range(self.bound_dim): diff --git a/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py b/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py index 7fc2f0fd..04f60834 100644 --- a/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py +++ b/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import atleast_2d from pyrecest.backend import linalg from math import pi from pyrecest.backend import random @@ -54,7 +55,7 @@ def __init__( self.C = C def pdf(self, xs, m: Union[int, int32, int64] = 3): - xs = np.atleast_2d(xs) + xs = atleast_2d(xs) if self.bound_dim > 0: xs[:, : self.bound_dim] = mod(xs[:, : self.bound_dim], 2 * pi) diff --git a/pyrecest/distributions/circle/circular_fourier_distribution.py b/pyrecest/distributions/circle/circular_fourier_distribution.py index 1e2e5dce..45fc901d 100644 --- a/pyrecest/distributions/circle/circular_fourier_distribution.py +++ b/pyrecest/distributions/circle/circular_fourier_distribution.py @@ -298,7 +298,7 @@ def from_distribution( ) -> "CircularFourierDistribution": if isinstance(distribution, CircularDiracDistribution): fd = CircularFourierDistribution( - np.conj(distribution.trigonometric_moment(n, whole_range=True)) + conj(distribution.trigonometric_moment(n, whole_range=True)) / (2.0 * pi), transformation, multiplied_by_n=False, diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py index c45ae9bd..ed4084e0 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py @@ -1,3 +1,6 @@ +from pyrecest.backend import full +from pyrecest.backend import atleast_2d +from pyrecest.backend import column_stack from pyrecest.backend import linalg from math import pi from typing import Union @@ -97,7 +100,7 @@ def gen_pdf_hyperspherical_coords(self): def gen_fun_hyperspherical_coords(f: Callable, dim: Union[int, int32, int64]): def generate_input(angles): dim_eucl = dim + 1 - angles = np.column_stack(angles) + angles = column_stack(angles) input_arr = zeros((angles.shape[0], dim_eucl)) # Start at last, which is just cos input_arr[:, -1] = cos(angles[:, -1]) @@ -121,7 +124,7 @@ def moment(self): return self.moment_numerical() def moment_numerical(self): - m = np.full( + m = full( ( self.dim + 1, self.dim + 1, @@ -343,7 +346,7 @@ def total_variation_distance(pdf1, pdf2): @staticmethod def polar_to_cart(polar_coords): - polar_coords = np.atleast_2d(polar_coords) + polar_coords = atleast_2d(polar_coords) coords = zeros( ( diff --git a/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py index bb3fd619..09160d65 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import full from math import pi from pyrecest.backend import sqrt from pyrecest.backend import real @@ -6,6 +7,7 @@ from pyrecest.backend import array from pyrecest.backend import abs from pyrecest.backend import zeros +from pyrecest.backend import atleast_2d import copy import warnings @@ -21,7 +23,7 @@ class AbstractSphericalHarmonicsDistribution( ): def __init__(self, coeff_mat, transformation="identity"): AbstractSphericalDistribution.__init__(self) - coeff_mat = np.atleast_2d(coeff_mat) + coeff_mat = atleast_2d(coeff_mat) assert ( coeff_mat.shape[1] == coeff_mat.shape[0] * 2 - 1 ), "CoefficientMatrix:Size, Dimensions of coefficient Matrix are incompatible." @@ -33,7 +35,7 @@ def __init__(self, coeff_mat, transformation="identity"): [ zeros((n - 1, 1)), np.kron( - np.triu(np.full((n - 1, n - 1), float('NaN'))), array([[1, 1]]) + np.triu(full((n - 1, n - 1), float('NaN'))), array([[1, 1]]) ), ], [zeros((1, 2 * n - 1))], diff --git a/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py b/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py index 83ee2f06..d79ca422 100644 --- a/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py +++ b/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py @@ -1,3 +1,7 @@ +from pyrecest.backend import full +from pyrecest.backend import atleast_2d +from pyrecest.backend import conj +from pyrecest.backend import column_stack from pyrecest.backend import linalg from math import pi from pyrecest.backend import sqrt @@ -33,7 +37,7 @@ def __init__(self, coeff_mat, transformation="identity", assert_real=True): self.assert_real = assert_real def value(self, xs): - xs = np.atleast_2d(xs) + xs = atleast_2d(xs) phi, theta = AbstractSphereSubsetDistribution.cart_to_sph( xs[:, 0], xs[:, 1], xs[:, 2] ) @@ -130,7 +134,7 @@ def fun_sph(phi, theta): x, y, z = AbstractSphericalDistribution.sph_to_cart( np.ravel(phi), np.ravel(theta) ) - vals = fun_cart(np.column_stack((x, y, z))) + vals = fun_cart(column_stack((x, y, z))) return reshape(vals, shape(theta)) return fun_sph @@ -152,19 +156,19 @@ def from_function_via_integral_sph(fun, degree, transformation="identity"): else: raise ValueError("Transformation not supported") - coeff_mat = np.full((degree + 1, 2 * degree + 1), float('NaN'), dtype=complex) + coeff_mat = full((degree + 1, 2 * degree + 1), float('NaN'), dtype=complex) def real_part(phi, theta, n, m): return real( fun_with_trans(array(phi), array(theta)) - * np.conj(sph_harm(m, n, phi, theta)) + * conj(sph_harm(m, n, phi, theta)) * sin(theta) ) def imag_part(phi, theta, n, m): return imag( fun_with_trans(array(phi), array(theta)) - * np.conj(sph_harm(m, n, phi, theta)) + * conj(sph_harm(m, n, phi, theta)) * sin(theta) ) diff --git a/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_real.py b/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_real.py index 9806eda3..c180d787 100644 --- a/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_real.py +++ b/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_real.py @@ -1,3 +1,5 @@ +from pyrecest.backend import full +from pyrecest.backend import atleast_2d from pyrecest.backend import sqrt from pyrecest.backend import real from pyrecest.backend import imag @@ -34,7 +36,7 @@ def real_spherical_harmonic_basis_function(n, m, theta, phi): return y_nm_real def value(self, xs): - xs = np.atleast_2d(xs) + xs = atleast_2d(xs) vals = zeros(xs.shape[0]) phi, theta = AbstractSphereSubsetDistribution.cart_to_sph( xs[:, 0], xs[:, 1], xs[:, 2] @@ -59,7 +61,7 @@ def to_spherical_harmonics_distribution_complex(self): raise NotImplementedError("Transformation currently not supported") real_coeff_mat = self.coeff_mat - complex_coeff_mat = np.full_like(real_coeff_mat, float('NaN'), dtype=complex) + complex_coeff_mat = full_like(real_coeff_mat, float('NaN'), dtype=complex) for n in range(real_coeff_mat.shape[0]): for m in range(-n, n + 1): diff --git a/pyrecest/distributions/hypersphere_subset/watson_distribution.py b/pyrecest/distributions/hypersphere_subset/watson_distribution.py index 62865a8e..1f6c66cd 100644 --- a/pyrecest/distributions/hypersphere_subset/watson_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/watson_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import full from pyrecest.backend import linalg from pyrecest.backend import vstack from pyrecest.backend import tile @@ -71,7 +72,7 @@ def to_bingham(self) -> BinghamDistribution: M = M + E Q, _ = qr(M) M = hstack([Q[:, 1:], Q[:, 0].reshape(-1, 1)]) - Z = hstack([np.full((self.dim), -self.kappa), 0]) + Z = hstack([full((self.dim), -self.kappa), 0]) return BinghamDistribution(Z, M) def sample(self, n): diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py b/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py index ff257f4f..b873bfe7 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py @@ -55,13 +55,13 @@ def pdf(self, xs, m: Union[int, int32, int64] = 3): xs = reshape(xs, (-1, self.dim)) # Generate all combinations of offsets for each dimension - offsets = [arange(-m, m + 1) * 2 * pi for _ in range(self.dim)] + offsets = [arange(-m, m + 1) * 2.0 * pi for _ in range(self.dim)] offset_combinations = array(meshgrid(*offsets)).T.reshape(-1, self.dim) # Calculate the PDF values by considering all combinations of offsets pdf_values = zeros(xs.shape[0]) for offset in offset_combinations: - shifted_xa = xs + offset[np.newaxis, :] + shifted_xa = xs + offset[None, :] pdf_values += multivariate_normal.pdf( shifted_xa, mean=self.mu.flatten(), cov=self.C ) diff --git a/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py b/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py index e49580af..1303ff52 100644 --- a/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py +++ b/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py @@ -1,3 +1,5 @@ +from pyrecest.backend import full +from pyrecest.backend import atleast_1d from pyrecest.backend import random from typing import Union from pyrecest.backend import squeeze @@ -54,7 +56,7 @@ def neg_pdf(x): return -self.pdf(x) assert ndim(starting_point) <= 1, "Starting point must be a 1D array" - starting_point = np.atleast_1d( + starting_point = atleast_1d( starting_point ) # Avoid numpy warning "DeprecationWarning: Use of `minimize` with `x0.ndim != 1` is deprecated" @@ -215,8 +217,8 @@ def get_suggested_integration_limits(self, scaling_factor=10): """ C = self.covariance() m = self.mode() - left = np.full((self.dim,), float('NaN')) - right = np.full((self.dim,), float('NaN')) + left = full((self.dim,), float('NaN')) + right = full((self.dim,), float('NaN')) for i in range(self.dim): # Change for linear dimensions left[i] = m[i] - scaling_factor * sqrt(C[i, i]) diff --git a/pyrecest/evaluation/perform_predict_update_cycles.py b/pyrecest/evaluation/perform_predict_update_cycles.py index fe667ffe..ef255d5b 100644 --- a/pyrecest/evaluation/perform_predict_update_cycles.py +++ b/pyrecest/evaluation/perform_predict_update_cycles.py @@ -1,3 +1,4 @@ +from pyrecest.backend import atleast_2d from pyrecest.backend import squeeze from pyrecest.backend import array from pyrecest.backend import empty @@ -52,7 +53,7 @@ def perform_predict_update_cycles( if perform_cumulative_updates: raise NotImplementedError("Cumulative updates not implemented yet.") - all_meas_curr_time_step = np.atleast_2d(measurements[t]) + all_meas_curr_time_step = atleast_2d(measurements[t]) n_updates = all_meas_curr_time_step.shape[0] for m in range(n_updates): curr_meas = all_meas_curr_time_step[m, :] diff --git a/pyrecest/filters/abstract_particle_filter.py b/pyrecest/filters/abstract_particle_filter.py index 02f34475..dcda19fd 100644 --- a/pyrecest/filters/abstract_particle_filter.py +++ b/pyrecest/filters/abstract_particle_filter.py @@ -41,7 +41,7 @@ def predict_nonlinear( if noise_distribution is not None: if not shift_instead_of_add: - noise = noise_distribution.sample(self.filter_state.w.size) + noise = noise_distribution.sample(self.filter_state.w.shape[0]) self.filter_state.d = self.filter_state.d + noise else: for i in range(self.filter_state.d.shape[1]): @@ -65,7 +65,7 @@ def predict_nonlinear_nonadditive(self, f, samples, weights): def update_identity( self, meas_noise, measurement, shift_instead_of_add: bool = True ): - assert measurement is None or np.size(measurement) == meas_noise.dim + assert measurement is None or measurement.shape == (meas_noise.dim,) assert ( ndim(measurement) == 1 or ndim(measurement) == 0 diff --git a/pyrecest/filters/abstract_tracker_with_logging.py b/pyrecest/filters/abstract_tracker_with_logging.py index 3a0a749b..1ee868d0 100644 --- a/pyrecest/filters/abstract_tracker_with_logging.py +++ b/pyrecest/filters/abstract_tracker_with_logging.py @@ -1,3 +1,4 @@ +from pyrecest.backend import full from pyrecest.backend import hstack from pyrecest.backend import array from abc import ABC @@ -28,7 +29,7 @@ def _store_estimates(self, curr_ests, estimates_over_time): ) estimates_over_time = hstack((estimates_over_time, curr_ests)) else: - estimates_over_time_new = np.full((n, t + 1), float('NaN')) + estimates_over_time_new = full((n, t + 1), float('NaN')) estimates_over_time_new[:m, :t] = estimates_over_time estimates_over_time_new[:, -1] = curr_ests.flatten() estimates_over_time = estimates_over_time_new diff --git a/pyrecest/filters/global_nearest_neighbor.py b/pyrecest/filters/global_nearest_neighbor.py index 0e84c805..ebc05666 100644 --- a/pyrecest/filters/global_nearest_neighbor.py +++ b/pyrecest/filters/global_nearest_neighbor.py @@ -1,3 +1,4 @@ +from pyrecest.backend import full from pyrecest.backend import stack from pyrecest.backend import squeeze from pyrecest.backend import repeat @@ -136,7 +137,7 @@ def find_association( # Pad to square and add max_new_tracks rows and columns pad_to = max(n_targets, n_meas) + self.association_param["max_new_tracks"] - association_matrix = np.full( + association_matrix = full( (pad_to, pad_to), self.association_param["gating_distance_threshold"] ) association_matrix[: dists.shape[0], : dists.shape[1]] = dists diff --git a/pyrecest/filters/hypertoroidal_particle_filter.py b/pyrecest/filters/hypertoroidal_particle_filter.py index 00daa84d..ec9a36f5 100644 --- a/pyrecest/filters/hypertoroidal_particle_filter.py +++ b/pyrecest/filters/hypertoroidal_particle_filter.py @@ -69,14 +69,14 @@ def predict_nonlinear( self.filter_state.d = self.filter_state.apply_function(f) if noise_distribution is not None: - noise = noise_distribution.sample(self.filter_state.w.size) + noise = noise_distribution.sample(self.filter_state.w.shape[0]) self.filter_state.d += noise.squeeze() self.filter_state.d = mod(self.filter_state.d, 2.0 * pi) def predict_nonlinear_nonadditive( self, f: Callable, samples, weights): assert ( - samples.shape[0] == weights.size + samples.shape == weights.size ), "samples and weights must match in size" weights /= sum(weights) diff --git a/pyrecest/sampling/hyperspherical_sampler.py b/pyrecest/sampling/hyperspherical_sampler.py index 7f379cf0..450df534 100644 --- a/pyrecest/sampling/hyperspherical_sampler.py +++ b/pyrecest/sampling/hyperspherical_sampler.py @@ -238,7 +238,7 @@ def get_grid(self, grid_density_parameter: int | list[int]): phi, theta, _ = spherical_sampler.get_grid_spherical_coordinates( grid_density_parameter[0] ) - spherical_points = np.column_stack( + spherical_points = column_stack( (theta, phi) ) # stack to match expected shape diff --git a/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py b/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py index 1cd6b62d..d58cf48d 100644 --- a/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py @@ -1,3 +1,5 @@ +from pyrecest.backend import column_stack +from pyrecest.backend import diff from math import pi from pyrecest.backend import ones from pyrecest.backend import array @@ -35,8 +37,8 @@ def test_condition_on_periodic(self): dist_cond1 = hwn.condition_on_periodic(array(1.5)) # There is some normalization constant involved, therefore, test if ratio stays the same np.testing.assert_allclose( - np.diff( - hwn.pdf(np.column_stack([1.5 * ones(11), arange(-5, 6)])) + diff( + hwn.pdf(column_stack([1.5 * ones(11), arange(-5, 6)])) / dist_cond1.pdf(arange(-5, 6)) ), zeros(10), @@ -44,8 +46,8 @@ def test_condition_on_periodic(self): ) dist_cond2 = hwn.condition_on_periodic(array(1.5) + 2 * pi) np.testing.assert_allclose( - np.diff( - hwn.pdf(np.column_stack([1.5 * ones(11), arange(-5, 6)])) + diff( + hwn.pdf(column_stack([1.5 * ones(11), arange(-5, 6)])) / dist_cond2.pdf(arange(-5, 6)) ), zeros(10), @@ -59,8 +61,8 @@ def test_condition_on_linear(self): ) dist_cond1 = hwn.condition_on_linear(array(1.5)) np.testing.assert_allclose( - np.diff( - hwn.pdf(np.column_stack([arange(-5, 6), 1.5 * ones(11)])) + diff( + hwn.pdf(column_stack([arange(-5, 6), 1.5 * ones(11)])) / dist_cond1.pdf(arange(-5, 6)) ), zeros(10), @@ -70,8 +72,8 @@ def test_condition_on_linear(self): self.assertFalse( ( allclose( - np.diff( - hwn.pdf(np.column_stack([arange(-5, 6), 1.5 * ones(11)])) + diff( + hwn.pdf(column_stack([arange(-5, 6), 1.5 * ones(11)])) / dist_cond2.pdf(arange(-5, 6)) ), zeros(10), diff --git a/pyrecest/tests/distributions/test_custom_hyperrectangular_distribution.py b/pyrecest/tests/distributions/test_custom_hyperrectangular_distribution.py index 3735d1d4..92fe34dc 100644 --- a/pyrecest/tests/distributions/test_custom_hyperrectangular_distribution.py +++ b/pyrecest/tests/distributions/test_custom_hyperrectangular_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import column_stack from pyrecest.backend import ones from pyrecest.backend import meshgrid from pyrecest.backend import linspace @@ -33,7 +34,7 @@ def test_pdf_method(self): """Test that the pdf method returns correct values.""" x_mesh, y_mesh = meshgrid(linspace(1.0, 3.0, 50), linspace(2.0, 5.0, 50)) expected_pdf = 1.0 / 6.0 * ones(50**2) - calculated_pdf = self.cd.pdf(np.column_stack((x_mesh.ravel(), y_mesh.ravel()))) + calculated_pdf = self.cd.pdf(column_stack((x_mesh.ravel(), y_mesh.ravel()))) self.assertTrue( allclose(calculated_pdf, expected_pdf), "PDF calculated values do not match the expected values.", diff --git a/pyrecest/tests/distributions/test_linear_mixture.py b/pyrecest/tests/distributions/test_linear_mixture.py index 41118ffe..dbd8d94c 100644 --- a/pyrecest/tests/distributions/test_linear_mixture.py +++ b/pyrecest/tests/distributions/test_linear_mixture.py @@ -1,3 +1,4 @@ +from pyrecest.backend import column_stack from pyrecest.backend import diag from pyrecest.backend import meshgrid from pyrecest.backend import linspace @@ -37,7 +38,7 @@ def test_pdf(self): lm = LinearMixture([gm1, gm2], array([0.3, 0.7])) x, y = meshgrid(linspace(-2, 2, 100), linspace(-2, 2, 100)) - points = np.column_stack((x.ravel(), y.ravel())) + points = column_stack((x.ravel(), y.ravel())) np.testing.assert_allclose( lm.pdf(points), 0.3 * gm1.pdf(points) + 0.7 * gm2.pdf(points), atol=1e-20 diff --git a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py index 29657137..fee0966e 100644 --- a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py +++ b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py @@ -1,3 +1,5 @@ +from pyrecest.backend import column_stack +from pyrecest.backend import diff from math import pi from pyrecest.backend import random from pyrecest.backend import sqrt @@ -70,12 +72,12 @@ def test_normalization(self): x, y, z = array( [cos(theta) * cos(phi), cos(theta) * sin(phi), sin(theta)] ) - vals_normalized = shd.pdf(np.column_stack([x, y, z])) + vals_normalized = shd.pdf(column_stack([x, y, z])) shd.coeff_mat = self.unnormalized_coeffs - vals_unnormalized = shd.pdf(np.column_stack([x, y, z])) + vals_unnormalized = shd.pdf(column_stack([x, y, z])) self.assertTrue( allclose( - np.diff(vals_normalized / vals_unnormalized), + diff(vals_normalized / vals_unnormalized), zeros(vals_normalized.shape[0] - 1), atol=1e-6, ) @@ -141,29 +143,29 @@ def test_truncation(self): x, y, z = AbstractSphericalDistribution.sph_to_cart(phi, theta) self.assertTrue( allclose( - shd2.pdf(np.column_stack((x, y, z))), - shd.pdf(np.column_stack((x, y, z))), + shd2.pdf(column_stack((x, y, z))), + shd.pdf(column_stack((x, y, z))), atol=1e-6, ) ) self.assertTrue( allclose( - shd3.pdf(np.column_stack((x, y, z))), - shd.pdf(np.column_stack((x, y, z))), + shd3.pdf(column_stack((x, y, z))), + shd.pdf(column_stack((x, y, z))), atol=1e-6, ) ) self.assertTrue( allclose( - shd4.pdf(np.column_stack((x, y, z))), - shd.pdf(np.column_stack((x, y, z))), + shd4.pdf(column_stack((x, y, z))), + shd.pdf(column_stack((x, y, z))), atol=1e-6, ) ) self.assertTrue( allclose( - shd5.pdf(np.column_stack((x, y, z))), - shd.pdf(np.column_stack((x, y, z))), + shd5.pdf(column_stack((x, y, z))), + shd.pdf(column_stack((x, y, z))), atol=1e-6, ) ) @@ -389,7 +391,7 @@ def test_basis_function(self, _, coeff_mat, expected_func): ) x, y, z = AbstractSphericalDistribution.sph_to_cart(phi.ravel(), theta.ravel()) np.testing.assert_allclose( - shd.pdf(np.column_stack([x, y, z])), expected_func(x, y, z), atol=1e-6 + shd.pdf(column_stack([x, y, z])), expected_func(x, y, z), atol=1e-6 ) @parameterized.expand( @@ -646,7 +648,7 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): ) x, y, z = AbstractSphericalDistribution.sph_to_cart(phi.ravel(), theta.ravel()) - vals_to_test = shd.pdf(np.column_stack([x, y, z])) + vals_to_test = shd.pdf(column_stack([x, y, z])) if name.endswith("cart"): expected_func_vals = expected_func(x, y, z) elif name.endswith("sph"): @@ -838,8 +840,8 @@ def test_conversion(self, _, coeff_mat): ) x, y, z = AbstractSphericalDistribution.sph_to_cart(phi.ravel(), theta.ravel()) np.testing.assert_allclose( - rshd.pdf(np.column_stack((x, y, z))), - shd.pdf(np.column_stack((x, y, z))), + rshd.pdf(column_stack((x, y, z))), + shd.pdf(column_stack((x, y, z))), atol=1e-6, ) @@ -940,8 +942,8 @@ def test_from_distribution_via_integral_vmf(self): shd.integrate_numerically(), dist.integrate_numerically(), atol=1e-10 ) np.testing.assert_allclose( - shd.pdf(np.column_stack([x, y, z])), - dist.pdf(np.column_stack([x, y, z])), + shd.pdf(column_stack([x, y, z])), + dist.pdf(column_stack([x, y, z])), atol=0.001, ) @@ -974,7 +976,7 @@ def test_convergence(self): diffs[i] = shd.total_variation_distance_numerical(dist) # Check if the deviation from true density is decreasing - self.assertTrue(all(np.diff(diffs) < 0)) + self.assertTrue(all(diff(diffs) < 0)) @parameterized.expand( [ diff --git a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py index 0375ea26..4f1bf524 100644 --- a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py +++ b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py @@ -1,3 +1,4 @@ +from pyrecest.backend import diff from math import pi from pyrecest.backend import random from pyrecest.backend import sqrt @@ -42,7 +43,7 @@ def testNormalization(self): vals_unnormalized = shd.pdf(column_stack((x, y, z))) self.assertTrue( allclose( - np.diff(vals_normalized / vals_unnormalized), + diff(vals_normalized / vals_unnormalized), zeros((1, x.size - 1)), atol=1e-6, ) @@ -142,7 +143,7 @@ def test_basis_function(self, name, coeff_mat, result_func): shd.coeff_mat = array(coeff_mat) x, y, z = SphericalHarmonicsDistributionRealTest._gen_naive_grid(10) np.testing.assert_allclose( - shd.pdf(np.column_stack((x, y, z))), + shd.pdf(column_stack((x, y, z))), result_func(x, y, z), rtol=1e-6, err_msg=name, @@ -335,8 +336,8 @@ def test_conversion(self, _, coeff_mat): ) x, y, z = AbstractSphericalDistribution.sph_to_cart(phi_to_test, theta_to_test) np.testing.assert_allclose( - cshd.pdf(np.column_stack((x, y, z))), - rshd.pdf(np.column_stack((x, y, z))), + cshd.pdf(column_stack((x, y, z))), + rshd.pdf(column_stack((x, y, z))), atol=1e-6, ) diff --git a/pyrecest/tests/distributions/test_toroidal_von_mises_sine_distribution.py b/pyrecest/tests/distributions/test_toroidal_von_mises_sine_distribution.py index 2c357a63..da4ca2fd 100644 --- a/pyrecest/tests/distributions/test_toroidal_von_mises_sine_distribution.py +++ b/pyrecest/tests/distributions/test_toroidal_von_mises_sine_distribution.py @@ -1,3 +1,4 @@ +from pyrecest.backend import column_stack from math import pi from pyrecest.backend import sin from pyrecest.backend import exp @@ -59,7 +60,7 @@ def _unnormalized_pdf(self, xs): (array([-3, 11]),), (array([[5, 1], [6, 3]]),), ( - np.column_stack( + column_stack( (arange(0, 2 * pi, 0.1), arange(1 * pi, 3 * pi, 0.1)) ), ), diff --git a/pyrecest/tests/filters/test_global_nearest_neighbor.py b/pyrecest/tests/filters/test_global_nearest_neighbor.py index 6e746578..451bc4be 100644 --- a/pyrecest/tests/filters/test_global_nearest_neighbor.py +++ b/pyrecest/tests/filters/test_global_nearest_neighbor.py @@ -1,3 +1,4 @@ +from pyrecest.backend import column_stack from pyrecest.backend import sort from pyrecest.backend import real from pyrecest.backend import eye @@ -177,15 +178,15 @@ def test_association_with_clutter(self): # Generate perfect measurements, association should then be # optimal. - perfect_meas_ordered = self.meas_mat @ np.column_stack( + perfect_meas_ordered = self.meas_mat @ column_stack( [gaussian.mu for gaussian in all_gaussians] ) - measurements = np.column_stack([perfect_meas_ordered, array([3, 2])]) + measurements = column_stack([perfect_meas_ordered, array([3, 2])]) association = tracker.find_association(measurements, self.meas_mat, eye(2)) np.testing.assert_array_equal(association, [0, 1, 2]) # Shift them and add one measurement - measurements = np.column_stack( + measurements = column_stack( [ perfect_meas_ordered[:, 1], perfect_meas_ordered[:, 2], @@ -221,7 +222,7 @@ def test_update_with_and_without_clutter(self): tracker_clut.filter_state = self.kfs_init all_gaussians = [kf.filter_state for kf in self.kfs_init] - perfect_meas_ordered = self.meas_mat @ np.column_stack( + perfect_meas_ordered = self.meas_mat @ column_stack( [gaussian.mu for gaussian in all_gaussians] ) measurements_no_clut = perfect_meas_ordered @@ -238,7 +239,7 @@ def test_update_with_and_without_clutter(self): all(curr_covs <= dstack([dist.C for dist in all_gaussians])) ) - measurements_clut = np.column_stack( + measurements_clut = column_stack( [measurements_no_clut, array([2, 2]).reshape(-1, 1)] ) tracker_clut.update_linear(measurements_clut, self.meas_mat, eye(2)) @@ -260,7 +261,7 @@ def test_update_with_and_without_clutter(self): curr_covs = dstack([dist.C for dist in tracker_no_clut.filter_state]) self.assertTrue(all(curr_covs <= previous_covs)) - measurements_clut = np.column_stack( + measurements_clut = column_stack( [ perfect_meas_ordered[:, [1, 2]], array([2, 2]).reshape(-1, 1), diff --git a/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py b/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py index d486558e..e4b020c0 100644 --- a/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py +++ b/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py @@ -3,6 +3,7 @@ from pyrecest.backend import array from pyrecest.backend import zeros import unittest +import numpy.testing as npt from pyrecest.distributions import HypertoroidalWNDistribution @@ -43,7 +44,7 @@ def test_predict_update_cycle_3D(self): self.test_predict_identity() for _ in range(3): self.test_update_identity() - np.testing.assert_allclose( + npt.assert_allclose( self.hpf.get_point_estimate(), self.forced_mean, atol=0.1 ) diff --git a/pyrecest/tests/test_evaluation_basic.py b/pyrecest/tests/test_evaluation_basic.py index 22d13938..155a61d2 100644 --- a/pyrecest/tests/test_evaluation_basic.py +++ b/pyrecest/tests/test_evaluation_basic.py @@ -1,3 +1,4 @@ +from pyrecest.backend import atleast_2d from pyrecest.backend import linalg from pyrecest.backend import random from pyrecest.backend import sqrt @@ -113,7 +114,7 @@ def test_generate_measurements(self, n_meas): self.assertEqual(np.size(measurements), self.n_timesteps_default) for i in range(self.n_timesteps_default): self.assertEqual( - np.atleast_2d(measurements[i]).shape, + atleast_2d(measurements[i]).shape, ( self.simulation_param["n_meas_at_individual_time_step"][i], self.simulation_param["initial_prior"].dim, diff --git a/pyrecest/tests/test_hypertoroidal_sampler.py b/pyrecest/tests/test_hypertoroidal_sampler.py index 66185e24..3a201aa9 100644 --- a/pyrecest/tests/test_hypertoroidal_sampler.py +++ b/pyrecest/tests/test_hypertoroidal_sampler.py @@ -1,3 +1,4 @@ +from pyrecest.backend import diff from math import pi from pyrecest.backend import std from pyrecest.backend import all @@ -34,7 +35,7 @@ def test_get_grid(self): self.assertTrue(all(grid_points < 2 * pi)) # Check that the grid points are equidistant - diff = np.diff(grid_points) + diff = diff(grid_points) self.assertAlmostEqual(std(diff), 0, places=5) diff --git a/pyrecest/utils/plotting.py b/pyrecest/utils/plotting.py index bd8db833..baf6368f 100644 --- a/pyrecest/utils/plotting.py +++ b/pyrecest/utils/plotting.py @@ -1,3 +1,4 @@ +from pyrecest.backend import column_stack from pyrecest.backend import linalg from pyrecest.backend import diag from math import pi @@ -25,7 +26,7 @@ def plot_ellipsoid(center, shape_matrix, scaling_factor=1, color="blue"): def plot_ellipsoid_2d(center, shape_matrix, scaling_factor=1, color="blue"): xs = linspace(0, 2 * pi, 100) - ps = scaling_factor * shape_matrix @ np.column_stack((cos(xs), sin(xs))) + ps = scaling_factor * shape_matrix @ column_stack((cos(xs), sin(xs))) plt.plot(ps[0] + center[0], ps[1] + center[1], color=color) plt.show() From 14526e267858039c711da4a72934afa3c3b36550 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Sat, 21 Oct 2023 22:06:33 +0100 Subject: [PATCH 073/232] More --- .../abstract_hypercylindrical_distribution.py | 2 +- ...bstract_hyperhemispherical_distribution.py | 4 +- .../hypersphere_subset/watson_distribution.py | 3 +- .../toroidal_von_mises_sine_distribution.py | 15 ++++---- ..._abstract_hypercylindrical_distribution.py | 9 +++-- ...bstract_hyperhemispherical_distribution.py | 5 ++- ...bstract_hypersphere_subset_distribution.py | 8 ++-- ...est_abstract_hypertoroidal_distribution.py | 8 ++-- .../test_abstract_linear_distribution.py | 9 +++-- .../test_bingham_distribution.py | 4 +- .../test_circular_fourier_distribution.py | 28 +++++++------- .../test_circular_uniform_distribution.py | 32 ++++++++-------- ...st_custom_hypercylindrical_distribution.py | 10 ++--- .../test_custom_linear_distribution.py | 4 +- .../test_disk_uniform_distribution.py | 4 +- ...t_ellipsoidal_ball_uniform_distribution.py | 4 +- ...est_hypercylindrical_dirac_distribution.py | 20 +++++----- .../test_hyperspherical_dirac_distribution.py | 24 ++++++------ .../test_hypertoroidal_dirac_distribution.py | 38 +++++++++---------- ...pertoroidal_wrapped_normal_distribution.py | 4 +- .../distributions/test_linear_mixture.py | 4 +- ...t_partially_wrapped_normal_distribution.py | 8 ++-- .../test_sphere_subset_distribution.py | 12 +++--- ...pherical_harmonics_distribution_complex.py | 23 +++++------ ...t_spherical_harmonics_distribution_real.py | 10 ++--- ...st_toroidal_von_mises_sine_distribution.py | 13 ++++--- .../test_von_mises_distribution.py | 4 +- .../test_von_mises_fisher_distribution.py | 16 ++++---- .../distributions/test_watson_distribution.py | 8 ++-- .../test_wrapped_cauchy_distribution.py | 6 +-- .../test_wrapped_laplace_distribution.py | 14 +++---- .../test_wrapped_normal_distribution.py | 4 +- .../filters/test_circular_particle_filter.py | 12 +++--- .../filters/test_euclidean_particle_filter.py | 8 ++-- .../filters/test_global_nearest_neighbor.py | 33 ++++++++-------- .../filters/test_random_matrix_tracker.py | 26 ++++++------- .../test_toroidal_wrapped_normal_filter.py | 10 ++--- .../tests/filters/test_von_mises_filter.py | 4 +- .../filters/test_wrapped_normal_filter.py | 4 +- pyrecest/tests/test_evaluation_basic.py | 5 ++- pyrecest/tests/test_metrics.py | 2 +- 41 files changed, 235 insertions(+), 226 deletions(-) diff --git a/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py b/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py index c433b170..fa9a62ce 100644 --- a/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py +++ b/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py @@ -216,7 +216,7 @@ def linear_mean_numerical(self): # Define the integrands for the mean calculation if self.lin_dim == 1 and self.bound_dim == 1: mu = scipy.integrate.nquad( - lambda x, y: (y * self.pdf([x, y]))[0], + lambda x, y: (y * self.pdf(array([x, y])))[0], [[0.0, 2 * pi], [-float('inf'), float('inf')]], )[0] elif self.bound_dim == 2 and self.lin_dim == 1: diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py index ca1b0caa..93ad0389 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py @@ -146,7 +146,7 @@ def integrate_fun_over_domain( def mode_numerical(self): def objective_function_2d(s): - return -self.pdf(AbstractHypersphereSubsetDistribution.polar_to_cart(s)) + return -self.pdf(AbstractHypersphereSubsetDistribution.polar_to_cart(array(s))) assert self.dim == 2, "Currently only implemented for 2D hemispheres." @@ -160,7 +160,7 @@ def objective_function_2d(s): "maxiter": 2000, }, ) - m = AbstractHypersphereSubsetDistribution.polar_to_cart(result.x) + m = AbstractHypersphereSubsetDistribution.polar_to_cart(array(result.x)) return (1 - 2 * (m[-1] < 0)) * m @staticmethod diff --git a/pyrecest/distributions/hypersphere_subset/watson_distribution.py b/pyrecest/distributions/hypersphere_subset/watson_distribution.py index 1f6c66cd..2f304177 100644 --- a/pyrecest/distributions/hypersphere_subset/watson_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/watson_distribution.py @@ -11,6 +11,7 @@ from pyrecest.backend import float64 from pyrecest.backend import zeros import numbers +import numpy.testing as npt import mpmath @@ -94,5 +95,5 @@ def set_mode(self, new_mode): return dist def shift(self, shift_by): - np.testing.assert_almost_equal(self.mu, vstack([zeros((self.dim, 1)), 1]), "There is no true shifting for the hypersphere. This is a function for compatibility and only works when mu is [0,0,...,1].") + npt.assert_almost_equal(self.mu, vstack([zeros((self.dim, 1)), 1]), "There is no true shifting for the hypersphere. This is a function for compatibility and only works when mu is [0,0,...,1].") return self.set_mode(shift_by) \ No newline at end of file diff --git a/pyrecest/distributions/hypertorus/toroidal_von_mises_sine_distribution.py b/pyrecest/distributions/hypertorus/toroidal_von_mises_sine_distribution.py index 9f95baf4..225db015 100644 --- a/pyrecest/distributions/hypertorus/toroidal_von_mises_sine_distribution.py +++ b/pyrecest/distributions/hypertorus/toroidal_von_mises_sine_distribution.py @@ -5,6 +5,7 @@ from pyrecest.backend import exp from pyrecest.backend import cos from pyrecest.backend import all +from pyrecest.backend import array from scipy.special import comb, iv @@ -14,16 +15,16 @@ class ToroidalVonMisesSineDistribution(AbstractToroidalDistribution): def __init__(self, mu, kappa, lambda_): AbstractToroidalDistribution.__init__(self) - assert np.size(mu) == 2 - assert np.size(kappa) == 2 - assert np.isscalar(lambda_) - assert all(kappa >= 0) + assert mu.shape == (2,) + assert kappa.shape == (2,) + assert lambda_.shape == () + assert all(kappa >= 0.0) - self.mu = mod(mu, 2 * pi) + self.mu = mod(mu, 2.0 * pi) self.kappa = kappa self.lambda_ = lambda_ - self.C = 1 / self.norm_const + self.C = 1.0 / self.norm_const @property def norm_const(self): @@ -35,7 +36,7 @@ def s(m): * iv(m, self.kappa[1]) ) - Cinv = 4 * pi**2 * sum([s(m) for m in range(11)]) + Cinv = 4.0 * pi**2 * sum(array([s(m) for m in range(11)])) return Cinv def pdf(self, xs): diff --git a/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py b/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py index d58cf48d..6c0760b9 100644 --- a/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py @@ -9,6 +9,7 @@ from pyrecest.backend import zeros import unittest import pyrecest.backend +import numpy.testing as npt from pyrecest.distributions.cart_prod.partially_wrapped_normal_distribution import ( @@ -27,7 +28,7 @@ def test_linear_mean_numerical(self): hwn = PartiallyWrappedNormalDistribution( array([1, 2]), array([[2.0, 0.3], [0.3, 1.0]]), 1 ) - np.testing.assert_allclose(hwn.linear_mean_numerical(), hwn.mu[-1]) + npt.assert_allclose(hwn.linear_mean_numerical(), hwn.mu[-1]) @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") def test_condition_on_periodic(self): @@ -36,7 +37,7 @@ def test_condition_on_periodic(self): ) dist_cond1 = hwn.condition_on_periodic(array(1.5)) # There is some normalization constant involved, therefore, test if ratio stays the same - np.testing.assert_allclose( + npt.assert_allclose( diff( hwn.pdf(column_stack([1.5 * ones(11), arange(-5, 6)])) / dist_cond1.pdf(arange(-5, 6)) @@ -45,7 +46,7 @@ def test_condition_on_periodic(self): atol=1e-10, ) dist_cond2 = hwn.condition_on_periodic(array(1.5) + 2 * pi) - np.testing.assert_allclose( + npt.assert_allclose( diff( hwn.pdf(column_stack([1.5 * ones(11), arange(-5, 6)])) / dist_cond2.pdf(arange(-5, 6)) @@ -60,7 +61,7 @@ def test_condition_on_linear(self): array([1.0, 2.0]), array([[2.0, 0.3], [0.3, 1.0]]), 1 ) dist_cond1 = hwn.condition_on_linear(array(1.5)) - np.testing.assert_allclose( + npt.assert_allclose( diff( hwn.pdf(column_stack([arange(-5, 6), 1.5 * ones(11)])) / dist_cond1.pdf(arange(-5, 6)) diff --git a/pyrecest/tests/distributions/test_abstract_hyperhemispherical_distribution.py b/pyrecest/tests/distributions/test_abstract_hyperhemispherical_distribution.py index 47ff7fef..c87c4bb3 100644 --- a/pyrecest/tests/distributions/test_abstract_hyperhemispherical_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hyperhemispherical_distribution.py @@ -4,6 +4,7 @@ from pyrecest.backend import ones from pyrecest.backend import array import unittest +import numpy.testing as npt from pyrecest.distributions import ( @@ -35,7 +36,7 @@ def test_mode_numerical(self): """Tests mode_numerical.""" watson_dist = HyperhemisphericalWatsonDistribution(self.mu_, self.kappa_) mode_numerical = watson_dist.mode_numerical() - np.testing.assert_array_almost_equal(self.mu_, mode_numerical, decimal=6) + npt.assert_array_almost_equal(self.mu_, mode_numerical, decimal=6) def test_sample_metropolis_hastings_basics_only(self): """Tests the sample_metropolis_hastings sampling""" @@ -48,7 +49,7 @@ def test_sample_metropolis_hastings_basics_only(self): for s in samples: with self.subTest(sample=s): self.assertEqual(s.shape, (n, chd.input_dim)) - np.testing.assert_allclose( + npt.assert_allclose( sum(s**2, axis=1), ones(n), rtol=1e-10 ) diff --git a/pyrecest/tests/distributions/test_abstract_hypersphere_subset_distribution.py b/pyrecest/tests/distributions/test_abstract_hypersphere_subset_distribution.py index b75ae991..263fe5e1 100644 --- a/pyrecest/tests/distributions/test_abstract_hypersphere_subset_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hypersphere_subset_distribution.py @@ -3,7 +3,7 @@ from pyrecest.backend import cos from pyrecest.backend import array import unittest - +import numpy.testing as npt from pyrecest.distributions import VonMisesFisherDistribution @@ -21,7 +21,7 @@ def fangles_1d(phi): phi_test = array([1.0, 2.0, 0.0, 0.3, 1.1]) - np.testing.assert_array_almost_equal( + npt.assert_array_almost_equal( pdf_hyperspherical(phi_test), fangles_1d(phi_test) ) @@ -47,7 +47,7 @@ def fangles_2d(phi1, phi2): phi1_test = [1.0, 2.0, 0.0, 0.3, 1.1] phi2_test = [2.0, 3.0, 0.1, 3.0, 1.1] - np.testing.assert_array_almost_equal( + npt.assert_array_almost_equal( pdf_hyperspherical(phi1_test, phi2_test), fangles_2d(phi1_test, phi2_test) ) @@ -75,7 +75,7 @@ def fangles_3d(phi1, phi2, phi3): phi2_test = array([2.0, 3.0, 0.1, 3.0, 1.1]) phi3_test = phi2_test + 0.2 - np.testing.assert_array_almost_equal( + npt.assert_array_almost_equal( pdf_hyperspherical(phi1_test, phi2_test, phi3_test), fangles_3d(phi1_test, phi2_test, phi3_test), ) diff --git a/pyrecest/tests/distributions/test_abstract_hypertoroidal_distribution.py b/pyrecest/tests/distributions/test_abstract_hypertoroidal_distribution.py index b7069ffd..a10cafce 100644 --- a/pyrecest/tests/distributions/test_abstract_hypertoroidal_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hypertoroidal_distribution.py @@ -3,17 +3,17 @@ from pyrecest.backend import array from pyrecest.distributions import AbstractHypertoroidalDistribution - +import numpy.testing as npt class TestAbstractHypertoroidalDistribution(unittest.TestCase): def test_angular_error(self): - np.testing.assert_allclose( + npt.assert_allclose( AbstractHypertoroidalDistribution.angular_error(array(pi), array(0.0)), pi ) - np.testing.assert_allclose( + npt.assert_allclose( AbstractHypertoroidalDistribution.angular_error(array(0), array(2 * pi)), 0 ) - np.testing.assert_allclose( + npt.assert_allclose( AbstractHypertoroidalDistribution.angular_error(array(pi / 4), array(7 * pi / 4)), pi / 2, ) \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_abstract_linear_distribution.py b/pyrecest/tests/distributions/test_abstract_linear_distribution.py index 796c0658..96e00212 100644 --- a/pyrecest/tests/distributions/test_abstract_linear_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_linear_distribution.py @@ -4,6 +4,7 @@ from pyrecest.backend import array import pyrecest.backend import unittest +import numpy.testing as npt import matplotlib @@ -61,19 +62,19 @@ def test_mode_numerical_custom_1D(self): self.assertAlmostEqual(cd.mode_numerical(), 0.5, delta=1e-4) def test_mean_numerical_gaussian_2D(self): - np.testing.assert_allclose(self.g_2D.mean_numerical(), self.mu_2D, atol=1e-6) + npt.assert_allclose(self.g_2D.mean_numerical(), self.mu_2D, atol=1e-6) def test_mode_numerical_gaussian_2D_mean_far_away(self): mu = array([5.0, 10.0]) C = array([[2.0, 1.0], [1.0, 1.0]]) g = GaussianDistribution(mu, C) - np.testing.assert_allclose(g.mode_numerical(), mu, atol=2e-4) + npt.assert_allclose(g.mode_numerical(), mu, atol=2e-4) def test_mode_numerical_gaussian_3D(self): - np.testing.assert_allclose(self.g_3D.mode_numerical(), self.mu_3D, atol=5e-4) + npt.assert_allclose(self.g_3D.mode_numerical(), self.mu_3D, atol=5e-4) def test_covariance_numerical_gaussian_2D(self): - np.testing.assert_allclose( + npt.assert_allclose( self.g_2D.covariance_numerical(), self.C_2D, atol=1e-6 ) diff --git a/pyrecest/tests/distributions/test_bingham_distribution.py b/pyrecest/tests/distributions/test_bingham_distribution.py index 69299bde..4e613f07 100644 --- a/pyrecest/tests/distributions/test_bingham_distribution.py +++ b/pyrecest/tests/distributions/test_bingham_distribution.py @@ -5,7 +5,7 @@ from pyrecest.distributions import BinghamDistribution from .test_von_mises_fisher_distribution import vectors_to_test_2d - +import numpy.testing as npt class TestBinghamDistribution(unittest.TestCase): def setUp(self): @@ -29,7 +29,7 @@ def test_pdf(self): ], ) computed_values = self.bd.pdf(vectors_to_test_2d) - np.testing.assert_array_almost_equal( + npt.assert_array_almost_equal( computed_values, expected_values, err_msg="Expected and computed pdf values do not match.", diff --git a/pyrecest/tests/distributions/test_circular_fourier_distribution.py b/pyrecest/tests/distributions/test_circular_fourier_distribution.py index 512b07c6..8eb8579e 100644 --- a/pyrecest/tests/distributions/test_circular_fourier_distribution.py +++ b/pyrecest/tests/distributions/test_circular_fourier_distribution.py @@ -10,7 +10,7 @@ import copy import unittest - +import numpy.testing as npt from parameterized import parameterized from pyrecest.distributions import ( CircularFourierDistribution, @@ -87,9 +87,9 @@ def test_vm_to_fourier(self, mult_by_n, transformation): transformation=transformation, store_values_multiplied_by_n=mult_by_n, ) - np.testing.assert_array_almost_equal(dist.pdf(xs), fd.pdf(xs)) + npt.assert_array_almost_equal(dist.pdf(xs), fd.pdf(xs)) fd_real = fd.to_real_fd() - np.testing.assert_array_almost_equal(dist.pdf(xs), fd_real.pdf(xs)) + npt.assert_array_almost_equal(dist.pdf(xs), fd_real.pdf(xs)) @parameterized.expand( [ @@ -109,20 +109,20 @@ def test_integrate_numerically(self, mult_by_n, transformation): transformation=transformation, store_values_multiplied_by_n=mult_by_n, ) - np.testing.assert_array_almost_equal(fd.integrate_numerically(), 1) + npt.assert_array_almost_equal(fd.integrate_numerically(), 1) fd_real = fd.to_real_fd() - np.testing.assert_array_almost_equal(fd_real.integrate_numerically(), 1) + npt.assert_array_almost_equal(fd_real.integrate_numerically(), 1) fd_unnorm = copy.copy(fd) fd_unnorm.c = fd.c * (scale_by) if transformation == "identity": expected_val = scale_by else: expected_val = (scale_by) ** 2 - np.testing.assert_array_almost_equal( + npt.assert_array_almost_equal( fd_unnorm.integrate_numerically(), expected_val ) fd_unnorm_real = fd_unnorm.to_real_fd() - np.testing.assert_array_almost_equal( + npt.assert_array_almost_equal( fd_unnorm_real.integrate_numerically(), expected_val ) @@ -143,18 +143,18 @@ def test_integrate(self, mult_by_n, transformation): transformation=transformation, store_values_multiplied_by_n=mult_by_n, ) - np.testing.assert_array_almost_equal(fd.integrate(), 1) + npt.assert_array_almost_equal(fd.integrate(), 1) fd_real = fd.to_real_fd() - np.testing.assert_array_almost_equal(fd_real.integrate(), 1) + npt.assert_array_almost_equal(fd_real.integrate(), 1) fd_unnorm = copy.copy(fd) fd_unnorm.c = fd.c * scale_by if transformation == "identity": expected_val = scale_by else: expected_val = scale_by ** 2 - np.testing.assert_array_almost_equal(fd_unnorm.integrate(), expected_val) + npt.assert_array_almost_equal(fd_unnorm.integrate(), expected_val) fd_unnorm_real = fd_unnorm.to_real_fd() - np.testing.assert_array_almost_equal(fd_unnorm_real.integrate(), expected_val) + npt.assert_array_almost_equal(fd_unnorm_real.integrate(), expected_val) fd_unnorm = CircularFourierDistribution.from_distribution( dist, n=31, @@ -165,8 +165,8 @@ def test_integrate(self, mult_by_n, transformation): fd_norm = fd_unnorm.normalize() fd_unnorm_real = fd_unnorm.to_real_fd() fd_norm_real = fd_unnorm_real.normalize() - np.testing.assert_array_almost_equal(fd_norm.integrate(), 1.0) - np.testing.assert_array_almost_equal(fd_norm_real.integrate(), 1.0) + npt.assert_array_almost_equal(fd_norm.integrate(), 1.0) + npt.assert_array_almost_equal(fd_norm_real.integrate(), 1.0) @parameterized.expand( [ @@ -198,7 +198,7 @@ def test_distance(self, mult_by_n): 2.0 * pi, ) fd_diff = fd1 - fd2 - np.testing.assert_array_almost_equal(fd_diff.integrate(), hel_like_distance) + npt.assert_array_almost_equal(fd_diff.integrate(), hel_like_distance) if __name__ == "__main__": diff --git a/pyrecest/tests/distributions/test_circular_uniform_distribution.py b/pyrecest/tests/distributions/test_circular_uniform_distribution.py index f482f2e9..f9f4cdba 100644 --- a/pyrecest/tests/distributions/test_circular_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_circular_uniform_distribution.py @@ -3,7 +3,7 @@ from pyrecest.backend import array import unittest - +import numpy.testing as npt from pyrecest.distributions.circle.circular_uniform_distribution import ( CircularUniformDistribution, ) @@ -15,53 +15,53 @@ def test_pdf(self): x = array([1, 2, 3, 4, 5, 6]) # Test pdf - np.testing.assert_allclose(cu.pdf(x), 1 / (2 * pi) * ones(x.shape)) + npt.assert_allclose(cu.pdf(x), 1 / (2 * pi) * ones(x.shape)) def test_shift(self): cu = CircularUniformDistribution() cu2 = cu.shift(3) x = array([1, 2, 3, 4, 5, 6]) - np.testing.assert_allclose(cu2.pdf(x), 1 / (2 * pi) * ones(x.shape)) + npt.assert_allclose(cu2.pdf(x), 1 / (2 * pi) * ones(x.shape)) def test_cdf(self): cu = CircularUniformDistribution() x = array([1, 2, 3, 4, 5, 6]) - np.testing.assert_allclose(cu.cdf(x), cu.cdf_numerical(x)) + npt.assert_allclose(cu.cdf(x), cu.cdf_numerical(x)) def test_cdf_with_shift(self): cu = CircularUniformDistribution() x = array([1, 2, 3, 4, 5, 6]) cu2 = cu.shift(3) - np.testing.assert_allclose(cu2.cdf(x), cu2.cdf_numerical(x)) + npt.assert_allclose(cu2.cdf(x), cu2.cdf_numerical(x)) def test_trigonometric_moment(self): cu = CircularUniformDistribution() - np.testing.assert_allclose( + npt.assert_allclose( cu.trigonometric_moment(0), cu.trigonometric_moment_numerical(0) ) - np.testing.assert_allclose(cu.trigonometric_moment(0), 1) + npt.assert_allclose(cu.trigonometric_moment(0), 1) def test_trigonometric_moment_with_shift(self): cu = CircularUniformDistribution() - np.testing.assert_allclose( + npt.assert_allclose( cu.trigonometric_moment(1), cu.trigonometric_moment_numerical(1), atol=1e-10 ) - np.testing.assert_allclose(cu.trigonometric_moment(1), 0, atol=1e-10) + npt.assert_allclose(cu.trigonometric_moment(1), 0, atol=1e-10) def test_integral(self): cu = CircularUniformDistribution() - np.testing.assert_allclose(cu.integrate(), cu.integrate_numerically()) - np.testing.assert_allclose(cu.integrate(), 1) + npt.assert_allclose(cu.integrate(), cu.integrate_numerically()) + npt.assert_allclose(cu.integrate(), 1) def test_integral_with_range(self): cu = CircularUniformDistribution() - np.testing.assert_allclose( + npt.assert_allclose( cu.integrate(array([1.0, 4.0])), cu.integrate_numerically(array([1.0, 4.0])) ) - np.testing.assert_allclose( + npt.assert_allclose( cu.integrate(array([-4.0, 11.0])), cu.integrate_numerically(array([-4.0, 11.0])) ) - np.testing.assert_allclose( + npt.assert_allclose( cu.integrate(array([2.0 * pi, -1.0])), cu.integrate_numerically(array([2.0 * pi, -1.0])) ) @@ -72,10 +72,10 @@ def test_mean(self): def test_entropy(self): cu = CircularUniformDistribution() - np.testing.assert_allclose(cu.entropy(), cu.entropy_numerical()) + npt.assert_allclose(cu.entropy(), cu.entropy_numerical()) def test_sampling(self): cu = CircularUniformDistribution() n = 10 s = cu.sample(n) - np.testing.assert_allclose(s.shape[0], n) \ No newline at end of file + npt.assert_allclose(s.shape[0], n) \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py b/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py index 67e6161d..9c01d5dd 100644 --- a/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py +++ b/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py @@ -5,7 +5,7 @@ from pyrecest.backend import array import pyrecest.backend import unittest - +import numpy.testing as npt from pyrecest.distributions import ( GaussianDistribution, @@ -37,13 +37,13 @@ def fun(x): def test_constructor(self): chd = CustomHypercylindricalDistribution(self.pwn.pdf, 3, 3) - np.testing.assert_allclose( + npt.assert_allclose( self.pwn.pdf(self.grid_flat), chd.pdf(self.grid_flat) ) def test_from_distribution(self): chd = CustomHypercylindricalDistribution.from_distribution(self.pwn) - np.testing.assert_allclose( + npt.assert_allclose( self.pwn.pdf(self.grid_flat), chd.pdf(self.grid_flat) ) @@ -52,14 +52,14 @@ def test_condition_on_linear(self): dist = self.chcd_vm_gauss_stacked.condition_on_linear(array([2.0, 1.0])) x = linspace(0.0, 2.0 * pi, 100) - np.testing.assert_allclose(dist.pdf(x), self.vm.pdf(x)) + npt.assert_allclose(dist.pdf(x), self.vm.pdf(x)) @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") def test_condition_on_periodic(self): dist = self.chcd_vm_gauss_stacked.condition_on_periodic(array(1.0)) grid = np.mgrid[-3:4, -3:4].reshape(2, -1).T - np.testing.assert_allclose(dist.pdf(grid), self.gauss.pdf(grid)) + npt.assert_allclose(dist.pdf(grid), self.gauss.pdf(grid)) if __name__ == "__main__": diff --git a/pyrecest/tests/distributions/test_custom_linear_distribution.py b/pyrecest/tests/distributions/test_custom_linear_distribution.py index 869c8d1a..3dd94a06 100644 --- a/pyrecest/tests/distributions/test_custom_linear_distribution.py +++ b/pyrecest/tests/distributions/test_custom_linear_distribution.py @@ -5,7 +5,7 @@ from pyrecest.backend import array from pyrecest.backend import concatenate import unittest - +import numpy.testing as npt from pyrecest.distributions import CustomLinearDistribution, GaussianDistribution from pyrecest.distributions.nonperiodic.gaussian_mixture import GaussianMixture @@ -33,7 +33,7 @@ def test_normalize(self): @staticmethod def verify_pdf_equal(dist1, dist2, tol): x, y = meshgrid(linspace(0.0, 2.0 * pi, 10), linspace(0.0, 2.0 * pi, 10)) - np.testing.assert_allclose( + npt.assert_allclose( dist1.pdf(concatenate((x, y)).reshape(2, -1).T), dist2.pdf(concatenate((x, y)).reshape(2, -1).T), atol=tol, diff --git a/pyrecest/tests/distributions/test_disk_uniform_distribution.py b/pyrecest/tests/distributions/test_disk_uniform_distribution.py index 71697e7d..e3cecd15 100644 --- a/pyrecest/tests/distributions/test_disk_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_disk_uniform_distribution.py @@ -6,7 +6,7 @@ from pyrecest.backend import zeros """ Test cases for DiskUniformDistribution""" import unittest - +import numpy.testing as npt from pyrecest.distributions import DiskUniformDistribution @@ -25,7 +25,7 @@ def test_pdf(self): ).T pdf_values = dist.pdf(xs) - np.testing.assert_allclose( + npt.assert_allclose( pdf_values, 1 / pi diff --git a/pyrecest/tests/distributions/test_ellipsoidal_ball_uniform_distribution.py b/pyrecest/tests/distributions/test_ellipsoidal_ball_uniform_distribution.py index a960d44d..ae70778e 100644 --- a/pyrecest/tests/distributions/test_ellipsoidal_ball_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_ellipsoidal_ball_uniform_distribution.py @@ -1,7 +1,7 @@ from pyrecest.backend import diag from pyrecest.backend import array import unittest - +import numpy.testing as npt from pyrecest.distributions import EllipsoidalBallUniformDistribution @@ -11,7 +11,7 @@ def test_pdf(self): dist = EllipsoidalBallUniformDistribution( array([0.0, 0.0, 0.0]), diag(array([4.0, 9.0, 16.0])) ) - np.testing.assert_allclose(dist.pdf(array([0.0, 0.0, 0.0])), 1 / 100.53096491) + npt.assert_allclose(dist.pdf(array([0.0, 0.0, 0.0])), 1 / 100.53096491) def test_sampling(self): dist = EllipsoidalBallUniformDistribution( diff --git a/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py b/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py index 52862e1a..19872f0e 100644 --- a/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py @@ -10,7 +10,7 @@ from pyrecest.backend import zeros_like from pyrecest.backend import zeros import unittest - +import numpy.testing as npt from pyrecest.distributions.cart_prod.hypercylindrical_dirac_distribution import ( HypercylindricalDiracDistribution, @@ -44,8 +44,8 @@ def test_covariance(self): def test_apply_function_identity(self): same = self.pwd.apply_function(lambda x: x) - np.testing.assert_array_equal(self.pwd.d, same.d) - np.testing.assert_array_equal(self.pwd.w, same.w) + npt.assert_array_equal(self.pwd.d, same.d) + npt.assert_array_equal(self.pwd.w, same.w) assert self.pwd.lin_dim == same.lin_dim assert self.pwd.bound_dim == same.bound_dim @@ -79,17 +79,17 @@ def f3(x): pwd_rew3 = self.pwd.reweigh(f3) assert isinstance(pwd_rew1, HypercylindricalDiracDistribution) - np.testing.assert_array_equal(pwd_rew1.d, self.pwd.d) - np.testing.assert_array_equal(pwd_rew1.w, f1(self.pwd.d)) + npt.assert_array_equal(pwd_rew1.d, self.pwd.d) + npt.assert_array_equal(pwd_rew1.w, f1(self.pwd.d)) assert isinstance(pwd_rew2, HypercylindricalDiracDistribution) - np.testing.assert_array_equal(pwd_rew2.d, self.pwd.d) - np.testing.assert_array_equal(pwd_rew2.w, self.pwd.w) + npt.assert_array_equal(pwd_rew2.d, self.pwd.d) + npt.assert_array_equal(pwd_rew2.w, self.pwd.w) assert isinstance(pwd_rew3, HypercylindricalDiracDistribution) - np.testing.assert_array_equal(pwd_rew3.d, self.pwd.d) + npt.assert_array_equal(pwd_rew3.d, self.pwd.d) w_new = self.pwd.d[:, 0] * self.pwd.w - np.testing.assert_array_equal(pwd_rew3.w, w_new / sum(w_new)) + npt.assert_array_equal(pwd_rew3.w, w_new / sum(w_new)) def test_sampling(self): random.seed(0) @@ -109,4 +109,4 @@ def test_from_distribution(self): C = array(wishart.rvs(df, scale, random_state=random_gen)) hwn = PartiallyWrappedNormalDistribution(array([1.0, 2.0, 3.0, 4.0]), C, 2) hddist = HypercylindricalDiracDistribution.from_distribution(hwn, 100000) - np.testing.assert_allclose(hddist.hybrid_mean(), hwn.hybrid_mean(), atol=0.2) \ No newline at end of file + npt.assert_allclose(hddist.hybrid_mean(), hwn.hybrid_mean(), atol=0.2) \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py b/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py index 02543887..367a102d 100644 --- a/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py @@ -8,7 +8,7 @@ from pyrecest.backend import array import pyrecest.backend import unittest - +import numpy.testing as npt from pyrecest.distributions import VonMisesFisherDistribution from pyrecest.distributions.hypersphere_subset.hyperspherical_dirac_distribution import ( @@ -32,19 +32,19 @@ def test_sampling(self): nSamples = 5 s = self.hdd.sample(nSamples) self.assertEqual(s.shape, (nSamples, self.d.shape[-1])) - np.testing.assert_array_almost_equal(s, mod(s, 2 * pi)) - np.testing.assert_array_almost_equal( + npt.assert_array_almost_equal(s, mod(s, 2 * pi)) + npt.assert_array_almost_equal( linalg.norm(s, axis=-1), ones(nSamples) ) def test_apply_function(self): same = self.hdd.apply_function(lambda x: x) - np.testing.assert_array_almost_equal(same.d, self.hdd.d, decimal=10) - np.testing.assert_array_almost_equal(same.w, self.hdd.w, decimal=10) + npt.assert_array_almost_equal(same.d, self.hdd.d, decimal=10) + npt.assert_array_almost_equal(same.w, self.hdd.w, decimal=10) mirrored = self.hdd.apply_function(lambda x: -x) - np.testing.assert_array_almost_equal(mirrored.d, -self.hdd.d, decimal=10) - np.testing.assert_array_almost_equal(mirrored.w, self.hdd.w, decimal=10) + npt.assert_array_almost_equal(mirrored.d, -self.hdd.d, decimal=10) + npt.assert_array_almost_equal(mirrored.w, self.hdd.w, decimal=10) def test_reweigh_identity(self): def f(x): @@ -52,8 +52,8 @@ def f(x): twdNew = self.hdd.reweigh(f) self.assertIsInstance(twdNew, HypersphericalDiracDistribution) - np.testing.assert_array_almost_equal(twdNew.d, self.hdd.d) - np.testing.assert_array_almost_equal(twdNew.w, self.hdd.w) + npt.assert_array_almost_equal(twdNew.d, self.hdd.d) + npt.assert_array_almost_equal(twdNew.w, self.hdd.w) def test_reweigh_coord_based(self): def f(x): @@ -61,17 +61,17 @@ def f(x): twdNew = self.hdd.reweigh(f) self.assertIsInstance(twdNew, HypersphericalDiracDistribution) - np.testing.assert_array_almost_equal(twdNew.d, self.hdd.d) + npt.assert_array_almost_equal(twdNew.d, self.hdd.d) self.assertAlmostEqual(sum(twdNew.w), 1, places=10) wNew = self.hdd.d[:, 1] * self.hdd.w - np.testing.assert_array_almost_equal(twdNew.w, wNew / sum(wNew)) + npt.assert_array_almost_equal(twdNew.w, wNew / sum(wNew)) @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") def test_from_distribution(self): random.seed(0) vmf = VonMisesFisherDistribution(array([1.0, 1.0, 1.0]) / sqrt(3), array(1.0)) dirac_dist = HypersphericalDiracDistribution.from_distribution(vmf, 100000) - np.testing.assert_almost_equal( + npt.assert_almost_equal( dirac_dist.mean_direction(), vmf.mean_direction(), decimal=2 ) diff --git a/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py b/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py index 848a5b81..20a1fc81 100644 --- a/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py @@ -10,7 +10,7 @@ from pyrecest.backend import array import copy import unittest - +import numpy.testing as npt from pyrecest.distributions import ( HypertoroidalDiracDistribution, @@ -28,19 +28,19 @@ def setUp(self): def test_init(self): self.assertIsInstance(self.twd, HypertoroidalDiracDistribution) - np.testing.assert_array_almost_equal(self.twd.d, self.d) - np.testing.assert_array_almost_equal(self.twd.w, self.w) + npt.assert_array_almost_equal(self.twd.d, self.d) + npt.assert_array_almost_equal(self.twd.w, self.w) def test_trigonometric_moment(self): m = self.twd.trigonometric_moment(1) m1 = self.twd.marginalize_to_1D(0).trigonometric_moment(1) m2 = self.twd.marginalize_to_1D(1).trigonometric_moment(1) - np.testing.assert_almost_equal(m[0], m1, decimal=10) - np.testing.assert_almost_equal(m[1], m2, decimal=10) - np.testing.assert_almost_equal( + npt.assert_almost_equal(m[0], m1, decimal=10) + npt.assert_almost_equal(m[1], m2, decimal=10) + npt.assert_almost_equal( m[0], sum(self.w * exp(1j * self.d[:, 0])), decimal=10 ) - np.testing.assert_almost_equal( + npt.assert_almost_equal( m[1], sum(self.w * exp(1j * self.d[:, 1])), decimal=10 ) @@ -48,27 +48,27 @@ def test_sample(self): n_samples = 5 s = self.twd.sample(n_samples) self.assertEqual(s.shape, (n_samples, self.d.shape[-1])) - np.testing.assert_array_almost_equal(s, mod(s, 2 * pi)) + npt.assert_array_almost_equal(s, mod(s, 2 * pi)) def test_marginalize_to_1D(self): for i in range(self.d.shape[-1]): wd = self.twd.marginalize_to_1D(i) - np.testing.assert_array_almost_equal(self.twd.w, wd.w) - np.testing.assert_array_almost_equal(wd.d, self.twd.d[:, i]) + npt.assert_array_almost_equal(self.twd.w, wd.w) + npt.assert_array_almost_equal(wd.d, self.twd.d[:, i]) def test_apply_function(self): same = self.twd.apply_function(lambda x: x) - np.testing.assert_array_almost_equal( + npt.assert_array_almost_equal( same.trigonometric_moment(1), self.twd.trigonometric_moment(1) ) shift_offset = array([1.4, -0.3, pi]) shifted = self.twd.apply_function(lambda x: x + shift_offset) - np.testing.assert_almost_equal( + npt.assert_almost_equal( shifted.trigonometric_moment(1)[0], sum(self.w * exp(1j * (self.d[:, 0] + shift_offset[0]))), decimal=10, ) - np.testing.assert_almost_equal( + npt.assert_almost_equal( shifted.trigonometric_moment(1)[1], sum(self.w * exp(1j * (self.d[:, 1] + shift_offset[1]))), decimal=10, @@ -90,8 +90,8 @@ def test_shift(self): s = array([1, -3, 6]) twd_shifted = twd.shift(s) self.assertIsInstance(twd_shifted, HypertoroidalDiracDistribution) - np.testing.assert_array_almost_equal(twd.w, twd_shifted.w) - np.testing.assert_array_almost_equal( + npt.assert_array_almost_equal(twd.w, twd_shifted.w) + npt.assert_array_almost_equal( twd.d, mod(twd_shifted.d - outer(ones_like(w), s), 2 * pi), decimal=10, @@ -112,15 +112,15 @@ def test_to_toroidal_wd(self): twd1 = ToroidalDiracDistribution(copy.copy(hwd.d), copy.copy(hwd.w)) twd2 = hwd.to_toroidal_wd() self.assertIsInstance(twd2, ToroidalDiracDistribution) - np.testing.assert_array_almost_equal(twd1.d, twd2.d, decimal=10) - np.testing.assert_array_almost_equal(twd1.w, twd2.w, decimal=10) + npt.assert_array_almost_equal(twd1.d, twd2.d, decimal=10) + npt.assert_array_almost_equal(twd1.w, twd2.w, decimal=10) def test_marginalization(self): hwd = TestHypertoroidalDiracDistribution.get_pseudorandom_hypertoroidal_wd(2) wd1 = hwd.marginalize_to_1D(0) wd2 = hwd.marginalize_out(1) - np.testing.assert_array_almost_equal(wd1.d, wd2.d) - np.testing.assert_array_almost_equal(wd1.w, wd2.w) + npt.assert_array_almost_equal(wd1.d, wd2.d) + npt.assert_array_almost_equal(wd1.w, wd2.w) if __name__ == "__main__": diff --git a/pyrecest/tests/distributions/test_hypertoroidal_wrapped_normal_distribution.py b/pyrecest/tests/distributions/test_hypertoroidal_wrapped_normal_distribution.py index 96dfe2a0..7809285f 100644 --- a/pyrecest/tests/distributions/test_hypertoroidal_wrapped_normal_distribution.py +++ b/pyrecest/tests/distributions/test_hypertoroidal_wrapped_normal_distribution.py @@ -1,6 +1,6 @@ from pyrecest.backend import array import unittest - +import numpy.testing as npt from pyrecest.distributions import HypertoroidalWNDistribution @@ -18,7 +18,7 @@ def test_pdf(self): expected_values = array( [0.0499028191873498, 0.425359477472412, 0.0499028191873498] ) - np.testing.assert_allclose(pdf_values, expected_values, rtol=1e-12) + npt.assert_allclose(pdf_values, expected_values, rtol=1e-12) if __name__ == "__main__": diff --git a/pyrecest/tests/distributions/test_linear_mixture.py b/pyrecest/tests/distributions/test_linear_mixture.py index dbd8d94c..20b6c044 100644 --- a/pyrecest/tests/distributions/test_linear_mixture.py +++ b/pyrecest/tests/distributions/test_linear_mixture.py @@ -5,7 +5,7 @@ from pyrecest.backend import array import unittest from warnings import catch_warnings, simplefilter - +import numpy.testing as npt from pyrecest.distributions import GaussianDistribution from pyrecest.distributions.nonperiodic.linear_mixture import LinearMixture @@ -40,7 +40,7 @@ def test_pdf(self): x, y = meshgrid(linspace(-2, 2, 100), linspace(-2, 2, 100)) points = column_stack((x.ravel(), y.ravel())) - np.testing.assert_allclose( + npt.assert_allclose( lm.pdf(points), 0.3 * gm1.pdf(points) + 0.7 * gm2.pdf(points), atol=1e-20 ) diff --git a/pyrecest/tests/distributions/test_partially_wrapped_normal_distribution.py b/pyrecest/tests/distributions/test_partially_wrapped_normal_distribution.py index d271a08b..36acea8b 100644 --- a/pyrecest/tests/distributions/test_partially_wrapped_normal_distribution.py +++ b/pyrecest/tests/distributions/test_partially_wrapped_normal_distribution.py @@ -1,7 +1,7 @@ from pyrecest.backend import ones from pyrecest.backend import array import unittest - +import numpy.testing as npt import scipy.linalg from pyrecest.distributions.cart_prod.partially_wrapped_normal_distribution import ( @@ -19,17 +19,17 @@ def test_pdf(self): self.assertEqual(self.dist_2d.pdf(ones((10, 2))).shape, (10,)) def test_hybrid_mean_2d(self): - np.testing.assert_allclose(self.dist_2d.hybrid_mean(), self.mu) + npt.assert_allclose(self.dist_2d.hybrid_mean(), self.mu) def test_hybrid_mean_4d(self): mu = array([5.0, 1.0, 3.0, 4.0]) C = array(scipy.linalg.block_diag([[2.0, 1.0], [1.0, 1.0]], [[2.0, 1.0], [1.0, 1.0]])) dist = PartiallyWrappedNormalDistribution(mu, C, 2) - np.testing.assert_allclose(dist.hybrid_mean(), mu) + npt.assert_allclose(dist.hybrid_mean(), mu) def test_hybrid_moment_2d(self): # Validate against precalculated values - np.testing.assert_allclose( + npt.assert_allclose( self.dist_2d.hybrid_moment(), [0.10435348, -0.35276852, self.mu[-1]] ) diff --git a/pyrecest/tests/distributions/test_sphere_subset_distribution.py b/pyrecest/tests/distributions/test_sphere_subset_distribution.py index 631865e7..08aceb40 100644 --- a/pyrecest/tests/distributions/test_sphere_subset_distribution.py +++ b/pyrecest/tests/distributions/test_sphere_subset_distribution.py @@ -1,7 +1,7 @@ from math import pi from pyrecest.backend import array import unittest - +import numpy.testing as npt from parameterized import parameterized from pyrecest.distributions.hypersphere_subset.abstract_sphere_subset_distribution import ( @@ -31,9 +31,9 @@ def test_cart_to_sph_to_cart(self, mode): ) # The new Cartesian coordinates should be close to the original ones - np.testing.assert_allclose(x_new, x, atol=1e-15) - np.testing.assert_allclose(y_new, y, atol=1e-15) - np.testing.assert_allclose(z_new, z, atol=1e-15) + npt.assert_allclose(x_new, x, atol=1e-15) + npt.assert_allclose(y_new, y, atol=1e-15) + npt.assert_allclose(z_new, z, atol=1e-15) @parameterized.expand( [ @@ -57,5 +57,5 @@ def test_sph_to_cart_to_sph(self, mode): ) # The new spherical coordinates should be close to the original ones - np.testing.assert_allclose(azimuth_new, azimuth, atol=1e-15) - np.testing.assert_allclose(theta_new, theta, atol=1e-15) \ No newline at end of file + npt.assert_allclose(azimuth_new, azimuth, atol=1e-15) + npt.assert_allclose(theta_new, theta, atol=1e-15) \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py index fee0966e..32ce4808 100644 --- a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py +++ b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py @@ -16,6 +16,7 @@ from pyrecest.backend import all from pyrecest.backend import zeros import unittest +import numpy.testing as npt from parameterized import parameterized @@ -390,7 +391,7 @@ def test_basis_function(self, _, coeff_mat, expected_func): linspace(0, 2 * pi, 10), linspace(0, pi, 10) ) x, y, z = AbstractSphericalDistribution.sph_to_cart(phi.ravel(), theta.ravel()) - np.testing.assert_allclose( + npt.assert_allclose( shd.pdf(column_stack([x, y, z])), expected_func(x, y, z), atol=1e-6 ) @@ -659,7 +660,7 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): ) expected_func_vals = expected_func(phi, theta) - np.testing.assert_allclose(vals_to_test, expected_func_vals, atol=1e-6) + npt.assert_allclose(vals_to_test, expected_func_vals, atol=1e-6) @parameterized.expand( [ @@ -839,7 +840,7 @@ def test_conversion(self, _, coeff_mat): linspace(0, 2 * pi, 10), linspace(-pi / 2, pi / 2, 10) ) x, y, z = AbstractSphericalDistribution.sph_to_cart(phi.ravel(), theta.ravel()) - np.testing.assert_allclose( + npt.assert_allclose( rshd.pdf(column_stack((x, y, z))), shd.pdf(column_stack((x, y, z))), atol=1e-6, @@ -920,7 +921,7 @@ def test_conversion(self, _, coeff_mat): ) def test_mean_direction(self, _, input_array, expected_output, fun_to_test): shd = SphericalHarmonicsDistributionComplex(input_array) - np.testing.assert_allclose(fun_to_test(shd), expected_output, atol=1e-10) + npt.assert_allclose(fun_to_test(shd), expected_output, atol=1e-10) def test_from_distribution_via_integral_vmf(self): # Test approximating a VMF @@ -932,16 +933,16 @@ def test_from_distribution_via_integral_vmf(self): linspace(0, 2 * pi, 10), linspace(-pi / 2, pi / 2, 10) ) x, y, z = AbstractSphericalDistribution.sph_to_cart(phi.ravel(), theta.ravel()) - np.testing.assert_allclose( + npt.assert_allclose( shd.mean_direction(), dist.mean_direction(), atol=1e-10 ) - np.testing.assert_allclose( + npt.assert_allclose( shd.mean_direction_numerical(), dist.mean_direction(), atol=1e-10 ) - np.testing.assert_allclose( + npt.assert_allclose( shd.integrate_numerically(), dist.integrate_numerically(), atol=1e-10 ) - np.testing.assert_allclose( + npt.assert_allclose( shd.pdf(column_stack([x, y, z])), dist.pdf(column_stack([x, y, z])), atol=0.001, @@ -951,7 +952,7 @@ def test_from_distribution_via_integral_uniform(self): shd = SphericalHarmonicsDistributionComplex.from_distribution_via_integral( HypersphericalUniformDistribution(2), degree=0 ) - np.testing.assert_allclose(shd.coeff_mat, array([[1 / sqrt(4 * pi)]])) + npt.assert_allclose(shd.coeff_mat, array([[1 / sqrt(4 * pi)]])) def test_transformation_via_integral_shd(self): # Test approximating a spherical harmonic distribution @@ -962,7 +963,7 @@ def test_transformation_via_integral_shd(self): shd = SphericalHarmonicsDistributionComplex.from_function_via_integral_cart( dist.pdf, 1 ) - np.testing.assert_allclose(shd.coeff_mat, dist.coeff_mat, atol=1e-6) + npt.assert_allclose(shd.coeff_mat, dist.coeff_mat, atol=1e-6) def test_convergence(self): no_diffs = 3 @@ -1046,7 +1047,7 @@ def test_convergence(self): ) def test_mean(self, _, coeff_mat, expected_output): shd = SphericalHarmonicsDistributionComplex(coeff_mat) - np.testing.assert_allclose(shd.mean_direction(), expected_output, atol=1e-6) + npt.assert_allclose(shd.mean_direction(), expected_output, atol=1e-6) if __name__ == "__main__": diff --git a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py index 4f1bf524..7722385e 100644 --- a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py +++ b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py @@ -11,7 +11,7 @@ from pyrecest.backend import column_stack import unittest import warnings - +import numpy.testing as npt from parameterized import parameterized from pyrecest.distributions.hypersphere_subset.abstract_spherical_distribution import ( @@ -142,7 +142,7 @@ def test_basis_function(self, name, coeff_mat, result_func): shd = SphericalHarmonicsDistributionReal(1 / sqrt(4 * pi)) shd.coeff_mat = array(coeff_mat) x, y, z = SphericalHarmonicsDistributionRealTest._gen_naive_grid(10) - np.testing.assert_allclose( + npt.assert_allclose( shd.pdf(column_stack((x, y, z))), result_func(x, y, z), rtol=1e-6, @@ -335,7 +335,7 @@ def test_conversion(self, _, coeff_mat): random.rand(10) * pi - pi / 2, ) x, y, z = AbstractSphericalDistribution.sph_to_cart(phi_to_test, theta_to_test) - np.testing.assert_allclose( + npt.assert_allclose( cshd.pdf(column_stack((x, y, z))), rshd.pdf(column_stack((x, y, z))), atol=1e-6, @@ -349,7 +349,7 @@ def test_conversion_to_complex_and_back(self): cshd = rshd.to_spherical_harmonics_distribution_complex() rshd2 = cshd.to_spherical_harmonics_distribution_real() - np.testing.assert_allclose( + npt.assert_allclose( rshd2.coeff_mat, rshd.coeff_mat, atol=1e-6, equal_nan=True ) @@ -360,7 +360,7 @@ def test_integral_analytical(self): warnings.simplefilter("ignore") shd = SphericalHarmonicsDistributionReal(unnormalized_coeffs) - np.testing.assert_allclose( + npt.assert_allclose( shd.integrate_numerically(), shd.integrate(), atol=1e-6 ) diff --git a/pyrecest/tests/distributions/test_toroidal_von_mises_sine_distribution.py b/pyrecest/tests/distributions/test_toroidal_von_mises_sine_distribution.py index da4ca2fd..82611b06 100644 --- a/pyrecest/tests/distributions/test_toroidal_von_mises_sine_distribution.py +++ b/pyrecest/tests/distributions/test_toroidal_von_mises_sine_distribution.py @@ -6,6 +6,7 @@ from pyrecest.backend import array from pyrecest.backend import arange import unittest +import numpy.testing as npt from parameterized import parameterized @@ -18,7 +19,7 @@ class ToroidalVMSineDistributionTest(unittest.TestCase): def setUp(self): self.mu = array([1, 2]) self.kappa = array([0.7, 1.4]) - self.lambda_ = 0.5 + self.lambda_ = array(0.5) self.tvm = ToroidalVonMisesSineDistribution(self.mu, self.kappa, self.lambda_) def test_instance(self): @@ -26,16 +27,16 @@ def test_instance(self): self.assertIsInstance(self.tvm, ToroidalVonMisesSineDistribution) def test_mu_kappa_lambda(self): - np.testing.assert_almost_equal(self.tvm.mu, self.mu, decimal=6) - np.testing.assert_almost_equal(self.tvm.kappa, self.kappa, decimal=6) + npt.assert_almost_equal(self.tvm.mu, self.mu, decimal=6) + npt.assert_almost_equal(self.tvm.kappa, self.kappa, decimal=6) self.assertEqual(self.tvm.lambda_, self.lambda_) def test_integral(self): # test integral - self.assertAlmostEqual(self.tvm.integrate(), 1, delta=1e-5) + self.assertAlmostEqual(self.tvm.integrate(), 1.0, delta=1e-5) def test_trigonometric_moment_numerical(self): - np.testing.assert_almost_equal( + npt.assert_almost_equal( self.tvm.trigonometric_moment_numerical(0), array([1, 1]), decimal=5 ) @@ -74,7 +75,7 @@ def pdf(x): expected = pdf(x) - np.testing.assert_almost_equal(self.tvm.pdf(x), expected, decimal=10) + npt.assert_almost_equal(self.tvm.pdf(x), expected, decimal=10) if __name__ == "__main__": diff --git a/pyrecest/tests/distributions/test_von_mises_distribution.py b/pyrecest/tests/distributions/test_von_mises_distribution.py index e2d89b3a..c99634b8 100644 --- a/pyrecest/tests/distributions/test_von_mises_distribution.py +++ b/pyrecest/tests/distributions/test_von_mises_distribution.py @@ -6,7 +6,7 @@ import matplotlib.pyplot as plt from pyrecest.distributions import VonMisesDistribution - +import numpy.testing as npt matplotlib.use("Agg") @@ -20,7 +20,7 @@ def test_vm_init(self): def test_pdf(self): dist = VonMisesDistribution(2, 1) xs = linspace(1, 7, 7) - np.testing.assert_array_almost_equal( + npt.assert_array_almost_equal( dist.pdf(xs), array( [ diff --git a/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py b/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py index c2c60107..0d29d6ac 100644 --- a/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py +++ b/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py @@ -5,7 +5,7 @@ from pyrecest.backend import all from pyrecest.backend import empty_like import unittest - +import numpy.testing as npt from parameterized import parameterized from pyrecest.distributions import VonMisesFisherDistribution @@ -77,14 +77,14 @@ def test_init_2d(self): mu = mu / linalg.norm(mu) kappa = 10 dist = VonMisesFisherDistribution(mu, kappa) - np.testing.assert_array_almost_equal(dist.C, 7.22562325261744e-05) + npt.assert_array_almost_equal(dist.C, 7.22562325261744e-05) def test_init_3d(self): mu = array([1, 1, 2, -3]) mu = mu / linalg.norm(mu) kappa = 2 dist = VonMisesFisherDistribution(mu, kappa) - np.testing.assert_array_almost_equal(dist.C, 0.0318492506152322) + npt.assert_array_almost_equal(dist.C, 0.0318492506152322) def test_pdf_2d(self): mu = array([1, 1, 2]) @@ -92,7 +92,7 @@ def test_pdf_2d(self): kappa = 10 dist = VonMisesFisherDistribution(mu, kappa) - np.testing.assert_array_almost_equal( + npt.assert_array_almost_equal( dist.pdf(vectors_to_test_2d), array( [ @@ -128,7 +128,7 @@ def test_pdf_3d(self): ) xs = xs_unnorm / linalg.norm(xs_unnorm, axis=1, keepdims=True) - np.testing.assert_array_almost_equal( + npt.assert_array_almost_equal( dist.pdf(xs), array( [ @@ -190,8 +190,8 @@ def test_from_distribution_vmf(self, _, mu, kappa): vmf1 = VonMisesFisherDistribution(mu, kappa) vmf2 = VonMisesFisherDistribution.from_distribution(vmf1) - np.testing.assert_allclose(vmf1.mu, vmf2.mu, rtol=1e-10) - np.testing.assert_allclose(vmf1.kappa, vmf2.kappa, rtol=1e-10) + npt.assert_allclose(vmf1.mu, vmf2.mu, rtol=1e-10) + npt.assert_allclose(vmf1.kappa, vmf2.kappa, rtol=1e-10) def test_from_distribution_dirac(self): dirac_dist = HypersphericalDiracDistribution( @@ -201,7 +201,7 @@ def test_from_distribution_dirac(self): ) vmf = VonMisesFisherDistribution.from_distribution(dirac_dist) - np.testing.assert_allclose(dirac_dist.mean(), vmf.mean()) + npt.assert_allclose(dirac_dist.mean(), vmf.mean()) if __name__ == "__main__": diff --git a/pyrecest/tests/distributions/test_watson_distribution.py b/pyrecest/tests/distributions/test_watson_distribution.py index fdb9daa1..6900126a 100644 --- a/pyrecest/tests/distributions/test_watson_distribution.py +++ b/pyrecest/tests/distributions/test_watson_distribution.py @@ -1,7 +1,7 @@ from pyrecest.backend import linalg from pyrecest.backend import array import unittest - +import numpy.testing as npt from pyrecest.distributions import BinghamDistribution, WatsonDistribution @@ -21,7 +21,7 @@ def test_constructor(self): w = WatsonDistribution(mu, kappa) self.assertIsInstance(w, WatsonDistribution) - np.testing.assert_array_equal(w.mu, mu) + npt.assert_array_equal(w.mu, mu) self.assertEqual(w.kappa, kappa) self.assertEqual(w.input_dim, mu.shape[0]) @@ -43,7 +43,7 @@ def test_pdf(self): ) pdf_values = w.pdf(self.xs) - np.testing.assert_almost_equal(pdf_values, expected_pdf_values, decimal=5) + npt.assert_almost_equal(pdf_values, expected_pdf_values, decimal=5) def test_integrate(self): mu = array([1, 2, 3]) @@ -58,7 +58,7 @@ def test_to_bingham(self): watson_dist = WatsonDistribution(mu, kappa) bingham_dist = watson_dist.to_bingham() self.assertIsInstance(bingham_dist, BinghamDistribution) - np.testing.assert_almost_equal( + npt.assert_almost_equal( watson_dist.pdf(self.xs), bingham_dist.pdf(self.xs), decimal=5 ) diff --git a/pyrecest/tests/distributions/test_wrapped_cauchy_distribution.py b/pyrecest/tests/distributions/test_wrapped_cauchy_distribution.py index b496b99e..021a3659 100644 --- a/pyrecest/tests/distributions/test_wrapped_cauchy_distribution.py +++ b/pyrecest/tests/distributions/test_wrapped_cauchy_distribution.py @@ -2,7 +2,7 @@ from pyrecest.backend import array from pyrecest.backend import arange import unittest - +import numpy.testing as npt from pyrecest.distributions.circle.custom_circular_distribution import ( CustomCircularDistribution, @@ -33,13 +33,13 @@ def pdf_wrapped(x, mu, gamma, terms=2000): lambda xs: array([pdf_wrapped(x, self.mu, self.gamma) for x in xs]) ) - np.testing.assert_allclose( + npt.assert_allclose( dist.pdf(xs=self.xs), custom_wrapped.pdf(xs=self.xs), atol=0.0001 ) def test_cdf(self): dist = WrappedCauchyDistribution(self.mu, self.gamma) - np.testing.assert_allclose( + npt.assert_allclose( dist.cdf(array([1])), dist.integrate(array([0, 1])) ) diff --git a/pyrecest/tests/distributions/test_wrapped_laplace_distribution.py b/pyrecest/tests/distributions/test_wrapped_laplace_distribution.py index eedb8b94..389d8411 100644 --- a/pyrecest/tests/distributions/test_wrapped_laplace_distribution.py +++ b/pyrecest/tests/distributions/test_wrapped_laplace_distribution.py @@ -4,7 +4,7 @@ from pyrecest.backend import arange from pyrecest.backend import array import unittest - +import numpy.testing as npt from pyrecest.distributions.circle.wrapped_laplace_distribution import ( WrappedLaplaceDistribution, @@ -35,12 +35,12 @@ def pdftemp(x): return sum(laplace(z) for z in x + 2.0 * pi * arange(-20, 21)) for x in [0.0, 1.0, 2.0, 3.0, 4.0]: - np.testing.assert_allclose(self.wl.pdf(x), pdftemp(x), rtol=1e-10) + npt.assert_allclose(self.wl.pdf(x), pdftemp(x), rtol=1e-10) def test_integral(self): - np.testing.assert_allclose(self.wl.integrate(), 1.0, rtol=1e-10) - np.testing.assert_allclose(self.wl.integrate_numerically(), 1.0, rtol=1e-10) - np.testing.assert_allclose( + npt.assert_allclose(self.wl.integrate(), 1.0, rtol=1e-10) + npt.assert_allclose(self.wl.integrate_numerically(), 1.0, rtol=1e-10) + npt.assert_allclose( self.wl.integrate(array([0.0, pi])) + self.wl.integrate(array([pi, 2.0 * pi])), 1, rtol=1e-10, @@ -48,14 +48,14 @@ def test_integral(self): def test_angular_moments(self): for i in range(1, 4): - np.testing.assert_allclose( + npt.assert_allclose( self.wl.trigonometric_moment(i), self.wl.trigonometric_moment_numerical(i), rtol=1e-10, ) def test_periodicity(self): - np.testing.assert_allclose( + npt.assert_allclose( self.wl.pdf(linspace(-2 * pi, 0, 100)), self.wl.pdf(linspace(0, 2 * pi, 100)), rtol=1e-10, diff --git a/pyrecest/tests/distributions/test_wrapped_normal_distribution.py b/pyrecest/tests/distributions/test_wrapped_normal_distribution.py index a9d4d086..dbda3b2b 100644 --- a/pyrecest/tests/distributions/test_wrapped_normal_distribution.py +++ b/pyrecest/tests/distributions/test_wrapped_normal_distribution.py @@ -10,7 +10,7 @@ from pyrecest.backend import all from pyrecest.backend import zeros import unittest - +import numpy.testing as npt from pyrecest.distributions import WrappedNormalDistribution @@ -36,7 +36,7 @@ def approx_with_wrapping(x): test_points = [self.mu, self.mu - 1, self.mu + 2] for point in test_points: with self.subTest(x=point): - np.testing.assert_almost_equal( + npt.assert_almost_equal( self.wn.pdf(point), approx_with_wrapping(point), decimal=10 ) diff --git a/pyrecest/tests/filters/test_circular_particle_filter.py b/pyrecest/tests/filters/test_circular_particle_filter.py index e1161c11..c3afefd8 100644 --- a/pyrecest/tests/filters/test_circular_particle_filter.py +++ b/pyrecest/tests/filters/test_circular_particle_filter.py @@ -5,7 +5,7 @@ from pyrecest.backend import allclose from pyrecest.backend import all import unittest - +import numpy.testing as npt from pyrecest.distributions import ( HypertoroidalDiracDistribution, @@ -37,8 +37,8 @@ def test_set_state(self): dist1 = self.filter.filter_state self.assertIsInstance(dist1, HypertoroidalDiracDistribution) self.assertEqual(dist1.dim, 1) - np.testing.assert_almost_equal(self.dist.d, dist1.d) - np.testing.assert_almost_equal(self.dist.w, dist1.w) + npt.assert_almost_equal(self.dist.d, dist1.d) + npt.assert_almost_equal(self.dist.w, dist1.w) def test_sampling(self): positions = arange(0, 1.1, 0.1) @@ -67,7 +67,7 @@ def f(x): dist2_identity = self.filter.filter_state self.assertIsInstance(dist2_identity, HypertoroidalDiracDistribution) self.assertEqual(dist2_identity.dim, 1) - np.testing.assert_almost_equal(dist2.w, dist2_identity.w) + npt.assert_almost_equal(dist2.w, dist2_identity.w) def test_nonlinear_prediction_without_noise(self): # nonlinear test without noise @@ -81,8 +81,8 @@ def f(x): predicted = self.filter.filter_state self.assertIsInstance(predicted, HypertoroidalDiracDistribution) dist_f = self.dist.apply_function(f) - np.testing.assert_almost_equal(predicted.d, dist_f.d, decimal=10) - np.testing.assert_almost_equal(predicted.w, dist_f.w, decimal=10) + npt.assert_almost_equal(predicted.d, dist_f.d, decimal=10) + npt.assert_almost_equal(predicted.w, dist_f.w, decimal=10) def test_update(self): # test update diff --git a/pyrecest/tests/filters/test_euclidean_particle_filter.py b/pyrecest/tests/filters/test_euclidean_particle_filter.py index 40a86928..8e5ae424 100644 --- a/pyrecest/tests/filters/test_euclidean_particle_filter.py +++ b/pyrecest/tests/filters/test_euclidean_particle_filter.py @@ -6,7 +6,7 @@ from pyrecest.backend import zeros_like from pyrecest.backend import zeros import unittest - +import numpy.testing as npt from pyrecest.distributions import GaussianDistribution from pyrecest.filters.euclidean_particle_filter import EuclideanParticleFilter @@ -35,7 +35,7 @@ def test_predict_update_cycle_3d(self): # jscpd:ignore-end self.assertEqual(self.pf.get_point_estimate().shape, (3,)) - np.testing.assert_almost_equal( + npt.assert_almost_equal( self.pf.get_point_estimate(), self.forced_mean, decimal=1 ) @@ -50,7 +50,7 @@ def f(x, w): self.pf.predict_nonlinear_nonadditive(f, samples, weights) est = self.pf.get_point_estimate() self.assertEqual(self.pf.get_point_estimate().shape, (3,)) - np.testing.assert_allclose( + npt.assert_allclose( est, self.prior.mu + mean(samples, axis=0), atol=0.1 ) @@ -67,7 +67,7 @@ def test_predict_update_cycle_3d_forced_particle_pos_no_pred(self): # jscpd:ignore-end self.assertEqual(self.pf.get_point_estimate().shape, (3,)) - np.testing.assert_allclose( + npt.assert_allclose( self.pf.get_point_estimate(), force_first_particle_pos, atol=1e-10 ) diff --git a/pyrecest/tests/filters/test_global_nearest_neighbor.py b/pyrecest/tests/filters/test_global_nearest_neighbor.py index 451bc4be..8fa8e2e3 100644 --- a/pyrecest/tests/filters/test_global_nearest_neighbor.py +++ b/pyrecest/tests/filters/test_global_nearest_neighbor.py @@ -10,6 +10,7 @@ from pyrecest.backend import dstack import pyrecest.backend import unittest +import numpy.testing as npt import scipy @@ -83,11 +84,11 @@ def test_predict_linear(self, name, sys_input): for i in range(3): with self.subTest(i=i): - np.testing.assert_array_equal( + npt.assert_array_equal( tracker.filter_bank[i].get_point_estimate(), self.sys_mat @ self.kfs_init[i].get_point_estimate() + sys_input, ) - np.testing.assert_array_equal( + npt.assert_array_equal( tracker.filter_bank[i].filter_state.C, C_matrices[i] ) @@ -109,23 +110,23 @@ def test_predict_linear_different_mats_and_inputs(self): tracker.predict_linear(sys_mats, sys_noises, sys_inputs) - np.testing.assert_array_equal( + npt.assert_array_equal( tracker.filter_bank[0].filter_state.mu, array([-1.0, 1.0, -1.0, 1.0]) ) - np.testing.assert_array_equal( + npt.assert_array_equal( tracker.filter_bank[1].filter_state.mu, array([2.0, 4.0, 6.0, 8.0]) ) - np.testing.assert_array_equal( + npt.assert_array_equal( tracker.filter_bank[2].filter_state.mu, array([-11.0, -7.0, -5.0, -3.0]) ) - np.testing.assert_array_equal( + npt.assert_array_equal( tracker.filter_bank[0].filter_state.C, scipy.linalg.block_diag([[4.0, 2.0], [2.0, 3.0]], [[8.0, 4.0], [4.0, 5.0]]), ) - np.testing.assert_array_equal( + npt.assert_array_equal( tracker.filter_bank[1].filter_state.C, diag([12.0, 13.0, 14.0, 15.0]) ) - np.testing.assert_array_equal( + npt.assert_array_equal( tracker.filter_bank[2].filter_state.C, scipy.linalg.block_diag([[4.0, 1.0], [1.0, 6.0]], [[10.0, 3.0], [3.0, 8.0]]), ) @@ -144,19 +145,19 @@ def test_association_no_clutter(self): association = tracker.find_association( perfect_meas_ordered, self.meas_mat, eye(2) ) - np.testing.assert_array_equal(association, [0, 1, 2]) + npt.assert_array_equal(association, [0, 1, 2]) # Shift them measurements = np.roll(perfect_meas_ordered, 1, axis=1) association = tracker.find_association(measurements, self.meas_mat, eye(2)) - np.testing.assert_array_equal( + npt.assert_array_equal( measurements[:, association], perfect_meas_ordered ) # Shift them and add a bit of noise measurements = np.roll(perfect_meas_ordered, 1, axis=1) + 0.1 association = tracker.find_association(measurements, self.meas_mat, eye(2)) - np.testing.assert_array_equal( + npt.assert_array_equal( measurements[:, association], perfect_meas_ordered + 0.1 ) @@ -166,7 +167,7 @@ def test_association_no_clutter(self): self.meas_mat, self.all_different_meas_covs, ) - np.testing.assert_array_equal( + npt.assert_array_equal( measurements[:, association], perfect_meas_ordered + 0.1 ) @@ -183,7 +184,7 @@ def test_association_with_clutter(self): ) measurements = column_stack([perfect_meas_ordered, array([3, 2])]) association = tracker.find_association(measurements, self.meas_mat, eye(2)) - np.testing.assert_array_equal(association, [0, 1, 2]) + npt.assert_array_equal(association, [0, 1, 2]) # Shift them and add one measurement measurements = column_stack( @@ -195,7 +196,7 @@ def test_association_with_clutter(self): ] ) association = tracker.find_association(measurements, self.meas_mat, eye(2)) - np.testing.assert_array_equal( + npt.assert_array_equal( measurements[:, association], perfect_meas_ordered ) @@ -203,7 +204,7 @@ def test_association_with_clutter(self): association = tracker.find_association( measurements + 0.1, self.meas_mat, eye(2) ) - np.testing.assert_array_equal( + npt.assert_array_equal( measurements[:, association] + 0.1, perfect_meas_ordered + 0.1 ) @@ -211,7 +212,7 @@ def test_association_with_clutter(self): association = tracker.find_association( measurements + 0.1, self.meas_mat, self.all_different_meas_covs_4 ) - np.testing.assert_array_equal( + npt.assert_array_equal( measurements[:, association] + 0.1, perfect_meas_ordered + 0.1 ) diff --git a/pyrecest/tests/filters/test_random_matrix_tracker.py b/pyrecest/tests/filters/test_random_matrix_tracker.py index d547098b..4d5d76ad 100644 --- a/pyrecest/tests/filters/test_random_matrix_tracker.py +++ b/pyrecest/tests/filters/test_random_matrix_tracker.py @@ -30,23 +30,23 @@ def setUp(self): ) def test_initialization(self): - np.testing.assert_array_equal(self.tracker.kinematic_state, self.initial_state) - np.testing.assert_array_equal(self.tracker.covariance, self.initial_covariance) - np.testing.assert_array_equal(self.tracker.extent, self.initial_extent) + npt.assert_array_equal(self.tracker.kinematic_state, self.initial_state) + npt.assert_array_equal(self.tracker.covariance, self.initial_covariance) + npt.assert_array_equal(self.tracker.extent, self.initial_extent) def test_get_point_estimate(self): expected = concatenate( [self.initial_state, array(self.initial_extent).flatten()] ) - np.testing.assert_array_equal(self.tracker.get_point_estimate(), expected) + npt.assert_array_equal(self.tracker.get_point_estimate(), expected) def test_get_point_estimate_kinematics(self): - np.testing.assert_array_equal( + npt.assert_array_equal( self.tracker.get_point_estimate_kinematics(), self.initial_state ) def test_get_point_estimate_extent(self): - np.testing.assert_array_equal( + npt.assert_array_equal( self.tracker.get_point_estimate_extent(), self.initial_extent ) @@ -65,13 +65,13 @@ def test_predict(self): expected_covariance = self.initial_covariance + Cw expected_extent = self.initial_extent - np.testing.assert_array_almost_equal( + npt.assert_array_almost_equal( self.tracker.kinematic_state, expected_state, decimal=5 ) - np.testing.assert_array_almost_equal( + npt.assert_array_almost_equal( self.tracker.covariance, expected_covariance, decimal=5 ) - np.testing.assert_array_almost_equal( + npt.assert_array_almost_equal( self.tracker.extent, expected_extent, decimal=5 ) @@ -105,20 +105,20 @@ def test_update(self, name, offset, _): mean(ys, axis=1), H, (self.initial_extent + Cv) / ys.shape[1] ) - np.testing.assert_array_almost_equal( + npt.assert_array_almost_equal( self.tracker.kinematic_state, kf.get_point_estimate(), decimal=5 ) - np.testing.assert_array_almost_equal( + npt.assert_array_almost_equal( self.tracker.covariance, kf.filter_state.C, decimal=5 ) # Check if extent has changed as expected if name == "smaller": - np.testing.assert_array_less( + npt.assert_array_less( zeros(2), linalg.eig(self.initial_extent - self.tracker.extent)[0] ) elif name == "larger": - np.testing.assert_array_less( + npt.assert_array_less( zeros(2), linalg.eig(self.tracker.extent - self.initial_extent)[0] ) else: diff --git a/pyrecest/tests/filters/test_toroidal_wrapped_normal_filter.py b/pyrecest/tests/filters/test_toroidal_wrapped_normal_filter.py index 9a0f44aa..ea1d0737 100644 --- a/pyrecest/tests/filters/test_toroidal_wrapped_normal_filter.py +++ b/pyrecest/tests/filters/test_toroidal_wrapped_normal_filter.py @@ -3,7 +3,7 @@ from pyrecest.backend import array import unittest import numpy as np - +import numpy.testing as npt from pyrecest.distributions.hypertorus.toroidal_wrapped_normal_distribution import ( ToroidalWrappedNormalDistribution, @@ -24,8 +24,8 @@ def test_sanity_check(self): curr_filter.filter_state = self.twn twn1 = curr_filter.filter_state self.assertIsInstance(twn1, ToroidalWrappedNormalDistribution) - np.testing.assert_array_almost_equal(twn1.mu, self.twn.mu) - np.testing.assert_array_almost_equal(twn1.C, self.twn.C) + npt.assert_array_almost_equal(twn1.mu, self.twn.mu) + npt.assert_array_almost_equal(twn1.C, self.twn.C) def test_predict_identity(self): """Test identity prediction of the filter.""" @@ -34,7 +34,7 @@ def test_predict_identity(self): curr_filter.predict_identity(self.twn) dist_result = curr_filter.filter_state self.assertIsInstance(dist_result, ToroidalWrappedNormalDistribution) - np.testing.assert_array_almost_equal( + npt.assert_array_almost_equal( dist_result.mu, mod(self.twn.mu + self.twn.mu, 2 * pi) ) - np.testing.assert_array_almost_equal(dist_result.C, self.twn.C + self.twn.C) \ No newline at end of file + npt.assert_array_almost_equal(dist_result.C, self.twn.C + self.twn.C) \ No newline at end of file diff --git a/pyrecest/tests/filters/test_von_mises_filter.py b/pyrecest/tests/filters/test_von_mises_filter.py index 8ad64cf8..66802967 100644 --- a/pyrecest/tests/filters/test_von_mises_filter.py +++ b/pyrecest/tests/filters/test_von_mises_filter.py @@ -1,6 +1,6 @@ import unittest - +import numpy.testing as npt from pyrecest.distributions import VonMisesDistribution from pyrecest.filters.von_mises_filter import VonMisesFilter @@ -34,7 +34,7 @@ def test_update(self): self.curr_filter.set_state(self.vm_prior) self.curr_filter.update_identity(meas_noise, meas) self.assertIsInstance(self.curr_filter.filter_state, VonMisesDistribution) - np.testing.assert_allclose( + npt.assert_allclose( self.curr_filter.get_point_estimate(), (self.vm_prior.mu + meas) / 2 ) self.assertGreater(self.curr_filter.filter_state.kappa, 1.3) diff --git a/pyrecest/tests/filters/test_wrapped_normal_filter.py b/pyrecest/tests/filters/test_wrapped_normal_filter.py index 01a3e3a2..ff90aedc 100644 --- a/pyrecest/tests/filters/test_wrapped_normal_filter.py +++ b/pyrecest/tests/filters/test_wrapped_normal_filter.py @@ -3,7 +3,7 @@ from pyrecest.distributions import WrappedNormalDistribution from pyrecest.filters.wrapped_normal_filter import WrappedNormalFilter - +import numpy.testing as npt class WrappedNormalFilterTest(unittest.TestCase): @@ -31,7 +31,7 @@ def test_update(self): self.wn_filter.update_identity(self.meas_noise, self.wn.mu) wn_identity = self.wn_filter.filter_state self.assertIsInstance(wn_identity, WrappedNormalDistribution) - np.testing.assert_almost_equal(self.wn.mu, wn_identity.mu) + npt.assert_almost_equal(self.wn.mu, wn_identity.mu) self.assertGreater(self.wn.sigma, wn_identity.sigma) # reset filter state for the next test within this function diff --git a/pyrecest/tests/test_evaluation_basic.py b/pyrecest/tests/test_evaluation_basic.py index 155a61d2..d6477e8e 100644 --- a/pyrecest/tests/test_evaluation_basic.py +++ b/pyrecest/tests/test_evaluation_basic.py @@ -41,6 +41,7 @@ ) from pyrecest.filters import HypertoroidalParticleFilter, KalmanFilter from shapely.geometry import Polygon +import numpy.testing as npt class TestEvalationBase(unittest.TestCase): @@ -200,12 +201,12 @@ def dummy_distance_function(x, y): assert len(all_deviations) == len(results) # Validate some of the results - np.testing.assert_allclose( + npt.assert_allclose( # Should be zeros as the lastEstimates match groundtruths all_deviations[0], [0.0, 0.0, 0.0], ) - np.testing.assert_allclose( + npt.assert_allclose( # Should be sqrt(2) away from groundtruths all_deviations[1], [sqrt(2), sqrt(2), sqrt(2)], diff --git a/pyrecest/tests/test_metrics.py b/pyrecest/tests/test_metrics.py index cc57ebe4..ca0c2b51 100644 --- a/pyrecest/tests/test_metrics.py +++ b/pyrecest/tests/test_metrics.py @@ -33,7 +33,7 @@ def test_ANEES_is_close_to_one(self): computed_ANEES = anees(samples, repeated_uncertainties, repeated_groundtruths) # Assert that computed ANEES is close to 1 with a tolerance of 0.05. - np.testing.assert_almost_equal( + npt.assert_almost_equal( computed_ANEES, self.groundtruths.shape[-1], decimal=2 ) From 60bd4f8d5943880fb6882238b0d68af4708d2b51 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Sat, 21 Oct 2023 23:18:26 +0100 Subject: [PATCH 074/232] More --- .../abstract_hypercylindrical_distribution.py | 4 ++-- .../partially_wrapped_normal_distribution.py | 4 ++-- ...abstract_hypersphere_subset_distribution.py | 4 ++-- ...est_toroidal_von_mises_sine_distribution.py | 18 ++++++++++-------- 4 files changed, 16 insertions(+), 14 deletions(-) diff --git a/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py b/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py index fa9a62ce..9496263d 100644 --- a/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py +++ b/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py @@ -259,13 +259,13 @@ def mode_numerical(self, starting_point=None): # Define bounds for the optimization bounds = [ - (0, 2 * pi) if i < self.bound_dim else (-float('inf'), float('inf')) + (0.0, 2.0 * pi) if i < self.bound_dim else (-float('inf'), float('inf')) for i in range(self.bound_dim + self.lin_dim) ] # Perform the optimization res = scipy.optimize.minimize( - lambda x: -self.pdf(x), starting_point, bounds=bounds + lambda x: -self.pdf(array(x)), starting_point, bounds=bounds ) # Check if the optimization might have stopped early diff --git a/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py b/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py index 04f60834..b7ae72db 100644 --- a/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py +++ b/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py @@ -57,12 +57,12 @@ def __init__( def pdf(self, xs, m: Union[int, int32, int64] = 3): xs = atleast_2d(xs) if self.bound_dim > 0: - xs[:, : self.bound_dim] = mod(xs[:, : self.bound_dim], 2 * pi) + xs[:, : self.bound_dim] = mod(xs[:, : self.bound_dim], 2.0 * pi) assert xs.shape[-1] == self.input_dim # generate multiples for wrapping - multiples = array(range(-m, m + 1)) * 2 * pi + multiples = array(range(-m, m + 1)) * 2.0 * pi # create meshgrid for all combinations of multiples mesh = array(meshgrid(*[multiples] * self.bound_dim)).reshape( diff --git a/pyrecest/tests/distributions/test_abstract_hypersphere_subset_distribution.py b/pyrecest/tests/distributions/test_abstract_hypersphere_subset_distribution.py index 263fe5e1..d925bd9c 100644 --- a/pyrecest/tests/distributions/test_abstract_hypersphere_subset_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hypersphere_subset_distribution.py @@ -44,8 +44,8 @@ def fangles_2d(phi1, phi2): ).T ) - phi1_test = [1.0, 2.0, 0.0, 0.3, 1.1] - phi2_test = [2.0, 3.0, 0.1, 3.0, 1.1] + phi1_test = array([1.0, 2.0, 0.0, 0.3, 1.1]) + phi2_test = array([2.0, 3.0, 0.1, 3.0, 1.1]) npt.assert_array_almost_equal( pdf_hyperspherical(phi1_test, phi2_test), fangles_2d(phi1_test, phi2_test) diff --git a/pyrecest/tests/distributions/test_toroidal_von_mises_sine_distribution.py b/pyrecest/tests/distributions/test_toroidal_von_mises_sine_distribution.py index 82611b06..d1c9991d 100644 --- a/pyrecest/tests/distributions/test_toroidal_von_mises_sine_distribution.py +++ b/pyrecest/tests/distributions/test_toroidal_von_mises_sine_distribution.py @@ -5,6 +5,7 @@ from pyrecest.backend import cos from pyrecest.backend import array from pyrecest.backend import arange +import pyrecest.backend import unittest import numpy.testing as npt @@ -17,7 +18,7 @@ class ToroidalVMSineDistributionTest(unittest.TestCase): def setUp(self): - self.mu = array([1, 2]) + self.mu = array([1.0, 2.0]) self.kappa = array([0.7, 1.4]) self.lambda_ = array(0.5) self.tvm = ToroidalVonMisesSineDistribution(self.mu, self.kappa, self.lambda_) @@ -31,13 +32,14 @@ def test_mu_kappa_lambda(self): npt.assert_almost_equal(self.tvm.kappa, self.kappa, decimal=6) self.assertEqual(self.tvm.lambda_, self.lambda_) + @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") def test_integral(self): # test integral self.assertAlmostEqual(self.tvm.integrate(), 1.0, delta=1e-5) def test_trigonometric_moment_numerical(self): npt.assert_almost_equal( - self.tvm.trigonometric_moment_numerical(0), array([1, 1]), decimal=5 + self.tvm.trigonometric_moment_numerical(0), array([1.0, 1.0]), decimal=5 ) # jscpd:ignore-start @@ -55,14 +57,14 @@ def _unnormalized_pdf(self, xs): @parameterized.expand( [ - (array([3, 2]),), - (array([1, 4]),), - (array([5, 6]),), - (array([-3, 11]),), - (array([[5, 1], [6, 3]]),), + (array([3.0, 2.0]),), + (array([1.0, 4.0]),), + (array([5.0, 6.0]),), + (array([-3.0, 11.0]),), + (array([[5.0, 1.0], [6.0, 3.0]]),), ( column_stack( - (arange(0, 2 * pi, 0.1), arange(1 * pi, 3 * pi, 0.1)) + (arange(0.0, 2.0 * pi, 0.1), arange(1.0 * pi, 3.0 * pi, 0.1)) ), ), ] From 5e91bbcf8d380a84aae185ec9058ff3104a49766 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Sat, 21 Oct 2023 23:27:38 +0100 Subject: [PATCH 075/232] Back --- .../abstract_hypersphere_subset_distribution.py | 1 + .../abstract_hyperspherical_distribution.py | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py index ed4084e0..8f873038 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py @@ -15,6 +15,7 @@ from pyrecest.backend import int32 from pyrecest.backend import zeros from pyrecest.backend import empty +from pyrecest.backend import array from abc import abstractmethod from collections.abc import Callable diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py index 1a23eef5..5edabc41 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py @@ -12,6 +12,7 @@ from pyrecest.backend import int64 from pyrecest.backend import int32 from pyrecest.backend import zeros +from pyrecest.backend import meshgrid from collections.abc import Callable import matplotlib.pyplot as plt @@ -208,10 +209,9 @@ def total_variation_distance(self, other: "AbstractHypersphericalDistribution"): @staticmethod def create_sphere(faces): - phi, theta = np.mgrid[ - 0.0 : pi : complex(0, faces), # noqa: E203 - 0.0 : 2.0 * pi : complex(0, faces), # noqa: E203 - ] + phi_linspace = linspace(0.0, pi, faces) + theta_linspace = linspace(0.0, 2.0 * pi, faces) + phi, theta = meshgrid(phi_linspace, theta_linspace, indexing='ij') x = sin(phi) * cos(theta) y = sin(phi) * sin(theta) z = cos(phi) From 9fa3c254f7dd1855e3ec28e9e2f7d1ad4e79bf4a Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Sun, 22 Oct 2023 02:32:35 +0100 Subject: [PATCH 076/232] more --- pyrecest/_backend/__init__.py | 24 ++++++++++------- pyrecest/_backend/numpy/__init__.py | 24 ++++++++++------- pyrecest/_backend/pytorch/__init__.py | 26 +++++++++++-------- .../abstract_dirac_distribution.py | 3 ++- ...stract_spherical_harmonics_distribution.py | 19 ++++++-------- .../spherical_harmonics_distribution_real.py | 8 +++--- .../nonperiodic/gaussian_distribution.py | 3 ++- pyrecest/sampling/hypertoroidal_sampler.py | 4 +-- ...pertoroidal_wrapped_normal_distribution.py | 2 +- .../distributions/test_linear_mixture.py | 4 +-- ...pherical_harmonics_distribution_complex.py | 2 +- pyrecest/tests/test_hypertoroidal_sampler.py | 3 +-- 12 files changed, 67 insertions(+), 55 deletions(-) diff --git a/pyrecest/_backend/__init__.py b/pyrecest/_backend/__init__.py index 62613e8b..7829bc19 100644 --- a/pyrecest/_backend/__init__.py +++ b/pyrecest/_backend/__init__.py @@ -166,16 +166,20 @@ def get_backend_name(): "zeros", "zeros_like", "trapz", - "diag", # Added for pyrecest - "diff", # Added for pyrecest - "apply_along_axis", # Added for pyrecest - "nonzero", # Added for pyrecest - "column_stack", # Added for pyrecest - "conj", # Added for pyrecest - "atleast_1d", # Added for pyrecest - "atleast_2d", # Added for pyrecest - "dstack", # Added for pyrecest - "full", # Added for pyrecest + # The ones below are for pyrecest + "diag", + "diff", + "apply_along_axis", + "nonzero", + "column_stack", + "conj", + "atleast_1d", + "atleast_2d", + "dstack", + "full", + "isreal", + "triu", + "kron", ], "autodiff": [ "custom_gradient", diff --git a/pyrecest/_backend/numpy/__init__.py b/pyrecest/_backend/numpy/__init__.py index 68aa655a..4a66357c 100644 --- a/pyrecest/_backend/numpy/__init__.py +++ b/pyrecest/_backend/numpy/__init__.py @@ -71,16 +71,20 @@ vstack, where, zeros_like, - diag, # For pyrecest - diff, # For pyrecest - apply_along_axis, # For pyrecest - nonzero, # For pyrecest - column_stack, # For pyrecest - conj, # For pyrecest - atleast_1d, # For pyrecest - atleast_2d, # For pyrecest - dstack, # For pyrecest - full, # For pyrecest + # The ones below are for pyrecest + diag, + diff, + apply_along_axis, + nonzero, + column_stack, + conj, + atleast_1d, + atleast_2d, + dstack, + full, + isreal, + triu, + kron, ) from scipy.special import erf, gamma, polygamma # NOQA diff --git a/pyrecest/_backend/pytorch/__init__.py b/pyrecest/_backend/pytorch/__init__.py index b43f91c0..6fd1dd12 100644 --- a/pyrecest/_backend/pytorch/__init__.py +++ b/pyrecest/_backend/pytorch/__init__.py @@ -33,15 +33,19 @@ ones_like, polygamma, quantile, - diag, # For pyrecest - diff, # For pyrecest - nonzero, # For pyrecest - column_stack, # For pyrecest - conj, # For pyrecest - atleast_1d, # For pyrecest - atleast_2d, # For pyrecest - dstack, # For pyrecest - full, # For pyrecest + # The ones below are for pyrecest + diag, + diff, + nonzero, + column_stack, + conj, + atleast_1d, + atleast_2d, + dstack, + full, + isreal, + triu, + kron, ) from torch import repeat_interleave as repeat from torch import ( @@ -391,13 +395,13 @@ def trace(x): return _torch.einsum("...ii", x) -def linspace(start, stop, endpoint=True, num=50, dtype=None): +def linspace(start, stop, num=50, endpoint=True, dtype=None): start_is_array = _torch.is_tensor(start) stop_is_array = _torch.is_tensor(stop) if not (start_is_array or stop_is_array) and endpoint: return _torch.linspace(start=start, end=stop, steps=num, dtype=dtype) - elif not (start_is_array or stop_is_array): # Added for pyrecest + elif not (start_is_array or stop_is_array): # Added for pyrecest return _torch.arange(start=start, end=stop, step=(stop-start)/num, dtype=dtype) else: raise ValueError("endpoint=False not supported for vectors") diff --git a/pyrecest/distributions/abstract_dirac_distribution.py b/pyrecest/distributions/abstract_dirac_distribution.py index 46702860..ce0f9796 100644 --- a/pyrecest/distributions/abstract_dirac_distribution.py +++ b/pyrecest/distributions/abstract_dirac_distribution.py @@ -9,6 +9,7 @@ from pyrecest.backend import int64 from pyrecest.backend import int32 from pyrecest.backend import apply_along_axis +from pyrecest.backend import array import copy import warnings from collections.abc import Callable @@ -81,7 +82,7 @@ def reweigh(self, f: Callable) -> "AbstractDiracDistribution": return dist def sample(self, n: Union[int, int32, int64]): - samples = random.choice(self.d, size=n, p=self.w) + samples = random.choice(self.d, size=array(n), p=self.w) return samples def entropy(self) -> float: diff --git a/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py index 09160d65..c84c2bfb 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py @@ -30,17 +30,14 @@ def __init__(self, coeff_mat, transformation="identity"): # Ignore irrelevant entries of coeff_mat and set to NaN n = coeff_mat.shape[0] - coeff_mat = coeff_mat + np.block( - [ - [ - zeros((n - 1, 1)), - np.kron( - np.triu(full((n - 1, n - 1), float('NaN'))), array([[1, 1]]) - ), - ], - [zeros((1, 2 * n - 1))], - ] - ) + for i in range(n): + # Calculate the range of column indices to keep + start_idx = n - i - 1 + end_idx = n + i + + # Set the elements outside this range to NaN + coeff_mat[i, :start_idx] = float('nan') + coeff_mat[i, end_idx:] = float('nan') AbstractOrthogonalBasisDistribution.__init__(self, coeff_mat, transformation) def pdf(self, xs): diff --git a/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_real.py b/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_real.py index c180d787..506dc6d5 100644 --- a/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_real.py +++ b/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_real.py @@ -5,6 +5,8 @@ from pyrecest.backend import imag from pyrecest.backend import all from pyrecest.backend import zeros +from pyrecest.backend import isreal + # pylint: disable=E0611 @@ -18,7 +20,7 @@ class SphericalHarmonicsDistributionReal(AbstractSphericalHarmonicsDistribution): def __init__(self, coeff_mat, transformation="identity"): - if not all(np.isreal(coeff_mat)): + if not all(isreal(coeff_mat)): raise ValueError("Coefficients must be real") AbstractSphericalHarmonicsDistribution.__init__(self, coeff_mat, transformation) @@ -27,11 +29,11 @@ def real_spherical_harmonic_basis_function(n, m, theta, phi): y_lm = sph_harm(m, n, phi, theta) if m < 0: - y_nm_real = -sqrt(2) * imag(y_lm) + y_nm_real = -sqrt(2.0) * imag(y_lm) elif m == 0: y_nm_real = real(y_lm) else: - y_nm_real = (-1) ** m * sqrt(2) * real(y_lm) + y_nm_real = (-1) ** m * sqrt(2.0) * real(y_lm) return y_nm_real diff --git a/pyrecest/distributions/nonperiodic/gaussian_distribution.py b/pyrecest/distributions/nonperiodic/gaussian_distribution.py index 26af2395..a0536831 100644 --- a/pyrecest/distributions/nonperiodic/gaussian_distribution.py +++ b/pyrecest/distributions/nonperiodic/gaussian_distribution.py @@ -14,8 +14,9 @@ class GaussianDistribution(AbstractLinearDistribution): def __init__(self, mu, C, check_validity=True): + assert ndim(mu) == 1, "mu must be 1-dimensional" + assert ndim(C) == 2, "C must be 2-dimensional" AbstractLinearDistribution.__init__(self, dim=mu.shape[0]) - assert ndim(mu) <= 1 assert ( 1 == mu.shape[0] == C.shape[0] or mu.shape[0] == C.shape[0] == C.shape[1] ), "Size of C invalid" diff --git a/pyrecest/sampling/hypertoroidal_sampler.py b/pyrecest/sampling/hypertoroidal_sampler.py index fac6ba77..4fc17cd6 100644 --- a/pyrecest/sampling/hypertoroidal_sampler.py +++ b/pyrecest/sampling/hypertoroidal_sampler.py @@ -23,7 +23,7 @@ def get_grid(self, grid_density_parameter: int): """ Returns an equidistant grid of points on the circle [0,2*pi). """ - points = linspace(0, 2 * pi, grid_density_parameter, endpoint=False) + points = linspace(0.0, 2.0 * pi, grid_density_parameter, endpoint=False) # Set it to the middle of the interval instead of the start - points += (2 * pi / grid_density_parameter) / 2 + points += (2.0 * pi / grid_density_parameter) / 2.0 return points \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_hypertoroidal_wrapped_normal_distribution.py b/pyrecest/tests/distributions/test_hypertoroidal_wrapped_normal_distribution.py index 7809285f..61452543 100644 --- a/pyrecest/tests/distributions/test_hypertoroidal_wrapped_normal_distribution.py +++ b/pyrecest/tests/distributions/test_hypertoroidal_wrapped_normal_distribution.py @@ -7,7 +7,7 @@ class TestHypertoroidalWNDistribution(unittest.TestCase): def test_pdf(self): - mu = array([[1], [2]]) + mu = array([1, 2]) C = array([[0.5, 0.1], [0.1, 0.3]]) hwn = HypertoroidalWNDistribution(mu, C) diff --git a/pyrecest/tests/distributions/test_linear_mixture.py b/pyrecest/tests/distributions/test_linear_mixture.py index 20b6c044..636b7197 100644 --- a/pyrecest/tests/distributions/test_linear_mixture.py +++ b/pyrecest/tests/distributions/test_linear_mixture.py @@ -17,8 +17,8 @@ def test_constructor_warning(self): simplefilter("always") LinearMixture( [ - GaussianDistribution(array(1), array(1)), - GaussianDistribution(array(50), array(1)), + GaussianDistribution(array([1]), array([1])), + GaussianDistribution(array([[50]]), array([1])), ], array([0.3, 0.7]), ) diff --git a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py index 32ce4808..617f8376 100644 --- a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py +++ b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py @@ -388,7 +388,7 @@ def test_basis_function(self, _, coeff_mat, expected_func): shd = SphericalHarmonicsDistributionComplex(1 / sqrt(4 * pi)) shd.coeff_mat = coeff_mat phi, theta = meshgrid( - linspace(0, 2 * pi, 10), linspace(0, pi, 10) + linspace(0.0, 2 * pi, 10), linspace(0.0, pi, 10) ) x, y, z = AbstractSphericalDistribution.sph_to_cart(phi.ravel(), theta.ravel()) npt.assert_allclose( diff --git a/pyrecest/tests/test_hypertoroidal_sampler.py b/pyrecest/tests/test_hypertoroidal_sampler.py index 3a201aa9..4f27aed8 100644 --- a/pyrecest/tests/test_hypertoroidal_sampler.py +++ b/pyrecest/tests/test_hypertoroidal_sampler.py @@ -35,8 +35,7 @@ def test_get_grid(self): self.assertTrue(all(grid_points < 2 * pi)) # Check that the grid points are equidistant - diff = diff(grid_points) - self.assertAlmostEqual(std(diff), 0, places=5) + self.assertAlmostEqual(std(diff(grid_points)), 0, places=5) if __name__ == "__main__": From f10770e9bd6b1911ba9d9b2f6ec8a1813fc209fa Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Sun, 22 Oct 2023 02:52:34 +0100 Subject: [PATCH 077/232] More... --- pyrecest/distributions/abstract_dirac_distribution.py | 2 +- .../distributions/test_linear_dirac_distribution.py | 2 +- pyrecest/tests/distributions/test_linear_mixture.py | 4 ++-- .../test_toroidal_uniform_distribution.py | 2 ++ .../test_toroidal_von_mises_sine_distribution.py | 10 +++++----- pyrecest/tests/test_hypertoroidal_sampler.py | 2 +- 6 files changed, 12 insertions(+), 10 deletions(-) diff --git a/pyrecest/distributions/abstract_dirac_distribution.py b/pyrecest/distributions/abstract_dirac_distribution.py index ce0f9796..57363c0e 100644 --- a/pyrecest/distributions/abstract_dirac_distribution.py +++ b/pyrecest/distributions/abstract_dirac_distribution.py @@ -82,7 +82,7 @@ def reweigh(self, f: Callable) -> "AbstractDiracDistribution": return dist def sample(self, n: Union[int, int32, int64]): - samples = random.choice(self.d, size=array(n), p=self.w) + samples = random.choice(self.d, size=array(self.dim, n), p=self.w) return samples def entropy(self) -> float: diff --git a/pyrecest/tests/distributions/test_linear_dirac_distribution.py b/pyrecest/tests/distributions/test_linear_dirac_distribution.py index 506ca3c6..ab5c350d 100644 --- a/pyrecest/tests/distributions/test_linear_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_linear_dirac_distribution.py @@ -17,7 +17,7 @@ class LinearDiracDistributionTest(unittest.TestCase): def test_from_distribution(self): random.seed(0) C = wishart.rvs(3, eye(3)) - hwn = GaussianDistribution(array([1, 2, 3]), C) + hwn = GaussianDistribution(array([1, 2, 3]), array(C)) hwd = LinearDiracDistribution.from_distribution(hwn, 100000) self.assertTrue(allclose(hwd.mean(), hwn.mean(), atol=0.005)) self.assertTrue(allclose(hwd.covariance(), hwn.covariance(), rtol=0.01)) diff --git a/pyrecest/tests/distributions/test_linear_mixture.py b/pyrecest/tests/distributions/test_linear_mixture.py index 636b7197..19da99b3 100644 --- a/pyrecest/tests/distributions/test_linear_mixture.py +++ b/pyrecest/tests/distributions/test_linear_mixture.py @@ -17,8 +17,8 @@ def test_constructor_warning(self): simplefilter("always") LinearMixture( [ - GaussianDistribution(array([1]), array([1])), - GaussianDistribution(array([[50]]), array([1])), + GaussianDistribution(array([1]), array([[1]])), + GaussianDistribution(array([50]), array([[1]])), ], array([0.3, 0.7]), ) diff --git a/pyrecest/tests/distributions/test_toroidal_uniform_distribution.py b/pyrecest/tests/distributions/test_toroidal_uniform_distribution.py index f8b1aded..92242177 100644 --- a/pyrecest/tests/distributions/test_toroidal_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_toroidal_uniform_distribution.py @@ -5,6 +5,7 @@ from pyrecest.backend import allclose from pyrecest.backend import all from pyrecest.backend import zeros +import pyrecest.backend import unittest @@ -65,6 +66,7 @@ def test_mean_direction(self): "Hypertoroidal uniform distributions do not have a unique mean", ) + @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") def test_entropy(self): self.assertAlmostEqual( self.tud.entropy(), self.tud.entropy_numerical(), delta=1e-10 diff --git a/pyrecest/tests/distributions/test_toroidal_von_mises_sine_distribution.py b/pyrecest/tests/distributions/test_toroidal_von_mises_sine_distribution.py index d1c9991d..1eb02af9 100644 --- a/pyrecest/tests/distributions/test_toroidal_von_mises_sine_distribution.py +++ b/pyrecest/tests/distributions/test_toroidal_von_mises_sine_distribution.py @@ -28,8 +28,8 @@ def test_instance(self): self.assertIsInstance(self.tvm, ToroidalVonMisesSineDistribution) def test_mu_kappa_lambda(self): - npt.assert_almost_equal(self.tvm.mu, self.mu, decimal=6) - npt.assert_almost_equal(self.tvm.kappa, self.kappa, decimal=6) + npt.assert_allclose(self.tvm.mu, self.mu) + npt.assert_allclose(self.tvm.kappa, self.kappa) self.assertEqual(self.tvm.lambda_, self.lambda_) @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") @@ -38,8 +38,8 @@ def test_integral(self): self.assertAlmostEqual(self.tvm.integrate(), 1.0, delta=1e-5) def test_trigonometric_moment_numerical(self): - npt.assert_almost_equal( - self.tvm.trigonometric_moment_numerical(0), array([1.0, 1.0]), decimal=5 + npt.assert_allclose( + self.tvm.trigonometric_moment_numerical(0), array([1.0, 1.0]) ) # jscpd:ignore-start @@ -77,7 +77,7 @@ def pdf(x): expected = pdf(x) - npt.assert_almost_equal(self.tvm.pdf(x), expected, decimal=10) + npt.assert_allclose(self.tvm.pdf(x), expected) if __name__ == "__main__": diff --git a/pyrecest/tests/test_hypertoroidal_sampler.py b/pyrecest/tests/test_hypertoroidal_sampler.py index 4f27aed8..645788a2 100644 --- a/pyrecest/tests/test_hypertoroidal_sampler.py +++ b/pyrecest/tests/test_hypertoroidal_sampler.py @@ -35,7 +35,7 @@ def test_get_grid(self): self.assertTrue(all(grid_points < 2 * pi)) # Check that the grid points are equidistant - self.assertAlmostEqual(std(diff(grid_points)), 0, places=5) + self.assertAlmostEqual(std(diff(grid_points)), 0.0, places=5) if __name__ == "__main__": From 2e9efaf19e767571fc7c54be20a269f14afddcb7 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Sun, 22 Oct 2023 04:24:57 +0100 Subject: [PATCH 078/232] More --- pyrecest/_backend/pytorch/random.py | 2 +- .../distributions/abstract_dirac_distribution.py | 2 +- .../abstract_hypersphere_subset_distribution.py | 4 ++-- .../abstract_hypertoroidal_distribution.py | 3 ++- .../hypertorus/hypertoroidal_dirac_distribution.py | 2 +- .../test_hypertoroidal_dirac_distribution.py | 2 +- pyrecest/tests/test_hypertoroidal_sampler.py | 12 ++++++------ 7 files changed, 14 insertions(+), 13 deletions(-) diff --git a/pyrecest/_backend/pytorch/random.py b/pyrecest/_backend/pytorch/random.py index b538a432..6a32144f 100644 --- a/pyrecest/_backend/pytorch/random.py +++ b/pyrecest/_backend/pytorch/random.py @@ -18,7 +18,7 @@ def choice(a, size=None, replace=True, p=None): p = _torch.tensor(p, dtype=_torch.float32) p = p / p.sum() # Normalize probabilities - indices = _torch.multinomial(p, num_samples=_torch.prod(size), replacement=True) + indices = _torch.multinomial(p, num_samples=_torch.prod(_torch.tensor(size)), replacement=True) else: indices = _torch.randint(0, len(a), size) diff --git a/pyrecest/distributions/abstract_dirac_distribution.py b/pyrecest/distributions/abstract_dirac_distribution.py index 57363c0e..e24918bd 100644 --- a/pyrecest/distributions/abstract_dirac_distribution.py +++ b/pyrecest/distributions/abstract_dirac_distribution.py @@ -82,7 +82,7 @@ def reweigh(self, f: Callable) -> "AbstractDiracDistribution": return dist def sample(self, n: Union[int, int32, int64]): - samples = random.choice(self.d, size=array(self.dim, n), p=self.w) + samples = random.choice(self.d, size=(self.dim, n), p=self.w) return samples def entropy(self) -> float: diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py index 8f873038..afeeea18 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py @@ -149,7 +149,7 @@ def g_1d(phi): if dim == 2: def g_2d(phi1, phi2): - return f_hypersph_coords(phi1, phi2) * sin(phi2) + return f_hypersph_coords(array(phi1), array(phi2)) * sin(phi2) return g_2d if dim == 3: @@ -226,7 +226,7 @@ def integrate_fun_over_domain_part( elif dim == 2: def g_2d(phi1, phi2): - return f_hypersph_coords(phi1, phi2) * sin(phi2) + return f_hypersph_coords(array(phi1), array(phi2)) * sin(phi2) i, _ = nquad( g_2d, diff --git a/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py b/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py index 8253a37d..53efb22a 100644 --- a/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py +++ b/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py @@ -18,6 +18,7 @@ from pyrecest.backend import int64 from pyrecest.backend import int32 from pyrecest.backend import zeros +from pyrecest.backend import minimum import pyrecest.backend import numbers from collections.abc import Callable @@ -163,7 +164,7 @@ def angular_error(alpha, beta): diff = abs(alpha - beta) # Calculate the angular error - e = np.minimum(diff, 2.0 * pi - diff) + e = minimum(diff, 2.0 * pi - diff) return e diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py b/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py index 28ea3745..a5850906 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py @@ -87,7 +87,7 @@ def marginalize_out(self, dimensions: int | list[int]): remaining_dims = list(range(self.dim)) remaining_dims = [dim for dim in remaining_dims if dim != dimensions] - return CircularDiracDistribution(self.d[:, remaining_dims], self.w) + return CircularDiracDistribution(self.d[:, remaining_dims].squeeze(), self.w) def shift(self, shift_by) -> "HypertoroidalDiracDistribution": assert shift_by.shape[-1] == self.dim diff --git a/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py b/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py index 20a1fc81..97fc561f 100644 --- a/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py @@ -48,7 +48,7 @@ def test_sample(self): n_samples = 5 s = self.twd.sample(n_samples) self.assertEqual(s.shape, (n_samples, self.d.shape[-1])) - npt.assert_array_almost_equal(s, mod(s, 2 * pi)) + npt.assert_array_almost_equal(s, mod(s, 2.0 * pi)) def test_marginalize_to_1D(self): for i in range(self.d.shape[-1]): diff --git a/pyrecest/tests/test_hypertoroidal_sampler.py b/pyrecest/tests/test_hypertoroidal_sampler.py index 645788a2..bd5d72cb 100644 --- a/pyrecest/tests/test_hypertoroidal_sampler.py +++ b/pyrecest/tests/test_hypertoroidal_sampler.py @@ -3,7 +3,7 @@ from pyrecest.backend import std from pyrecest.backend import all import unittest - +import numpy.testing as npt from pyrecest.sampling.hypertoroidal_sampler import CircularUniformSampler @@ -20,8 +20,8 @@ def test_sample_stochastic(self): self.assertEqual(samples.shape[0], n_samples) # Check that all samples are within the range [0, 2*pi) - self.assertTrue(all(samples >= 0)) - self.assertTrue(all(samples < 2 * pi)) + self.assertTrue(all(samples >= 0.0)) + self.assertTrue(all(samples < 2.0 * pi)) def test_get_grid(self): grid_density_parameter = 100 @@ -31,11 +31,11 @@ def test_get_grid(self): self.assertEqual(grid_points.shape[0], grid_density_parameter) # Check that all grid points are within the range [0, 2*pi) - self.assertTrue(all(grid_points >= 0)) - self.assertTrue(all(grid_points < 2 * pi)) + self.assertTrue(all(grid_points >= 0.0)) + self.assertTrue(all(grid_points < 2.0 * pi)) # Check that the grid points are equidistant - self.assertAlmostEqual(std(diff(grid_points)), 0.0, places=5) + npt.assert_array_almost_equal(std(diff(grid_points)), 0.0) if __name__ == "__main__": From f5d5e8d5ba468a107bd1af730a5973b4f8ed843d Mon Sep 17 00:00:00 2001 From: github-actions Date: Sun, 22 Oct 2023 03:27:26 +0000 Subject: [PATCH 079/232] Update requirements.txt --- poetry.lock | 12 ++++++------ requirements-dev.txt | 4 ++-- requirements.txt | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/poetry.lock b/poetry.lock index 52541aed..67fb8c9d 100644 --- a/poetry.lock +++ b/poetry.lock @@ -68,13 +68,13 @@ tomli = {version = "*", markers = "python_version < \"3.11\""} [[package]] name = "beartype" -version = "0.16.3" +version = "0.16.4" description = "Unbearably fast runtime type checking in pure Python." optional = false python-versions = ">=3.8.0" files = [ - {file = "beartype-0.16.3-py3-none-any.whl", hash = "sha256:dc7b3fd28d4998771b4ff8eb41eccb70aa665a8dd505b8db43ba03c191450dd6"}, - {file = "beartype-0.16.3.tar.gz", hash = "sha256:085591b5b77807229b65a137fd473c6891c45287fe0ca6565b3250dead00380b"}, + {file = "beartype-0.16.4-py3-none-any.whl", hash = "sha256:64865952f9dff1e17f22684b3c7286fc79754553b47eaefeb1286224ae8c1bd9"}, + {file = "beartype-0.16.4.tar.gz", hash = "sha256:1ada89cf2d6eb30eb6e156eed2eb5493357782937910d74380918e53c2eae0bf"}, ] [package.extras] @@ -406,13 +406,13 @@ woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] [[package]] name = "fsspec" -version = "2023.9.2" +version = "2023.10.0" description = "File-system specification" optional = false python-versions = ">=3.8" files = [ - {file = "fsspec-2023.9.2-py3-none-any.whl", hash = "sha256:603dbc52c75b84da501b9b2ec8c11e1f61c25984c4a0dda1f129ef391fbfc9b4"}, - {file = "fsspec-2023.9.2.tar.gz", hash = "sha256:80bfb8c70cc27b2178cc62a935ecf242fc6e8c3fb801f9c571fc01b1e715ba7d"}, + {file = "fsspec-2023.10.0-py3-none-any.whl", hash = "sha256:346a8f024efeb749d2a5fca7ba8854474b1ff9af7c3faaf636a4548781136529"}, + {file = "fsspec-2023.10.0.tar.gz", hash = "sha256:330c66757591df346ad3091a53bd907e15348c2ba17d63fd54f5c39c4457d2a5"}, ] [package.extras] diff --git a/requirements-dev.txt b/requirements-dev.txt index 1dc0d91b..1555d530 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,6 +1,6 @@ astropy==5.3.4 ; python_version >= "3.10" and python_version < "3.13" autopep8==2.0.4 ; python_version >= "3.10" and python_version < "3.13" -beartype==0.16.3 ; python_version >= "3.10" and python_version < "3.13" +beartype==0.16.4 ; python_version >= "3.10" and python_version < "3.13" certifi==2023.7.22 ; python_version >= "3.10" and python_version < "3.13" charset-normalizer==3.3.0 ; python_version >= "3.10" and python_version < "3.13" colorama==0.4.6 ; python_version >= "3.10" and python_version < "3.13" and (sys_platform == "win32" or platform_system == "Windows") @@ -10,7 +10,7 @@ exceptiongroup==1.1.3 ; python_version >= "3.10" and python_version < "3.11" filelock==3.12.4 ; python_version >= "3.10" and python_version < "3.13" filterpy==1.4.5 ; python_version >= "3.10" and python_version < "3.13" fonttools==4.43.1 ; python_version >= "3.10" and python_version < "3.13" -fsspec==2023.9.2 ; python_version >= "3.10" and python_version < "3.13" +fsspec==2023.10.0 ; python_version >= "3.10" and python_version < "3.13" healpy==1.16.6 ; python_version >= "3.10" and python_version < "3.13" idna==3.4 ; python_version >= "3.10" and python_version < "3.13" iniconfig==2.0.0 ; python_version >= "3.10" and python_version < "3.13" diff --git a/requirements.txt b/requirements.txt index 69691cb2..ee5650ae 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ astropy==5.3.4 ; python_version >= "3.10" and python_version < "3.13" -beartype==0.16.3 ; python_version >= "3.10" and python_version < "3.13" +beartype==0.16.4 ; python_version >= "3.10" and python_version < "3.13" certifi==2023.7.22 ; python_version >= "3.10" and python_version < "3.13" charset-normalizer==3.3.0 ; python_version >= "3.10" and python_version < "3.13" colorama==0.4.6 ; python_version >= "3.10" and python_version < "3.13" and platform_system == "Windows" From 29bbf9e6c0ec25667be6c6e99408b0d728e12067 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Sun, 22 Oct 2023 04:33:24 +0100 Subject: [PATCH 080/232] More.............. --- pyrecest/_backend/__init__.py | 1 + pyrecest/_backend/numpy/__init__.py | 1 + pyrecest/_backend/pytorch/__init__.py | 1 + pyrecest/filters/von_mises_filter.py | 4 ++-- pyrecest/tests/filters/test_von_mises_filter.py | 7 ++++--- 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/pyrecest/_backend/__init__.py b/pyrecest/_backend/__init__.py index 7829bc19..219c4d09 100644 --- a/pyrecest/_backend/__init__.py +++ b/pyrecest/_backend/__init__.py @@ -180,6 +180,7 @@ def get_backend_name(): "isreal", "triu", "kron", + "angle", ], "autodiff": [ "custom_gradient", diff --git a/pyrecest/_backend/numpy/__init__.py b/pyrecest/_backend/numpy/__init__.py index 4a66357c..b219d6b0 100644 --- a/pyrecest/_backend/numpy/__init__.py +++ b/pyrecest/_backend/numpy/__init__.py @@ -85,6 +85,7 @@ isreal, triu, kron, + angle, ) from scipy.special import erf, gamma, polygamma # NOQA diff --git a/pyrecest/_backend/pytorch/__init__.py b/pyrecest/_backend/pytorch/__init__.py index 6fd1dd12..30659616 100644 --- a/pyrecest/_backend/pytorch/__init__.py +++ b/pyrecest/_backend/pytorch/__init__.py @@ -46,6 +46,7 @@ isreal, triu, kron, + angle, ) from torch import repeat_interleave as repeat from torch import ( diff --git a/pyrecest/filters/von_mises_filter.py b/pyrecest/filters/von_mises_filter.py index 9ba0bdae..f136724a 100644 --- a/pyrecest/filters/von_mises_filter.py +++ b/pyrecest/filters/von_mises_filter.py @@ -59,7 +59,7 @@ def update_identity(self, vmMeas: VonMisesDistribution, z=0.0): vmMeas (VMDistribution) : distribution of additive noise z : measurement in [0, 2pi) """ - assert np.size(z) == 1, "z must be a scalar" + assert z.shape in ((), (1,)), "z must be a scalar" if vmMeas.mu != 0.0: warning_message = ( "The measurement noise is not centered at 0.0. " @@ -69,6 +69,6 @@ def update_identity(self, vmMeas: VonMisesDistribution, z=0.0): ) warnings.warn(warning_message) - muWnew = mod(z - vmMeas.mu, 2 * pi) + muWnew = mod(z - vmMeas.mu, 2.0 * pi) vmMeasShifted = VonMisesDistribution(muWnew, vmMeas.kappa) self.filter_state = self.filter_state.multiply(vmMeasShifted) \ No newline at end of file diff --git a/pyrecest/tests/filters/test_von_mises_filter.py b/pyrecest/tests/filters/test_von_mises_filter.py index 66802967..3ed33dac 100644 --- a/pyrecest/tests/filters/test_von_mises_filter.py +++ b/pyrecest/tests/filters/test_von_mises_filter.py @@ -1,4 +1,5 @@ import unittest +from pyrecest.backend import array import numpy.testing as npt from pyrecest.distributions import VonMisesDistribution @@ -28,14 +29,14 @@ def test_prediction(self): self.assertLess(self.curr_filter.filter_state.kappa, 1.3) def test_update(self): - meas_noise = VonMisesDistribution(0, 1.3) - meas = 1.1 + meas_noise = VonMisesDistribution(0.0, 1.3) + meas = array(1.1) self.curr_filter.set_state(self.vm_prior) self.curr_filter.update_identity(meas_noise, meas) self.assertIsInstance(self.curr_filter.filter_state, VonMisesDistribution) npt.assert_allclose( - self.curr_filter.get_point_estimate(), (self.vm_prior.mu + meas) / 2 + self.curr_filter.get_point_estimate(), (self.vm_prior.mu + meas) / 2.0 ) self.assertGreater(self.curr_filter.filter_state.kappa, 1.3) From f70e3c56a88027ba0e740edcf3a2208e27ca3793 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Sun, 22 Oct 2023 04:34:24 +0100 Subject: [PATCH 081/232] More.... --- .../hypertorus/abstract_hypertoroidal_distribution.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py b/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py index 53efb22a..1ac7463b 100644 --- a/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py +++ b/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py @@ -11,6 +11,7 @@ from pyrecest.backend import log from pyrecest.backend import linspace from pyrecest.backend import isnan +from pyrecest.backend import angle from pyrecest.backend import cos from pyrecest.backend import array from pyrecest.backend import arange @@ -231,7 +232,7 @@ def mean(self): def mean_direction(self): a = self.trigonometric_moment(1) - m = mod(np.angle(a), 2.0 * pi) + m = mod(angle(a), 2.0 * pi) return m def mode(self): From 28206bca9813f20163f0b7629ad59cfc82e9019a Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Sun, 22 Oct 2023 04:51:45 +0100 Subject: [PATCH 082/232] More... --- .../abstract_spherical_harmonics_distribution.py | 4 ++-- .../spherical_harmonics_distribution_complex.py | 3 ++- .../hypertorus/hypertoroidal_uniform_distribution.py | 4 +++- .../test_spherical_harmonics_distribution_complex.py | 2 +- .../distributions/test_toroidal_uniform_distribution.py | 2 +- .../test_toroidal_wrapped_normal_distribution.py | 6 ++++-- 6 files changed, 13 insertions(+), 8 deletions(-) diff --git a/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py index c84c2bfb..ecce5faa 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py @@ -73,13 +73,13 @@ def normalize_in_place(self): def integrate(self): if self.transformation == "identity": - int_val = self.coeff_mat[0, 0] * sqrt(4 * pi) + int_val = self.coeff_mat[0, 0] * sqrt(4.0 * pi) elif self.transformation == "sqrt": int_val = norm(self.coeff_mat[~isnan(self.coeff_mat)]) ** 2 else: raise ValueError("No analytical formula for normalization available") - assert abs(imag(int_val) < 1e-8) + assert abs(imag(int_val)) < 1e-8 return real(int_val) def truncate(self, degree): diff --git a/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py b/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py index d79ca422..f24c4e5f 100644 --- a/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py +++ b/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py @@ -3,6 +3,7 @@ from pyrecest.backend import conj from pyrecest.backend import column_stack from pyrecest.backend import linalg +from pyrecest.backend import complex128 from math import pi from pyrecest.backend import sqrt from pyrecest.backend import sin @@ -44,7 +45,7 @@ def value(self, xs): return self.value_sph(phi, theta) def value_sph(self, phi, theta): - vals = zeros(theta.shape[0], dtype=complex) + vals = zeros((theta.shape[0],), dtype=complex128) for n_curr in range(self.coeff_mat.shape[0]): for m_curr in range(-n_curr, n_curr + 1): # Evaluate it for all query points at once diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_uniform_distribution.py b/pyrecest/distributions/hypertorus/hypertoroidal_uniform_distribution.py index 2a38092d..ed4d6961 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_uniform_distribution.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_uniform_distribution.py @@ -24,7 +24,9 @@ def pdf(self, xs): :param xs: Values at which to evaluate the PDF :returns: PDF evaluated at xs """ - return 1 / self.get_manifold_size() * ones(xs.shape[0]) + assert self.dim == xs.shape[-1] + n_inputs = xs.shape[0] if xs.ndim == 2 else 1 + return 1.0 / self.get_manifold_size() * ones(n_inputs) def trigonometric_moment(self, n: Union[int, int32, int64]): """ diff --git a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py index 617f8376..b949c59d 100644 --- a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py +++ b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py @@ -967,7 +967,7 @@ def test_transformation_via_integral_shd(self): def test_convergence(self): no_diffs = 3 - dist = VonMisesFisherDistribution(array([0, -1, 0]), 1) + dist = VonMisesFisherDistribution(array([0.0, -1.0, 0.0]), 1.0) diffs = zeros(no_diffs) for i in range(0, no_diffs): diff --git a/pyrecest/tests/distributions/test_toroidal_uniform_distribution.py b/pyrecest/tests/distributions/test_toroidal_uniform_distribution.py index 92242177..56a65280 100644 --- a/pyrecest/tests/distributions/test_toroidal_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_toroidal_uniform_distribution.py @@ -17,7 +17,7 @@ class TestToroidalUniformDistribution(unittest.TestCase): def setUp(self): self.tud = ToroidalUniformDistribution() - self.x = tile(array([[1, 2, 3, 4, 5, 6]]), (2, 1)) + self.x = tile(array([[1.0, 2.0, 3.0, 4.0, 5.0, 6.0]]), (2, 1)) def test_pdf(self): self.assertTrue( diff --git a/pyrecest/tests/distributions/test_toroidal_wrapped_normal_distribution.py b/pyrecest/tests/distributions/test_toroidal_wrapped_normal_distribution.py index f7b4f351..d70bc27f 100644 --- a/pyrecest/tests/distributions/test_toroidal_wrapped_normal_distribution.py +++ b/pyrecest/tests/distributions/test_toroidal_wrapped_normal_distribution.py @@ -4,6 +4,7 @@ from pyrecest.backend import allclose from pyrecest.backend import all import unittest +import pyrecest.backend from pyrecest.distributions.hypertorus.toroidal_wrapped_normal_distribution import ( @@ -13,7 +14,7 @@ class TestToroidalWrappedNormalDistribution(unittest.TestCase): def setUp(self): - self.mu = array([1, 2]) + self.mu = array([1.0, 2.0]) self.C = array([[1.3, -0.9], [-0.9, 1.2]]) self.twn = ToroidalWrappedNormalDistribution(self.mu, self.C) @@ -22,10 +23,11 @@ def test_sanity_check(self): self.assertTrue(allclose(self.twn.mu, self.mu)) self.assertTrue(allclose(self.twn.C, self.C)) + @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") def test_integrate(self): self.assertAlmostEqual(self.twn.integrate(), 1, delta=1e-5) self.assertTrue( - allclose(self.twn.trigonometric_moment(0), array([1, 1]), rtol=1e-5) + allclose(self.twn.trigonometric_moment(0), array([1.0, 1.0]), rtol=1e-5) ) def test_sampling(self): From a8d7545c126aa92e302fb9b147b88ca7173e3199 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Sun, 22 Oct 2023 04:58:15 +0100 Subject: [PATCH 083/232] More --- .../spherical_harmonics_distribution_complex.py | 15 ++++++++------- ...st_spherical_harmonics_distribution_complex.py | 2 +- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py b/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py index f24c4e5f..f30782e8 100644 --- a/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py +++ b/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py @@ -133,7 +133,7 @@ def _fun_cart_to_fun_sph(fun_cart): def fun_sph(phi, theta): x, y, z = AbstractSphericalDistribution.sph_to_cart( - np.ravel(phi), np.ravel(theta) + phi.ravel(), theta.ravel() ) vals = fun_cart(column_stack((x, y, z))) return reshape(vals, shape(theta)) @@ -157,31 +157,32 @@ def from_function_via_integral_sph(fun, degree, transformation="identity"): else: raise ValueError("Transformation not supported") - coeff_mat = full((degree + 1, 2 * degree + 1), float('NaN'), dtype=complex) + coeff_mat = full((degree + 1, 2 * degree + 1), float('NaN'), dtype=complex128) def real_part(phi, theta, n, m): return real( fun_with_trans(array(phi), array(theta)) - * conj(sph_harm(m, n, phi, theta)) + * conj(array(sph_harm(m, n, phi, theta))) * sin(theta) ) def imag_part(phi, theta, n, m): return imag( fun_with_trans(array(phi), array(theta)) - * conj(sph_harm(m, n, phi, theta)) + * conj(array(sph_harm(m, n, phi, theta))) * sin(theta) ) for n in range(degree + 1): # Use n instead of l to comply with PEP 8 for m in range(-n, n + 1): real_integral, _ = scipy.integrate.nquad( - real_part, [[0, 2 * pi], [0, pi]], args=(n, m) + real_part, [[0.0, 2.0 * pi], [0.0, pi]], args=(n, m) ) imag_integral, _ = scipy.integrate.nquad( - imag_part, [[0, 2 * pi], [0, pi]], args=(n, m) + imag_part, [[0.0, 2.0 * pi], [0.0, pi]], args=(n, m) ) - + real_integral = array(real_integral) + imag_integral = array(imag_integral) if isnan(real_integral) or isnan(imag_integral): print(f"Integration failed for l={n}, m={m}") diff --git a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py index b949c59d..5aa415b6 100644 --- a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py +++ b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py @@ -977,7 +977,7 @@ def test_convergence(self): diffs[i] = shd.total_variation_distance_numerical(dist) # Check if the deviation from true density is decreasing - self.assertTrue(all(diff(diffs) < 0)) + self.assertTrue(all(diff(diffs) < 0.0)) @parameterized.expand( [ From 786f0f07461b58d00f725c089138e74d17c4830d Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Sun, 22 Oct 2023 05:07:37 +0100 Subject: [PATCH 084/232] More... --- .../test_von_mises_fisher_distribution.py | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py b/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py index 0d29d6ac..67cfbf4e 100644 --- a/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py +++ b/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py @@ -27,11 +27,11 @@ class TestVonMisesFisherDistribution(unittest.TestCase): def setUp(self): - self.mu = array([1, 2, 3]) + self.mu = array([1.0, 2.0, 3.0]) self.mu = self.mu / linalg.norm(self.mu) self.kappa = 2 self.vmf = VonMisesFisherDistribution(self.mu, self.kappa) - self.other = VonMisesFisherDistribution(array([0, 0, 1]), self.kappa / 3) + self.other = VonMisesFisherDistribution(array([0.0, 0.0, 1.0]), self.kappa / 3.0) def test_vmf_distribution_3d_sanity_check(self): self.assertIsInstance(self.vmf, VonMisesFisherDistribution) @@ -50,10 +50,10 @@ def test_vmf_distribution_3d_integral(self): def test_vmf_distribution_3d_multiplication(self): vmf_mul = self.vmf.multiply(self.other) vmf_mul2 = self.other.multiply(self.vmf) - c = vmf_mul.pdf(array([1, 0, 0])) / ( - self.vmf.pdf(array([1, 0, 0])) * self.other.pdf(array([1, 0, 0])) + c = vmf_mul.pdf(array([1.0, 0.0, 0.0])) / ( + self.vmf.pdf(array([1.0, 0.0, 0.0])) * self.other.pdf(array([1.0, 0.0, 0.0])) ) - x = array([0, 1, 0]) + x = array([0.0, 1.0, 0.0]) self.assertAlmostEqual( self.vmf.pdf(x) * self.other.pdf(x) * c, vmf_mul.pdf(x), delta=1e-10 ) @@ -73,23 +73,23 @@ def test_vmf_distribution_3d_convolve(self): ) def test_init_2d(self): - mu = array([1, 1, 2]) + mu = array([1.0, 1.0, 2.0]) mu = mu / linalg.norm(mu) - kappa = 10 + kappa = 10.0 dist = VonMisesFisherDistribution(mu, kappa) npt.assert_array_almost_equal(dist.C, 7.22562325261744e-05) def test_init_3d(self): - mu = array([1, 1, 2, -3]) + mu = array([1.0, 1.0, 2.0, -3.0]) mu = mu / linalg.norm(mu) - kappa = 2 + kappa = 2.0 dist = VonMisesFisherDistribution(mu, kappa) npt.assert_array_almost_equal(dist.C, 0.0318492506152322) def test_pdf_2d(self): - mu = array([1, 1, 2]) + mu = array([1.0, 1.0, 2.0]) mu = mu / linalg.norm(mu) - kappa = 10 + kappa = 10.0 dist = VonMisesFisherDistribution(mu, kappa) npt.assert_array_almost_equal( @@ -107,23 +107,23 @@ def test_pdf_2d(self): ) def test_pdf_3d(self): - mu = array([1, 1, 2, -3]) + mu = array([1.0, 1.0, 2.0, -3.0]) mu = mu / linalg.norm(mu) - kappa = 2 + kappa = 2.0 dist = VonMisesFisherDistribution(mu, kappa) xs_unnorm = array( [ - [1, 0, 0, 0], - [0, 1, 0, 0], - [0, 0, 1, 0], - [0, 0, 0, 1], - [1, 1, 0, 0], - [1, -1, 0, 0], - [1, 0, 1, 0], - [1, 0, -1, 0], - [1, 0, 0, 1], - [1, 0, 0, -1], + [1.0, 0.0, 0.0, 0.0], + [0.0, 1.0, 0.0, 0.0], + [0.0, 0.0, 1.0, 0.0], + [0.0, 0.0, 0.0, 1.0], + [1.0, 1.0, 0.0, 0.0], + [1.0, -1.0, 0.0, 0.0], + [1.0, 0.0, 1.0, 0.0], + [1.0, 0.0, -1.0, 0.0], + [1.0, 0.0, 0.0, 1.0], + [1.0, 0.0, 0.0, -1.0], ] ) xs = xs_unnorm / linalg.norm(xs_unnorm, axis=1, keepdims=True) From 5d0e217438a2e6c1a6877e67a4cb1403d2e92b37 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Sun, 22 Oct 2023 05:24:46 +0100 Subject: [PATCH 085/232] More............ --- pyrecest/_backend/__init__.py | 1 + pyrecest/_backend/numpy/__init__.py | 1 + pyrecest/_backend/pytorch/__init__.py | 1 + .../circle/wrapped_cauchy_distribution.py | 3 ++- .../test_von_mises_fisher_distribution.py | 18 +++++++++--------- .../distributions/test_watson_distribution.py | 14 +++++++------- .../test_wrapped_cauchy_distribution.py | 6 +++--- .../test_wrapped_normal_distribution.py | 4 ++-- .../filters/test_toroidal_particle_filter.py | 8 ++++---- .../filters/test_von_mises_fisher_filter.py | 4 ++-- 10 files changed, 32 insertions(+), 28 deletions(-) diff --git a/pyrecest/_backend/__init__.py b/pyrecest/_backend/__init__.py index 219c4d09..8848591b 100644 --- a/pyrecest/_backend/__init__.py +++ b/pyrecest/_backend/__init__.py @@ -181,6 +181,7 @@ def get_backend_name(): "triu", "kron", "angle", + "arctan", ], "autodiff": [ "custom_gradient", diff --git a/pyrecest/_backend/numpy/__init__.py b/pyrecest/_backend/numpy/__init__.py index b219d6b0..42d7babf 100644 --- a/pyrecest/_backend/numpy/__init__.py +++ b/pyrecest/_backend/numpy/__init__.py @@ -86,6 +86,7 @@ triu, kron, angle, + arctan, ) from scipy.special import erf, gamma, polygamma # NOQA diff --git a/pyrecest/_backend/pytorch/__init__.py b/pyrecest/_backend/pytorch/__init__.py index 30659616..1d398d11 100644 --- a/pyrecest/_backend/pytorch/__init__.py +++ b/pyrecest/_backend/pytorch/__init__.py @@ -47,6 +47,7 @@ triu, kron, angle, + arctan, ) from torch import repeat_interleave as repeat from torch import ( diff --git a/pyrecest/distributions/circle/wrapped_cauchy_distribution.py b/pyrecest/distributions/circle/wrapped_cauchy_distribution.py index e5b82c2a..b3ea9885 100644 --- a/pyrecest/distributions/circle/wrapped_cauchy_distribution.py +++ b/pyrecest/distributions/circle/wrapped_cauchy_distribution.py @@ -7,6 +7,7 @@ from pyrecest.backend import exp from pyrecest.backend import cosh from pyrecest.backend import cos +from pyrecest.backend import arctan from .abstract_circular_distribution import AbstractCircularDistribution @@ -34,7 +35,7 @@ def coth(x): return 1 / tanh(x) assert xs.ndim == 1 - return np.arctan(coth(self.gamma / 2) * tan((xs - self.mu) / 2)) / pi + return arctan(coth(self.gamma / 2.0) * tan((xs - self.mu) / 2.0)) / pi def trigonometric_moment(self, n): m = exp(1j * n * self.mu - abs(n) * self.gamma) diff --git a/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py b/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py index 67cfbf4e..4338a936 100644 --- a/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py +++ b/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py @@ -147,15 +147,15 @@ def test_pdf_3d(self): ) def test_mean_direction(self): - mu = 1 / sqrt(2) * array([1, 1, 0]) + mu = 1.0 / sqrt(2.0) * array([1.0, 1.0, 0.0]) vmf = VonMisesFisherDistribution(mu, 1) self.assertTrue(allclose(vmf.mean_direction(), mu, atol=1e-13)) def _test_hellinger_distance_helper( self, dist1, dist2, delta=1e-10, numerical_delta=1e-10 ): - self.assertAlmostEqual(dist1.hellinger_distance(dist1), 0, delta=delta) - self.assertAlmostEqual(dist2.hellinger_distance(dist2), 0, delta=delta) + self.assertAlmostEqual(dist1.hellinger_distance(dist1), 0.0, delta=delta) + self.assertAlmostEqual(dist2.hellinger_distance(dist2), 0.0, delta=delta) self.assertAlmostEqual( dist1.hellinger_distance(dist2), dist1.hellinger_distance_numerical(dist2), @@ -169,21 +169,21 @@ def _test_hellinger_distance_helper( def test_hellinger_distance_2d(self): # 2D - vmf1 = VonMisesFisherDistribution(array([1, 0]), 0.9) - vmf2 = VonMisesFisherDistribution(array([0, 1]), 1.7) + vmf1 = VonMisesFisherDistribution(array([1.0, 0.0]), 0.9) + vmf2 = VonMisesFisherDistribution(array([0.0, 1.0]), 1.7) self._test_hellinger_distance_helper(vmf1, vmf2) def test_hellinger_distance_3d(self): # 3D - vmf1 = VonMisesFisherDistribution(array([1, 0, 0]), 0.6) + vmf1 = VonMisesFisherDistribution(array([1.0, 0.0, 0.0]), 0.6) mu2 = array([1, 2, 3]) vmf2 = VonMisesFisherDistribution(mu2 / linalg.norm(mu2), 2.1) self._test_hellinger_distance_helper(vmf1, vmf2, numerical_delta=1e-6) @parameterized.expand( [ - ("2D_case", array([-1, 0, 0]), 1.3), - ("3D_case", array([0, 1, 0, 0]), 0.5), + ("2D_case", array([-1.0, 0.0, 0.0]), 1.3), + ("3D_case", array([0.0, 1.0, 0.0, 0.0]), 0.5), ] ) def test_from_distribution_vmf(self, _, mu, kappa): @@ -196,7 +196,7 @@ def test_from_distribution_vmf(self, _, mu, kappa): def test_from_distribution_dirac(self): dirac_dist = HypersphericalDiracDistribution( array( - [[0, 0, 1], [0, 1, 0], [1, 0, 0], [0, 1, 1] / linalg.norm([0, 1, 1])] + [[0.0, 0.0, 1.0], [0.0, 1.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 1.0] / linalg.norm([0.0, 1.0, 1.0])] ) ) vmf = VonMisesFisherDistribution.from_distribution(dirac_dist) diff --git a/pyrecest/tests/distributions/test_watson_distribution.py b/pyrecest/tests/distributions/test_watson_distribution.py index 6900126a..b1175ffb 100644 --- a/pyrecest/tests/distributions/test_watson_distribution.py +++ b/pyrecest/tests/distributions/test_watson_distribution.py @@ -9,15 +9,15 @@ class TestWatsonDistribution(unittest.TestCase): def setUp(self): self.xs = array( - [[1, 0, 0], [1, 2, 2], [0, 1, 0], [0, 0, 1], [1, 1, 1], [-1, -1, -1]], + [[1.0, 0.0, 0.0], [1.0, 2.0, 2.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0], [1.0, 1.0, 1.0], [-1.0, -1.0, -1.0]], dtype=float, ) self.xs = self.xs / linalg.norm(self.xs, axis=1, keepdims=True) def test_constructor(self): - mu = array([1, 2, 3]) + mu = array([1.0, 2.0, 3.0]) mu = mu / linalg.norm(mu) - kappa = 2 + kappa = 2.0 w = WatsonDistribution(mu, kappa) self.assertIsInstance(w, WatsonDistribution) @@ -26,9 +26,9 @@ def test_constructor(self): self.assertEqual(w.input_dim, mu.shape[0]) def test_pdf(self): - mu = array([1, 2, 3]) + mu = array([1.0, 2.0, 3.0]) mu = mu / linalg.norm(mu) - kappa = 2 + kappa = 2.0 w = WatsonDistribution(mu, kappa) expected_pdf_values = array( @@ -46,9 +46,9 @@ def test_pdf(self): npt.assert_almost_equal(pdf_values, expected_pdf_values, decimal=5) def test_integrate(self): - mu = array([1, 2, 3]) + mu = array([1.0, 2.0, 3.0]) mu = mu / linalg.norm(mu) - kappa = 2 + kappa = 2.0 w = WatsonDistribution(mu, kappa) self.assertAlmostEqual(w.integrate(), 1, delta=1e-5) diff --git a/pyrecest/tests/distributions/test_wrapped_cauchy_distribution.py b/pyrecest/tests/distributions/test_wrapped_cauchy_distribution.py index 021a3659..4a456250 100644 --- a/pyrecest/tests/distributions/test_wrapped_cauchy_distribution.py +++ b/pyrecest/tests/distributions/test_wrapped_cauchy_distribution.py @@ -14,7 +14,7 @@ class WrappedCauchyDistributionTest(unittest.TestCase): def setUp(self): - self.mu = 0 + self.mu = 0.0 self.gamma = 0.5 self.xs = arange(10) @@ -25,7 +25,7 @@ def pdf_wrapped(x, mu, gamma, terms=2000): summation = 0 for k in range(-terms, terms + 1): summation += gamma / ( - pi * (gamma**2 + (x - mu + 2 * pi * k) ** 2) + pi * (gamma**2 + (x - mu + 2.0 * pi * k) ** 2) ) return summation @@ -40,7 +40,7 @@ def pdf_wrapped(x, mu, gamma, terms=2000): def test_cdf(self): dist = WrappedCauchyDistribution(self.mu, self.gamma) npt.assert_allclose( - dist.cdf(array([1])), dist.integrate(array([0, 1])) + dist.cdf(array([1.0])), dist.integrate(array([0.0, 1.0])) ) diff --git a/pyrecest/tests/distributions/test_wrapped_normal_distribution.py b/pyrecest/tests/distributions/test_wrapped_normal_distribution.py index dbda3b2b..240a1521 100644 --- a/pyrecest/tests/distributions/test_wrapped_normal_distribution.py +++ b/pyrecest/tests/distributions/test_wrapped_normal_distribution.py @@ -53,9 +53,9 @@ def test_pdf_with_large_sigma_is_uniform(self): """ Test that the pdf with large sigma is approximately a uniform distribution. """ - wn_large_sigma = WrappedNormalDistribution(0, 100) + wn_large_sigma = WrappedNormalDistribution(0.0, 100.0) x = arange(0, 7) - fx = ones_like(x) / (2 * pi) + fx = ones_like(x) / (2.0 * pi) self.assertTrue(allclose(wn_large_sigma.pdf(x), fx, rtol=1e-10)) diff --git a/pyrecest/tests/filters/test_toroidal_particle_filter.py b/pyrecest/tests/filters/test_toroidal_particle_filter.py index ffba8314..d6d78c0d 100644 --- a/pyrecest/tests/filters/test_toroidal_particle_filter.py +++ b/pyrecest/tests/filters/test_toroidal_particle_filter.py @@ -19,19 +19,19 @@ class ToroidalParticleFilterTest(unittest.TestCase): def test_toroidal_particle_filter(self): random.seed(0) C = array([[0.7, 0.4], [0.4, 0.6]]) - mu = array([1, 1]) + pi / 2 + mu = array([1.0, 1.0]) + pi / 2.0 hwnd = ToroidalWrappedNormalDistribution(mu, C) tpf = ToroidalParticleFilter(200) tpf.set_state(hwnd) - forced_mean = array([1, 1]) + forced_mean = array([1.0, 1.0]) for _ in range(50): tpf.predict_identity( - HypertoroidalWrappedNormalDistribution(array([0, 0]), C) + HypertoroidalWrappedNormalDistribution(array([0.0, 0.0]), C) ) for _ in range(3): tpf.update_identity( - HypertoroidalWrappedNormalDistribution(array([0, 0]), 0.5 * C), + HypertoroidalWrappedNormalDistribution(array([0.0, 0.0]), 0.5 * C), forced_mean, ) diff --git a/pyrecest/tests/filters/test_von_mises_fisher_filter.py b/pyrecest/tests/filters/test_von_mises_fisher_filter.py index 5dff8f43..edfcf1f1 100644 --- a/pyrecest/tests/filters/test_von_mises_fisher_filter.py +++ b/pyrecest/tests/filters/test_von_mises_fisher_filter.py @@ -30,14 +30,14 @@ def test_VMFFilter2d(self): def test_prediction_identity(self): """Test prediction identity.""" self.filter.state = self.vmf - noise_distribution = VonMisesFisherDistribution(array([0, 1]), 0.9) + noise_distribution = VonMisesFisherDistribution(array([0.0, 1.0]), 0.9) self.filter.predict_identity(noise_distribution) # Add other assertions and logic here def test_update_identity(self): """Test update identity.""" self.filter.filter_state = self.vmf - noise_distribution = VonMisesFisherDistribution(array([0, 1]), 0.9) + noise_distribution = VonMisesFisherDistribution(array([0.0, 1.0]), 0.9) self.filter.update_identity(noise_distribution, self.vmf.mu) vmf_updated_identity = self.filter.filter_state self.assertEqual(type(vmf_updated_identity), VonMisesFisherDistribution) From 9ee00bbab98733c72f935c302d2e68a8dcba9030 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Sun, 22 Oct 2023 05:33:17 +0100 Subject: [PATCH 086/232] More. --- .../circle/wrapped_laplace_distribution.py | 8 ++++---- .../circle/wrapped_normal_distribution.py | 11 ++++++----- pyrecest/filters/von_mises_fisher_filter.py | 2 +- .../tests/distributions/test_watson_distribution.py | 2 +- .../distributions/test_wrapped_cauchy_distribution.py | 2 ++ .../distributions/test_wrapped_normal_distribution.py | 2 +- 6 files changed, 15 insertions(+), 12 deletions(-) diff --git a/pyrecest/distributions/circle/wrapped_laplace_distribution.py b/pyrecest/distributions/circle/wrapped_laplace_distribution.py index d785f752..50614f5b 100644 --- a/pyrecest/distributions/circle/wrapped_laplace_distribution.py +++ b/pyrecest/distributions/circle/wrapped_laplace_distribution.py @@ -10,10 +10,10 @@ class WrappedLaplaceDistribution(AbstractCircularDistribution): def __init__(self, lambda_, kappa_): AbstractCircularDistribution.__init__(self) - assert np.isscalar(lambda_) - assert np.isscalar(kappa_) - assert lambda_ > 0 - assert kappa_ > 0 + assert lambda_.shape in ((1,), ()) + assert kappa_.shape in ((1,), ()) + assert lambda_ > 0.0 + assert kappa_ > 0.0 self.lambda_ = lambda_ self.kappa = kappa_ diff --git a/pyrecest/distributions/circle/wrapped_normal_distribution.py b/pyrecest/distributions/circle/wrapped_normal_distribution.py index 4ab377a9..014a82f3 100644 --- a/pyrecest/distributions/circle/wrapped_normal_distribution.py +++ b/pyrecest/distributions/circle/wrapped_normal_distribution.py @@ -13,6 +13,7 @@ from pyrecest.backend import int64 from pyrecest.backend import int32 from pyrecest.backend import zeros +from pyrecestd.backend import angle import numbers @@ -96,7 +97,7 @@ def pdf(self, xs): def cdf( self, xs, - startingPoint: float = 0, + startingPoint: float = 0.0, n_wraps: Union[int, int32, int64] = 10, ): startingPoint = mod(startingPoint, 2 * pi) @@ -141,10 +142,10 @@ def multiply_vm(self, other): return wn def sample(self, n: Union[int, int32, int64]): - return mod(self.mu + self.sigma * random.randn(1, n), 2 * pi) + return mod(self.mu + self.sigma * random.randn(1, n), 2.0 * pi) def shift(self, shift_by): - assert np.isscalar(shift_by) + assert shift_by.shape in ((1,), ()) return WrappedNormalDistribution(self.mu + shift_by, self.sigma) def to_vm(self) -> VonMisesDistribution: @@ -154,11 +155,11 @@ def to_vm(self) -> VonMisesDistribution: @staticmethod def from_moment(m: complex) -> "WrappedNormalDistribution": - mu = mod(np.angle(m), 2 * pi) + mu = mod(angle(m), 2.0 * pi) sigma = sqrt(-2 * log(abs(m))) return WrappedNormalDistribution(mu, sigma) @staticmethod def sigma_to_kappa(sigma): # Approximate conversion from sigma to kappa for a Von Mises distribution - return 1 / sigma**2 \ No newline at end of file + return 1.0 / sigma**2 \ No newline at end of file diff --git a/pyrecest/filters/von_mises_fisher_filter.py b/pyrecest/filters/von_mises_fisher_filter.py index c8f3df5f..56291a0a 100644 --- a/pyrecest/filters/von_mises_fisher_filter.py +++ b/pyrecest/filters/von_mises_fisher_filter.py @@ -9,7 +9,7 @@ class VonMisesFisherFilter(AbstractHypersphericalFilter): def __init__(self): AbstractHypersphericalFilter.__init__( - self, VonMisesFisherDistribution(array([1, 0]), 1) + self, VonMisesFisherDistribution(array([1.0, 0.0]), 1.0) ) @property diff --git a/pyrecest/tests/distributions/test_watson_distribution.py b/pyrecest/tests/distributions/test_watson_distribution.py index b1175ffb..d24ad1e5 100644 --- a/pyrecest/tests/distributions/test_watson_distribution.py +++ b/pyrecest/tests/distributions/test_watson_distribution.py @@ -12,7 +12,7 @@ def setUp(self): [[1.0, 0.0, 0.0], [1.0, 2.0, 2.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0], [1.0, 1.0, 1.0], [-1.0, -1.0, -1.0]], dtype=float, ) - self.xs = self.xs / linalg.norm(self.xs, axis=1, keepdims=True) + self.xs = self.xs / linalg.norm(self.xs, axis=1).reshape((-1, 1)) def test_constructor(self): mu = array([1.0, 2.0, 3.0]) diff --git a/pyrecest/tests/distributions/test_wrapped_cauchy_distribution.py b/pyrecest/tests/distributions/test_wrapped_cauchy_distribution.py index 4a456250..a0a04645 100644 --- a/pyrecest/tests/distributions/test_wrapped_cauchy_distribution.py +++ b/pyrecest/tests/distributions/test_wrapped_cauchy_distribution.py @@ -3,6 +3,7 @@ from pyrecest.backend import arange import unittest import numpy.testing as npt +import pyrecest.backend from pyrecest.distributions.circle.custom_circular_distribution import ( CustomCircularDistribution, @@ -37,6 +38,7 @@ def pdf_wrapped(x, mu, gamma, terms=2000): dist.pdf(xs=self.xs), custom_wrapped.pdf(xs=self.xs), atol=0.0001 ) + @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") def test_cdf(self): dist = WrappedCauchyDistribution(self.mu, self.gamma) npt.assert_allclose( diff --git a/pyrecest/tests/distributions/test_wrapped_normal_distribution.py b/pyrecest/tests/distributions/test_wrapped_normal_distribution.py index 240a1521..0c1e8478 100644 --- a/pyrecest/tests/distributions/test_wrapped_normal_distribution.py +++ b/pyrecest/tests/distributions/test_wrapped_normal_distribution.py @@ -53,7 +53,7 @@ def test_pdf_with_large_sigma_is_uniform(self): """ Test that the pdf with large sigma is approximately a uniform distribution. """ - wn_large_sigma = WrappedNormalDistribution(0.0, 100.0) + wn_large_sigma = WrappedNormalDistribution(array(0.0), array(100.0)) x = arange(0, 7) fx = ones_like(x) / (2.0 * pi) self.assertTrue(allclose(wn_large_sigma.pdf(x), fx, rtol=1e-10)) From 5ad5c4ab8d349059f9d25f0ec6400428fb979d79 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Sun, 22 Oct 2023 05:39:08 +0100 Subject: [PATCH 087/232] More.. --- pyrecest/distributions/circle/wrapped_normal_distribution.py | 2 +- .../hypersphere_subset/von_mises_fisher_distribution.py | 5 +++-- pyrecest/tests/distributions/test_watson_distribution.py | 2 +- .../tests/distributions/test_wrapped_laplace_distribution.py | 2 ++ 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/pyrecest/distributions/circle/wrapped_normal_distribution.py b/pyrecest/distributions/circle/wrapped_normal_distribution.py index 014a82f3..d38d79fb 100644 --- a/pyrecest/distributions/circle/wrapped_normal_distribution.py +++ b/pyrecest/distributions/circle/wrapped_normal_distribution.py @@ -13,7 +13,7 @@ from pyrecest.backend import int64 from pyrecest.backend import int32 from pyrecest.backend import zeros -from pyrecestd.backend import angle +from pyrecest.backend import angle import numbers diff --git a/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py b/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py index b03b61cc..3fadea74 100644 --- a/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py @@ -14,6 +14,7 @@ from pyrecest.backend import int64 from pyrecest.backend import int32 from pyrecest.backend import zeros +from pyrecest.backend import array import numbers @@ -154,8 +155,8 @@ def convolve(self, other: "VonMisesFisherDistribution"): @staticmethod def a_d(d: Union[int, int32, int64], kappa): - bessel1 = iv(d / 2, kappa) - bessel2 = iv(d / 2 - 1, kappa) + bessel1 = array(iv(d / 2, kappa)) + bessel2 = array(iv(d / 2 - 1, kappa)) if isnan(bessel1) or isnan(bessel2): print(f"Bessel functions returned NaN for d={d}, kappa={kappa}") return bessel1 / bessel2 diff --git a/pyrecest/tests/distributions/test_watson_distribution.py b/pyrecest/tests/distributions/test_watson_distribution.py index d24ad1e5..a7f834d6 100644 --- a/pyrecest/tests/distributions/test_watson_distribution.py +++ b/pyrecest/tests/distributions/test_watson_distribution.py @@ -43,7 +43,7 @@ def test_pdf(self): ) pdf_values = w.pdf(self.xs) - npt.assert_almost_equal(pdf_values, expected_pdf_values, decimal=5) + npt.assert_array_almost_equal(pdf_values, expected_pdf_values, decimal=5) def test_integrate(self): mu = array([1.0, 2.0, 3.0]) diff --git a/pyrecest/tests/distributions/test_wrapped_laplace_distribution.py b/pyrecest/tests/distributions/test_wrapped_laplace_distribution.py index 389d8411..2f348609 100644 --- a/pyrecest/tests/distributions/test_wrapped_laplace_distribution.py +++ b/pyrecest/tests/distributions/test_wrapped_laplace_distribution.py @@ -3,6 +3,7 @@ from pyrecest.backend import exp from pyrecest.backend import arange from pyrecest.backend import array +import pyrecest.backend import unittest import numpy.testing as npt @@ -37,6 +38,7 @@ def pdftemp(x): for x in [0.0, 1.0, 2.0, 3.0, 4.0]: npt.assert_allclose(self.wl.pdf(x), pdftemp(x), rtol=1e-10) + @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") def test_integral(self): npt.assert_allclose(self.wl.integrate(), 1.0, rtol=1e-10) npt.assert_allclose(self.wl.integrate_numerically(), 1.0, rtol=1e-10) From 24153505c4f415a65bca8b2a809a3d8d5f74bc4f Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Sun, 22 Oct 2023 05:47:58 +0100 Subject: [PATCH 088/232] More --- .../tests/distributions/test_abstract_linear_distribution.py | 2 ++ .../distributions/test_spherical_harmonics_distribution_real.py | 2 +- pyrecest/tests/test_hyperspherical_sampler.py | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/pyrecest/tests/distributions/test_abstract_linear_distribution.py b/pyrecest/tests/distributions/test_abstract_linear_distribution.py index 96e00212..252bbcc0 100644 --- a/pyrecest/tests/distributions/test_abstract_linear_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_linear_distribution.py @@ -64,12 +64,14 @@ def test_mode_numerical_custom_1D(self): def test_mean_numerical_gaussian_2D(self): npt.assert_allclose(self.g_2D.mean_numerical(), self.mu_2D, atol=1e-6) + @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") def test_mode_numerical_gaussian_2D_mean_far_away(self): mu = array([5.0, 10.0]) C = array([[2.0, 1.0], [1.0, 1.0]]) g = GaussianDistribution(mu, C) npt.assert_allclose(g.mode_numerical(), mu, atol=2e-4) + @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") def test_mode_numerical_gaussian_3D(self): npt.assert_allclose(self.g_3D.mode_numerical(), self.mu_3D, atol=5e-4) diff --git a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py index 7722385e..d553c727 100644 --- a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py +++ b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py @@ -35,7 +35,7 @@ def testNormalizationWarning(self): def testNormalization(self): unnormalized_coeffs = random.rand(3, 5) shd = SphericalHarmonicsDistributionReal(unnormalized_coeffs) - self.assertAlmostEqual(shd.integrate(), 1, delta=1e-6) + self.assertAlmostEqual(shd.integrate(), 1.0, delta=1e-6) x, y, z = SphericalHarmonicsDistributionRealTest._gen_naive_grid(10) vals_normalized = shd.pdf(column_stack((x, y, z))) diff --git a/pyrecest/tests/test_hyperspherical_sampler.py b/pyrecest/tests/test_hyperspherical_sampler.py index c2655518..5b610711 100644 --- a/pyrecest/tests/test_hyperspherical_sampler.py +++ b/pyrecest/tests/test_hyperspherical_sampler.py @@ -22,6 +22,8 @@ class TestHypersphericalGridGenerationFunction(unittest.TestCase): + + @unittest.skipIf(not healpy_installed, "healpy is not installed") @parameterized.expand( [ ("healpix", 2, 48, "n_side"), From 2564edb24967fd02184f36271d410f41e57b43f3 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Sun, 22 Oct 2023 11:13:52 +0100 Subject: [PATCH 089/232] More.......... --- pyrecest/_backend/pytorch/__init__.py | 2 +- pyrecest/_backend/pytorch/random.py | 8 +- .../abstract_dirac_distribution.py | 2 +- .../nonperiodic/linear_dirac_distribution.py | 3 +- .../test_linear_dirac_distribution.py | 6 +- ...pherical_harmonics_distribution_complex.py | 384 +++++++++--------- 6 files changed, 200 insertions(+), 205 deletions(-) diff --git a/pyrecest/_backend/pytorch/__init__.py b/pyrecest/_backend/pytorch/__init__.py index 1d398d11..cc4dd973 100644 --- a/pyrecest/_backend/pytorch/__init__.py +++ b/pyrecest/_backend/pytorch/__init__.py @@ -405,7 +405,7 @@ def linspace(start, stop, num=50, endpoint=True, dtype=None): return _torch.linspace(start=start, end=stop, steps=num, dtype=dtype) elif not (start_is_array or stop_is_array): # Added for pyrecest return _torch.arange(start=start, end=stop, step=(stop-start)/num, dtype=dtype) - else: + elif endpoint: raise ValueError("endpoint=False not supported for vectors") if not start_is_array: diff --git a/pyrecest/_backend/pytorch/random.py b/pyrecest/_backend/pytorch/random.py index 6a32144f..9ca12aa8 100644 --- a/pyrecest/_backend/pytorch/random.py +++ b/pyrecest/_backend/pytorch/random.py @@ -22,13 +22,7 @@ def choice(a, size=None, replace=True, p=None): else: indices = _torch.randint(0, len(a), size) - result = a[indices] - - # Reshape the result to match the given size - if size is not None: - result = result.reshape(size) - - return result + return a[indices] def seed(*args, **kwargs): diff --git a/pyrecest/distributions/abstract_dirac_distribution.py b/pyrecest/distributions/abstract_dirac_distribution.py index e24918bd..e2545b58 100644 --- a/pyrecest/distributions/abstract_dirac_distribution.py +++ b/pyrecest/distributions/abstract_dirac_distribution.py @@ -82,7 +82,7 @@ def reweigh(self, f: Callable) -> "AbstractDiracDistribution": return dist def sample(self, n: Union[int, int32, int64]): - samples = random.choice(self.d, size=(self.dim, n), p=self.w) + samples = random.choice(self.d, size=n, p=self.w) return samples def entropy(self) -> float: diff --git a/pyrecest/distributions/nonperiodic/linear_dirac_distribution.py b/pyrecest/distributions/nonperiodic/linear_dirac_distribution.py index c2dba437..ea1dc2fd 100644 --- a/pyrecest/distributions/nonperiodic/linear_dirac_distribution.py +++ b/pyrecest/distributions/nonperiodic/linear_dirac_distribution.py @@ -14,7 +14,8 @@ def __init__(self, d, w=None): AbstractDiracDistribution.__init__(self, d, w) def mean(self): - return np.average(self.d, weights=self.w, axis=0) + # Like np.average(self.d, weights=self.w, axis=0) but for all backends + return (self.d * self.w.reshape(-1, 1)).sum(dim=0) def set_mean(self, new_mean): mean_offset = new_mean - self.mean diff --git a/pyrecest/tests/distributions/test_linear_dirac_distribution.py b/pyrecest/tests/distributions/test_linear_dirac_distribution.py index ab5c350d..da82a8fb 100644 --- a/pyrecest/tests/distributions/test_linear_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_linear_dirac_distribution.py @@ -17,14 +17,14 @@ class LinearDiracDistributionTest(unittest.TestCase): def test_from_distribution(self): random.seed(0) C = wishart.rvs(3, eye(3)) - hwn = GaussianDistribution(array([1, 2, 3]), array(C)) - hwd = LinearDiracDistribution.from_distribution(hwn, 100000) + hwn = GaussianDistribution(array([1.0, 2.0, 3.0]), array(C)) + hwd = LinearDiracDistribution.from_distribution(hwn, 150000) self.assertTrue(allclose(hwd.mean(), hwn.mean(), atol=0.005)) self.assertTrue(allclose(hwd.covariance(), hwn.covariance(), rtol=0.01)) def test_mean_and_cov(self): random.seed(0) - gd = GaussianDistribution(array([1, 2]), array([[2, -0.3], [-0.3, 1]])) + gd = GaussianDistribution(array([1.0, 2.0]), array([[2.0, -0.3], [-0.3, 1.0]])) ddist = LinearDiracDistribution(gd.sample(10000)) self.assertTrue(allclose(ddist.mean(), gd.mean(), atol=0.05)) self.assertTrue(allclose(ddist.covariance(), gd.covariance(), atol=0.05)) diff --git a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py index 5aa415b6..82c921bd 100644 --- a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py +++ b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py @@ -110,7 +110,7 @@ def test_integral_analytical(self, transformation): ) # First initialize and overwrite afterward to prevent normalization shd = SphericalHarmonicsDistributionComplex( - array([[1, float('NaN'), float('NaN')], [0, 0, 0]]) + array([[1, float('NaN'), float('NaN')], [0.0, 0.0, 0]]) ) shd.coeff_mat = unnormalized_coeffs shd.transformation = transformation @@ -178,46 +178,46 @@ def test_truncation(self): "testl0m0", array( [ - [1, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN')], - [0, 0, 0, 0, 0], + [1.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, 0.0, 0.0], ] ), - lambda _, _1, z: ones_like(z) * sqrt(1 / (4 * pi)), + lambda _, _1, z: ones_like(z) * sqrt(1.0 / (4.0 * pi)), ), ( "testl1m0", array( [ - [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 1, 0, float('NaN'), float('NaN')], - [0, 0, 0, 0, 0], + [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0.0, 1.0, 0.0, float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, 0.0, 0.0], ] ), - lambda _, _1, z: sqrt(3 / (4 * pi)) * z, + lambda _, _1, z: sqrt(3.0 / (4.0 * pi)) * z, ), ( "testl2m0", array( [ - [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN')], - [0, 0, 1, 0, 0], + [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, 0.0, 1.0, 0.0, 0.0], ] ), - lambda x, y, z: 1 - / 4 + lambda x, y, z: 1.0 + / 4.0 * sqrt(5 / pi) - * (2 * z**2 - x**2 - y**2), + * (2.0 * z**2 - x**2 - y**2), ), ( "testl3m0", array( [ - [0, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, 0, 0, float('NaN'), float('NaN')], - [0, 0, 0, 1, 0, 0, 0], + [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0], ] ), lambda x, y, z: 1 @@ -232,9 +232,9 @@ def test_truncation(self): "test_l1mneg1real", array( [ - [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [1j * sqrt(1 / 2), 0, 1j * sqrt(1 / 2), float('NaN'), float('NaN')], - [0, 0, 0, 0, 0], + [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [1j * sqrt(1 / 2), 0.0, 1j * sqrt(1 / 2), float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, 0.0, 0], ] ), lambda _, y, _1: sqrt(3 / (4 * pi)) * y, @@ -243,9 +243,9 @@ def test_truncation(self): "test_l1m1real", array( [ - [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [sqrt(1 / 2), 0, -sqrt(1 / 2), float('NaN'), float('NaN')], - [0, 0, 0, 0, 0], + [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [sqrt(1 / 2), 0.0, -sqrt(1 / 2), float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, 0.0, 0], ] ), lambda x, _, _1: sqrt(3 / (4 * pi)) * x, @@ -254,9 +254,9 @@ def test_truncation(self): "test_l2mneg2real", array( [ - [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN')], - [1j * sqrt(1 / 2), 0, 0, 0, -1j * sqrt(1 / 2)], + [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [1j * sqrt(1 / 2), 0.0, 0.0, 0.0, -1j * sqrt(1 / 2)], ] ), lambda x, y, _: 1 / 2 * sqrt(15 / pi) * x * y, @@ -265,9 +265,9 @@ def test_truncation(self): "test_l2mneg1real", array( [ - [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN')], - [0, 1j * sqrt(1 / 2), 0, 1j * sqrt(1 / 2), 0], + [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, 1j * sqrt(1 / 2), 0.0, 1j * sqrt(1 / 2), 0], ] ), lambda _, y, z: 1 / 2 * sqrt(15 / pi) * y * z, @@ -276,9 +276,9 @@ def test_truncation(self): "test_l2m1real", array( [ - [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN')], - [0, sqrt(1 / 2), 0, -sqrt(1 / 2), 0], + [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, sqrt(1 / 2), 0.0, -sqrt(1 / 2), 0], ] ), lambda x, _, z: 1 / 2 * sqrt(15 / pi) * x * z, @@ -287,9 +287,9 @@ def test_truncation(self): "test_l2m2real", array( [ - [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN')], - [sqrt(1 / 2), 0, 0, 0, sqrt(1 / 2)], + [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [sqrt(1 / 2), 0.0, 0.0, 0.0, sqrt(1 / 2)], ] ), lambda x, y, _: 1 / 4 * sqrt(15 / pi) * (x**2 - y**2), @@ -298,26 +298,26 @@ def test_truncation(self): "test_l3mneg3real", array( [ - [0, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, 0, 0, float('NaN'), float('NaN')], - [1j / sqrt(2), 0, 0, 0, 0, 0, 1j / sqrt(2)], + [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [1j / sqrt(2), 0.0, 0.0, 0.0, 0.0, 0.0, 1j / sqrt(2)], ] ), - lambda x, y, z: 1 - / 4 - * sqrt(35 / (2 * pi)) + lambda x, y, z: 1.0 + / 4.0 + * sqrt(35.0 / (2.0 * pi)) * y - * (3 * x**2 - y**2), + * (3.0 * x**2 - y**2), ), ( "test_l3mneg2real", array( [ - [0, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, 0, 0, float('NaN'), float('NaN')], - [0, 1j / sqrt(2), 0, 0, 0, -1j / sqrt(2), 0], + [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, 1j / sqrt(2), 0.0, 0.0, 0.0, -1j / sqrt(2), 0], ] ), lambda x, y, z: 1 / 2 * sqrt(105 / pi) * x * y * z, @@ -326,10 +326,10 @@ def test_truncation(self): "test_l3mneg1real", array( [ - [0, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, 0, 0, float('NaN'), float('NaN')], - [0, 0, 1j / sqrt(2), 0, 1j / sqrt(2), 0, 0], + [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, 0.0, 1j / sqrt(2), 0.0, 1j / sqrt(2), 0.0, 0], ] ), lambda x, y, z: 1 @@ -342,10 +342,10 @@ def test_truncation(self): "test_l3m1real", array( [ - [0, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, 0, 0, float('NaN'), float('NaN')], - [0, 0, 1 / sqrt(2), 0, -1 / sqrt(2), 0, 0], + [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, 0.0, 1 / sqrt(2), 0.0, -1 / sqrt(2), 0.0, 0], ] ), lambda x, y, z: 1 @@ -358,10 +358,10 @@ def test_truncation(self): "test_l3m2real", array( [ - [0, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, 0, 0, float('NaN'), float('NaN')], - [0, 1 / sqrt(2), 0, 0, 0, 1 / sqrt(2), 0], + [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, 1 / sqrt(2), 0.0, 0.0, 0.0, 1 / sqrt(2), 0], ] ), lambda x, y, z: 1 / 4 * sqrt(105 / pi) * z * (x**2 - y**2), @@ -370,10 +370,10 @@ def test_truncation(self): "test_l3m3real", array( [ - [0, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, 0, 0, float('NaN'), float('NaN')], - [1 / sqrt(2), 0, 0, 0, 0, 0, -1 / sqrt(2)], + [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [1 / sqrt(2), 0.0, 0.0, 0.0, 0.0, 0.0, -1 / sqrt(2)], ] ), lambda x, y, z: 1 @@ -385,10 +385,10 @@ def test_truncation(self): ] ) def test_basis_function(self, _, coeff_mat, expected_func): - shd = SphericalHarmonicsDistributionComplex(1 / sqrt(4 * pi)) + shd = SphericalHarmonicsDistributionComplex(1.0 / sqrt(4.0 * pi)) shd.coeff_mat = coeff_mat phi, theta = meshgrid( - linspace(0.0, 2 * pi, 10), linspace(0.0, pi, 10) + linspace(0.0.0, 2.0 * pi, 10), linspace(0.0.0, pi, 10) ) x, y, z = AbstractSphericalDistribution.sph_to_cart(phi.ravel(), theta.ravel()) npt.assert_allclose( @@ -402,9 +402,9 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl1mneg1_cart", array( [ - [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [1, 0, 0, float('NaN'), float('NaN')], - [0, 0, 0, 0, 0], + [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [1, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, 0.0, 0], ] ), lambda x, y, _: 0.5 * sqrt(3 / (2 * pi)) * (x - 1j * y), @@ -413,9 +413,9 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl1m1_cart", array( [ - [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 1, float('NaN'), float('NaN')], - [0, 0, 0, 0, 0], + [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0.0, 0.0, 1, float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, 0.0, 0], ] ), lambda x, y, _: -0.5 * sqrt(3 / (2 * pi)) * (x + 1j * y), @@ -424,9 +424,9 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl2mneg2_cart", array( [ - [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN')], - [1, 0, 0, 0, 0], + [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [1, 0.0, 0.0, 0.0, 0], ] ), lambda x, y, _: 0.25 * sqrt(15 / (2 * pi)) * (x - 1j * y) ** 2, @@ -435,9 +435,9 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl2mneg1_cart", array( [ - [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN')], - [0, 1, 0, 0, 0], + [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, 1, 0.0, 0.0, 0], ] ), lambda x, y, z: 0.5 * sqrt(15 / (2 * pi)) * (x - 1j * y) * z, @@ -446,9 +446,9 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl2m1_cart", array( [ - [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN')], - [0, 0, 0, 1, 0], + [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, 1, 0], ] ), lambda x, y, z: -0.5 * sqrt(15 / (2 * pi)) * (x + 1j * y) * z, @@ -457,9 +457,9 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl2m2_cart", array( [ - [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN')], - [0, 0, 0, 0, 1], + [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, 0.0, 1], ] ), lambda x, y, _: 0.25 * sqrt(15 / (2 * pi)) * (x + 1j * y) ** 2, @@ -469,9 +469,9 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl1mneg1_sph", array( [ - [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [1, 0, 0, float('NaN'), float('NaN')], - [0, 0, 0, 0, 0], + [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [1, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, 0.0, 0], ] ), lambda phi, theta: 0.5 @@ -483,9 +483,9 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl1m1_sph", array( [ - [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 1, float('NaN'), float('NaN')], - [0, 0, 0, 0, 0], + [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0.0, 0.0, 1, float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, 0.0, 0], ] ), lambda phi, theta: -0.5 @@ -497,9 +497,9 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl2mneg2_sph", array( [ - [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN')], - [1, 0, 0, 0, 0], + [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [1, 0.0, 0.0, 0.0, 0], ] ), lambda phi, theta: 0.25 @@ -511,9 +511,9 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl2mneg1_sph", array( [ - [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN')], - [0, 1, 0, 0, 0], + [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, 1, 0.0, 0.0, 0], ] ), lambda phi, theta: 0.5 @@ -526,9 +526,9 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl2m1_sph", array( [ - [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN')], - [0, 0, 0, 1, 0], + [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, 1, 0], ] ), lambda phi, theta: -0.5 @@ -541,9 +541,9 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl2m2_sph", array( [ - [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN')], - [0, 0, 0, 0, 1], + [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, 0.0, 1], ] ), lambda phi, theta: 0.25 @@ -555,9 +555,9 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl1mneg1_sphconv_colatitude", array( [ - [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [1, 0, 0, float('NaN'), float('NaN')], - [0, 0, 0, 0, 0], + [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [1, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, 0.0, 0], ] ), lambda phi, theta: 0.5 @@ -569,9 +569,9 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl1m1_sphconv_colatitude", array( [ - [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 1, float('NaN'), float('NaN')], - [0, 0, 0, 0, 0], + [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0.0, 0.0, 1, float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, 0.0, 0], ] ), lambda phi, theta: -0.5 @@ -583,9 +583,9 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl2mneg2_sphconv_colatitude", array( [ - [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN')], - [1, 0, 0, 0, 0], + [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [1, 0.0, 0.0, 0.0, 0], ] ), lambda phi, theta: 0.25 @@ -597,9 +597,9 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl2mneg1_sphconv_colatitude", array( [ - [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN')], - [0, 1, 0, 0, 0], + [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, 1, 0.0, 0.0, 0], ] ), lambda phi, theta: 0.5 @@ -612,9 +612,9 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl2m1_sphconv_colatitude", array( [ - [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN')], - [0, 0, 0, 1, 0], + [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, 1, 0], ] ), lambda phi, theta: -0.5 @@ -627,9 +627,9 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl2m2_sphconv_colatitude", array( [ - [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN')], - [0, 0, 0, 0, 1], + [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, 0.0, 1], ] ), lambda phi, theta: 0.25 @@ -645,7 +645,7 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): ) shd.coeff_mat = coeff_mat phi, theta = meshgrid( - linspace(0, 2 * pi, 10), linspace(-pi / 2, pi / 2, 10) + linspace(0.0, 2 * pi, 10), linspace(-pi / 2, pi / 2, 10) ) x, y, z = AbstractSphericalDistribution.sph_to_cart(phi.ravel(), theta.ravel()) @@ -669,8 +669,8 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): array( [ [1, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN')], - [0, 0, 0, 0, 0], + [0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, 0.0, 0], ] ), ), @@ -679,8 +679,8 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): array( [ [1, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [1j * sqrt(1 / 2), 0, 1j * sqrt(1 / 2), float('NaN'), float('NaN')], - [0, 0, 0, 0, 0], + [1j * sqrt(1 / 2), 0.0, 1j * sqrt(1 / 2), float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, 0.0, 0], ] ), ), @@ -689,8 +689,8 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): array( [ [1, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 1, 0, float('NaN'), float('NaN')], - [0, 0, 0, 0, 0], + [0.0, 1, 0.0, float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, 0.0, 0], ] ), ), @@ -699,8 +699,8 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): array( [ [1, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [sqrt(1 / 2), 0, -sqrt(1 / 2), float('NaN'), float('NaN')], - [0, 0, 0, 0, 0], + [sqrt(1 / 2), 0.0, -sqrt(1 / 2), float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, 0.0, 0], ] ), ), @@ -709,8 +709,8 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): array( [ [1, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN')], - [1j * sqrt(1 / 2), 0, 0, 0, -1j * sqrt(1 / 2)], + [0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [1j * sqrt(1 / 2), 0.0, 0.0, 0.0, -1j * sqrt(1 / 2)], ] ), ), @@ -719,8 +719,8 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): array( [ [1, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN')], - [0, 1j * sqrt(1 / 2), 0, 1j * sqrt(1 / 2), 0], + [0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, 1j * sqrt(1 / 2), 0.0, 1j * sqrt(1 / 2), 0], ] ), ), @@ -729,8 +729,8 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): array( [ [1, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN')], - [0, 0, 1, 0, 0], + [0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, 0.0, 1, 0.0, 0], ] ), ), @@ -739,8 +739,8 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): array( [ [1, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN')], - [0, sqrt(1 / 2), 0, -sqrt(1 / 2), 0], + [0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, sqrt(1 / 2), 0.0, -sqrt(1 / 2), 0], ] ), ), @@ -749,8 +749,8 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): array( [ [1, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN')], - [sqrt(1 / 2), 0, 0, 0, sqrt(1 / 2)], + [0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [sqrt(1 / 2), 0.0, 0.0, 0.0, sqrt(1 / 2)], ] ), ), @@ -759,9 +759,9 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): array( [ [1, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, 0, 0, float('NaN'), float('NaN')], - [1j / sqrt(2), 0, 0, 0, 0, 0, 1j / sqrt(2)], + [0.0, 0.0, 0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [1j / sqrt(2), 0.0, 0.0, 0.0, 0.0, 0.0, 1j / sqrt(2)], ] ), ), @@ -770,9 +770,9 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): array( [ [1, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, 0, 0, float('NaN'), float('NaN')], - [0, 1j / sqrt(2), 0, 0, 0, -1j / sqrt(2), 0], + [0.0, 0.0, 0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, 1j / sqrt(2), 0.0, 0.0, 0.0, -1j / sqrt(2), 0], ] ), ), @@ -781,9 +781,9 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): array( [ [1, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, 0, 0, float('NaN'), float('NaN')], - [0, 0, 1j / sqrt(2), 0, 1j / sqrt(2), 0, 0], + [0.0, 0.0, 0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, 0.0, 1j / sqrt(2), 0.0, 1j / sqrt(2), 0.0, 0], ] ), ), @@ -792,9 +792,9 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): array( [ [1, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, 0, 0, float('NaN'), float('NaN')], - [0, 0, 0, 1, 0, 0, 0], + [0.0, 0.0, 0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, 1, 0.0, 0.0, 0], ] ), ), @@ -803,9 +803,9 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): array( [ [1, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, 0, 0, float('NaN'), float('NaN')], - [0, 0, 1 / sqrt(2), 0, -1 / sqrt(2), 0, 0], + [0.0, 0.0, 0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, 0.0, 1 / sqrt(2), 0.0, -1 / sqrt(2), 0.0, 0], ] ), ), @@ -814,9 +814,9 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): array( [ [1, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, 0, 0, float('NaN'), float('NaN')], - [0, 1 / sqrt(2), 0, 0, 0, 1 / sqrt(2), 0], + [0.0, 0.0, 0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, 1 / sqrt(2), 0.0, 0.0, 0.0, 1 / sqrt(2), 0], ] ), ), @@ -825,9 +825,9 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): array( [ [1, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, 0, 0, float('NaN'), float('NaN')], - [1 / sqrt(2), 0, 0, 0, 0, 0, -1 / sqrt(2)], + [0.0, 0.0, 0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [0.0, 0.0, 0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [1 / sqrt(2), 0.0, 0.0, 0.0, 0.0, 0.0, -1 / sqrt(2)], ] ), ), @@ -837,7 +837,7 @@ def test_conversion(self, _, coeff_mat): shd = SphericalHarmonicsDistributionComplex(coeff_mat) rshd = shd.to_spherical_harmonics_distribution_real() phi, theta = meshgrid( - linspace(0, 2 * pi, 10), linspace(-pi / 2, pi / 2, 10) + linspace(0.0, 2 * pi, 10), linspace(-pi / 2, pi / 2, 10) ) x, y, z = AbstractSphericalDistribution.sph_to_cart(phi.ravel(), theta.ravel()) npt.assert_allclose( @@ -850,22 +850,22 @@ def test_conversion(self, _, coeff_mat): [ ( "shd_x", - array([[1, float('NaN'), float('NaN')], [sqrt(1 / 2), 0, -sqrt(1 / 2)]]), - array([1, 0, 0]), + array([[1, float('NaN'), float('NaN')], [sqrt(1 / 2), 0.0, -sqrt(1 / 2)]]), + array([1, 0.0, 0]), SphericalHarmonicsDistributionComplex.mean_direction, ), ( "shd_y", array( - [[1, float('NaN'), float('NaN')], [1j * sqrt(1 / 2), 0, 1j * sqrt(1 / 2)]] + [[1, float('NaN'), float('NaN')], [1j * sqrt(1 / 2), 0.0, 1j * sqrt(1 / 2)]] ), - array([0, 1, 0]), + array([0.0, 1, 0]), SphericalHarmonicsDistributionComplex.mean_direction, ), ( "shd_z", - array([[1, float('NaN'), float('NaN')], [0, 1, 0]]), - array([0, 0, 1]), + array([[1, float('NaN'), float('NaN')], [0.0, 1, 0]]), + array([0.0, 0.0, 1]), SphericalHarmonicsDistributionComplex.mean_direction, ), ( @@ -875,7 +875,7 @@ def test_conversion(self, _, coeff_mat): [1, float('NaN'), float('NaN')], [ sqrt(1 / 2) + 1j * sqrt(1 / 2), - 0, + 0.0, -sqrt(1 / 2) + 1j * sqrt(1 / 2), ], ] @@ -886,7 +886,7 @@ def test_conversion(self, _, coeff_mat): ( "shd_xz", array([[1, float('NaN'), float('NaN')], [sqrt(1 / 2), 1, -sqrt(1 / 2)]]), - array([1, 0, 1]) / sqrt(2), + array([1, 0.0, 1]) / sqrt(2), SphericalHarmonicsDistributionComplex.mean_direction, ), ( @@ -894,27 +894,27 @@ def test_conversion(self, _, coeff_mat): array( [[1, float('NaN'), float('NaN')], [1j * sqrt(1 / 2), 1, 1j * sqrt(1 / 2)]] ), - array([0, 1, 1]) / sqrt(2), + array([0.0, 1, 1]) / sqrt(2), SphericalHarmonicsDistributionComplex.mean_direction, ), ( "numerical_shd_x", - array([[1, float('NaN'), float('NaN')], [sqrt(1 / 2), 0, -sqrt(1 / 2)]]), - array([1, 0, 0]), + array([[1, float('NaN'), float('NaN')], [sqrt(1 / 2), 0.0, -sqrt(1 / 2)]]), + array([1, 0.0, 0]), SphericalHarmonicsDistributionComplex.mean_direction_numerical, ), ( "numerical_shd_y", array( - [[1, float('NaN'), float('NaN')], [1j * sqrt(1 / 2), 0, 1j * sqrt(1 / 2)]] + [[1, float('NaN'), float('NaN')], [1j * sqrt(1 / 2), 0.0, 1j * sqrt(1 / 2)]] ), - array([0, 1, 0]), + array([0.0, 1, 0]), SphericalHarmonicsDistributionComplex.mean_direction_numerical, ), ( "numerical_shd_z", - array([[1, float('NaN'), float('NaN')], [0, 1, 0]]), - array([0, 0, 1]), + array([[1, float('NaN'), float('NaN')], [0.0, 1, 0]]), + array([0.0, 0.0, 1]), SphericalHarmonicsDistributionComplex.mean_direction_numerical, ), ] @@ -930,7 +930,7 @@ def test_from_distribution_via_integral_vmf(self): dist, 3 ) phi, theta = meshgrid( - linspace(0, 2 * pi, 10), linspace(-pi / 2, pi / 2, 10) + linspace(0.0, 2 * pi, 10), linspace(-pi / 2, pi / 2, 10) ) x, y, z = AbstractSphericalDistribution.sph_to_cart(phi.ravel(), theta.ravel()) npt.assert_allclose( @@ -957,7 +957,7 @@ def test_from_distribution_via_integral_uniform(self): def test_transformation_via_integral_shd(self): # Test approximating a spherical harmonic distribution dist = SphericalHarmonicsDistributionComplex( - array([[1, float('NaN'), float('NaN')], [0, 1, 0]]) + array([[1, float('NaN'), float('NaN')], [0.0, 1, 0]]) ) shd = SphericalHarmonicsDistributionComplex.from_function_via_integral_cart( @@ -970,7 +970,7 @@ def test_convergence(self): dist = VonMisesFisherDistribution(array([0.0, -1.0, 0.0]), 1.0) diffs = zeros(no_diffs) - for i in range(0, no_diffs): + for i in range(0.0, no_diffs): shd = SphericalHarmonicsDistributionComplex.from_function_via_integral_cart( dist.pdf, i ) @@ -981,43 +981,43 @@ def test_convergence(self): @parameterized.expand( [ - ("zplus", [[1 / sqrt(4 * pi), float('NaN'), float('NaN')], [0, 1, 0]], [0, 0, 1]), + ("zplus", [[1 / sqrt(4 * pi), float('NaN'), float('NaN')], [0.0, 1, 0]], [0.0, 0.0, 1]), ( "zminus", - [[1 / sqrt(4 * pi), float('NaN'), float('NaN')], [0, -1, 0]], - [0, 0, -1], + [[1 / sqrt(4 * pi), float('NaN'), float('NaN')], [0.0, -1, 0]], + [0.0, 0.0, -1], ), ( "yplus", [ [1 / sqrt(4 * pi), float('NaN'), float('NaN')], - [1j * sqrt(1 / 2), 0, 1j * sqrt(1 / 2)], + [1j * sqrt(1 / 2), 0.0, 1j * sqrt(1 / 2)], ], - [0, 1, 0], + [0.0, 1, 0], ), ( "yminus", [ [1 / sqrt(4 * pi), float('NaN'), float('NaN')], - [-1j * sqrt(1 / 2), 0, -1j * sqrt(1 / 2)], + [-1j * sqrt(1 / 2), 0.0, -1j * sqrt(1 / 2)], ], - [0, -1, 0], + [0.0, -1, 0], ), ( "xplus", [ [1 / sqrt(4 * pi), float('NaN'), float('NaN')], - [sqrt(1 / 2), 0, -sqrt(1 / 2)], + [sqrt(1 / 2), 0.0, -sqrt(1 / 2)], ], - [1, 0, 0], + [1, 0.0, 0], ), ( "xminus", [ [1 / sqrt(4 * pi), float('NaN'), float('NaN')], - [-sqrt(1 / 2), 0, sqrt(1 / 2)], + [-sqrt(1 / 2), 0.0, sqrt(1 / 2)], ], - [-1, 0, 0], + [-1, 0.0, 0], ), ( "xyplus", @@ -1037,7 +1037,7 @@ def test_convergence(self): [1 / sqrt(4 * pi), float('NaN'), float('NaN')], [ -1j * sqrt(1 / 2) - sqrt(1 / 2), - 0, + 0.0, -1j * sqrt(1 / 2) + sqrt(1 / 2), ], ], From ef5d219242ab2fc3c6f33bd31beb3408e330d5d1 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Sun, 22 Oct 2023 11:55:15 +0100 Subject: [PATCH 090/232] More --- .../abstract_spherical_harmonics_distribution.py | 9 ++------- .../test_spherical_harmonics_distribution_complex.py | 4 ++-- .../test_spherical_harmonics_distribution_real.py | 2 +- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py index ecce5faa..6d1bf7a1 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py @@ -31,13 +31,8 @@ def __init__(self, coeff_mat, transformation="identity"): # Ignore irrelevant entries of coeff_mat and set to NaN n = coeff_mat.shape[0] for i in range(n): - # Calculate the range of column indices to keep - start_idx = n - i - 1 - end_idx = n + i - - # Set the elements outside this range to NaN - coeff_mat[i, :start_idx] = float('nan') - coeff_mat[i, end_idx:] = float('nan') + # Set the irrelevant elements to nan + coeff_mat[i, 2*i+1:] = float('NaN') AbstractOrthogonalBasisDistribution.__init__(self, coeff_mat, transformation) def pdf(self, xs): diff --git a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py index 82c921bd..cdbb957e 100644 --- a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py +++ b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py @@ -388,7 +388,7 @@ def test_basis_function(self, _, coeff_mat, expected_func): shd = SphericalHarmonicsDistributionComplex(1.0 / sqrt(4.0 * pi)) shd.coeff_mat = coeff_mat phi, theta = meshgrid( - linspace(0.0.0, 2.0 * pi, 10), linspace(0.0.0, pi, 10) + linspace(0.0, 2.0 * pi, 10), linspace(0.0, pi, 10) ) x, y, z = AbstractSphericalDistribution.sph_to_cart(phi.ravel(), theta.ravel()) npt.assert_allclose( @@ -970,7 +970,7 @@ def test_convergence(self): dist = VonMisesFisherDistribution(array([0.0, -1.0, 0.0]), 1.0) diffs = zeros(no_diffs) - for i in range(0.0, no_diffs): + for i in range(0, no_diffs): shd = SphericalHarmonicsDistributionComplex.from_function_via_integral_cart( dist.pdf, i ) diff --git a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py index d553c727..6be4d9f1 100644 --- a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py +++ b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py @@ -44,7 +44,7 @@ def testNormalization(self): self.assertTrue( allclose( diff(vals_normalized / vals_unnormalized), - zeros((1, x.size - 1)), + zeros(x.shape[0] - 1), atol=1e-6, ) ) From 14d31b9702b4b42a9d809952670146298a741bbe Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Sun, 22 Oct 2023 12:32:54 +0100 Subject: [PATCH 091/232] More --- ...bstract_hypersphere_subset_distribution.py | 19 ++++++++++++++----- .../hypertoroidal_uniform_distribution.py | 11 +++++++++-- .../filters/test_circular_particle_filter.py | 2 +- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py index afeeea18..8829755b 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py @@ -13,6 +13,7 @@ from pyrecest.backend import abs from pyrecest.backend import int64 from pyrecest.backend import int32 +from pyrecest.backend import float64 from pyrecest.backend import zeros from pyrecest.backend import empty from pyrecest.backend import array @@ -53,12 +54,20 @@ def mean_direction_numerical(self, integration_boundaries=None): def f(x, i=i): return x[i] * self.pdf(x) - + fangles = self.gen_fun_hyperspherical_coords(f, self.dim) + + # Casts the floats to arrays, relevant for operations on torch.tensors + # that are not backward compatible + def fangles_array(*args): + tensors = [array([arg], dtype=float64) for arg in args] + result = fangles(*tensors) + return result.item() + if self.dim == 1: mu[i], _ = quad( - fangles, + fangles_array, integration_boundaries[0, 0], integration_boundaries[0, 1], epsabs=1e-3, @@ -66,13 +75,13 @@ def f(x, i=i): ) elif self.dim == 2: mu[i], _ = nquad( - fangles, + fangles_array, integration_boundaries, opts={"epsabs": 1e-3, "epsrel": 1e-3}, ) elif self.dim == 3: mu[i], _ = nquad( - fangles, + fangles_array, integration_boundaries, opts={"epsabs": 1e-3, "epsrel": 1e-3}, ) @@ -237,7 +246,7 @@ def g_2d(phi1, phi2): def g_3d(phi1, phi2, phi3): return ( - f_hypersph_coords(phi1, phi2, phi3) + f_hypersph_coords(array(phi1), array(phi2), array(phi3)) * sin(phi2) * (sin(phi3)) ** 2 ) diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_uniform_distribution.py b/pyrecest/distributions/hypertorus/hypertoroidal_uniform_distribution.py index ed4d6961..aeacb837 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_uniform_distribution.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_uniform_distribution.py @@ -24,8 +24,15 @@ def pdf(self, xs): :param xs: Values at which to evaluate the PDF :returns: PDF evaluated at xs """ - assert self.dim == xs.shape[-1] - n_inputs = xs.shape[0] if xs.ndim == 2 else 1 + if xs.ndim == 0: + assert self.dim==1 + elif xs.ndim == 1 and self.dim==1: + n_inputs = xs.shape[0] + elif xs.ndim == 1: + assert self.dim==xs.shape[0] + else: + n_inputs = xs.shape[0] + return 1.0 / self.get_manifold_size() * ones(n_inputs) def trigonometric_moment(self, n: Union[int, int32, int64]): diff --git a/pyrecest/tests/filters/test_circular_particle_filter.py b/pyrecest/tests/filters/test_circular_particle_filter.py index c3afefd8..76a2e1ff 100644 --- a/pyrecest/tests/filters/test_circular_particle_filter.py +++ b/pyrecest/tests/filters/test_circular_particle_filter.py @@ -135,7 +135,7 @@ def likelihood1(_, x): # test update with single parameter likelihood random.seed(0) self.filter.filter_state = self.dist - wn = WrappedNormalDistribution(1.3, 0.8) + wn = WrappedNormalDistribution(array(1.3), array(0.8)) def likelihood2(x): return wn.pdf(-x) From 9c96004dc426ee9521c9c0f13fd441b6c62b3882 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Sun, 22 Oct 2023 12:37:48 +0100 Subject: [PATCH 092/232] More...... --- .../circle/wrapped_normal_distribution.py | 2 +- pyrecest/filters/abstract_particle_filter.py | 2 +- .../tests/filters/test_circular_particle_filter.py | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pyrecest/distributions/circle/wrapped_normal_distribution.py b/pyrecest/distributions/circle/wrapped_normal_distribution.py index d38d79fb..c19db3ee 100644 --- a/pyrecest/distributions/circle/wrapped_normal_distribution.py +++ b/pyrecest/distributions/circle/wrapped_normal_distribution.py @@ -142,7 +142,7 @@ def multiply_vm(self, other): return wn def sample(self, n: Union[int, int32, int64]): - return mod(self.mu + self.sigma * random.randn(1, n), 2.0 * pi) + return mod(self.mu + self.sigma * random.normal(0.0, 1.0, (1, n)), 2.0 * pi) def shift(self, shift_by): assert shift_by.shape in ((1,), ()) diff --git a/pyrecest/filters/abstract_particle_filter.py b/pyrecest/filters/abstract_particle_filter.py index dcda19fd..9b7be82b 100644 --- a/pyrecest/filters/abstract_particle_filter.py +++ b/pyrecest/filters/abstract_particle_filter.py @@ -65,7 +65,7 @@ def predict_nonlinear_nonadditive(self, f, samples, weights): def update_identity( self, meas_noise, measurement, shift_instead_of_add: bool = True ): - assert measurement is None or measurement.shape == (meas_noise.dim,) + assert measurement is None or measurement.shape == (meas_noise.dim,) or meas_noise.dim == 1 and measurement.shape == () assert ( ndim(measurement) == 1 or ndim(measurement) == 0 diff --git a/pyrecest/tests/filters/test_circular_particle_filter.py b/pyrecest/tests/filters/test_circular_particle_filter.py index 76a2e1ff..59edad8f 100644 --- a/pyrecest/tests/filters/test_circular_particle_filter.py +++ b/pyrecest/tests/filters/test_circular_particle_filter.py @@ -37,8 +37,8 @@ def test_set_state(self): dist1 = self.filter.filter_state self.assertIsInstance(dist1, HypertoroidalDiracDistribution) self.assertEqual(dist1.dim, 1) - npt.assert_almost_equal(self.dist.d, dist1.d) - npt.assert_almost_equal(self.dist.w, dist1.w) + npt.assert_array_almost_equal(self.dist.d, dist1.d) + npt.assert_array_almost_equal(self.dist.w, dist1.w) def test_sampling(self): positions = arange(0, 1.1, 0.1) @@ -67,7 +67,7 @@ def f(x): dist2_identity = self.filter.filter_state self.assertIsInstance(dist2_identity, HypertoroidalDiracDistribution) self.assertEqual(dist2_identity.dim, 1) - npt.assert_almost_equal(dist2.w, dist2_identity.w) + npt.assert_array_almost_equal(dist2.w, dist2_identity.w) def test_nonlinear_prediction_without_noise(self): # nonlinear test without noise @@ -81,8 +81,8 @@ def f(x): predicted = self.filter.filter_state self.assertIsInstance(predicted, HypertoroidalDiracDistribution) dist_f = self.dist.apply_function(f) - npt.assert_almost_equal(predicted.d, dist_f.d, decimal=10) - npt.assert_almost_equal(predicted.w, dist_f.w, decimal=10) + npt.assert_array_almost_equal(predicted.d, dist_f.d, decimal=10) + npt.assert_array_almost_equal(predicted.w, dist_f.w, decimal=10) def test_update(self): # test update @@ -92,7 +92,7 @@ def test_update(self): def h(x): return x - z = 0 + z = array(0.0) def likelihood(z, x): return self.wn.pdf(z - h(x)) From eaa33af7090291df027f0dad89db4333faaff4de Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Sun, 22 Oct 2023 13:04:34 +0100 Subject: [PATCH 093/232] More... --- .../von_mises_fisher_distribution.py | 2 +- .../hypertoroidal_uniform_distribution.py | 2 ++ pyrecest/filters/abstract_particle_filter.py | 6 +++--- .../test_circular_uniform_distribution.py | 21 ++++++++++++------- ...st_custom_hypercylindrical_distribution.py | 11 ++++++---- .../test_von_mises_fisher_distribution.py | 2 +- 6 files changed, 27 insertions(+), 17 deletions(-) diff --git a/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py b/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py index 3fadea74..5f58a066 100644 --- a/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py @@ -118,7 +118,7 @@ def from_moment(m): mu_ = m / linalg.norm(m) Rbar = linalg.norm(m) - kappa_ = VonMisesFisherDistribution.a_d_inverse(np.size(m), Rbar) + kappa_ = VonMisesFisherDistribution.a_d_inverse(m.shape[0], Rbar) V = VonMisesFisherDistribution(mu_, kappa_) return V diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_uniform_distribution.py b/pyrecest/distributions/hypertorus/hypertoroidal_uniform_distribution.py index aeacb837..f9ac8c05 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_uniform_distribution.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_uniform_distribution.py @@ -26,10 +26,12 @@ def pdf(self, xs): """ if xs.ndim == 0: assert self.dim==1 + n_inputs = 1 elif xs.ndim == 1 and self.dim==1: n_inputs = xs.shape[0] elif xs.ndim == 1: assert self.dim==xs.shape[0] + n_inputs = 1 else: n_inputs = xs.shape[0] diff --git a/pyrecest/filters/abstract_particle_filter.py b/pyrecest/filters/abstract_particle_filter.py index 9b7be82b..bfd6d2e6 100644 --- a/pyrecest/filters/abstract_particle_filter.py +++ b/pyrecest/filters/abstract_particle_filter.py @@ -54,11 +54,11 @@ def predict_nonlinear_nonadditive(self, f, samples, weights): ), "samples and weights must match in size" weights = weights / sum(weights) - n = self.filter_state.w.size - noise_ids = random.choice(weights.size, n, p=weights) + n = self.filter_state.w.shape[0] + noise_samples = random.choice(self.filter_state.d, n, p=weights) d = zeros((n, self.filter_state.dim)) for i in range(n): - d[i, :] = f(self.filter_state.d[i, :], samples[noise_ids[i]]) + d[i, :] = f(self.filter_state.d[i, :], noise_samples[i]) self.filter_state.d = d diff --git a/pyrecest/tests/distributions/test_circular_uniform_distribution.py b/pyrecest/tests/distributions/test_circular_uniform_distribution.py index f9f4cdba..48a207eb 100644 --- a/pyrecest/tests/distributions/test_circular_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_circular_uniform_distribution.py @@ -2,6 +2,7 @@ from pyrecest.backend import ones from pyrecest.backend import array import unittest +import pyrecest.backend import numpy.testing as npt from pyrecest.distributions.circle.circular_uniform_distribution import ( @@ -12,25 +13,27 @@ class CircularUniformDistributionTest(unittest.TestCase): def test_pdf(self): cu = CircularUniformDistribution() - x = array([1, 2, 3, 4, 5, 6]) + x = array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]) # Test pdf - npt.assert_allclose(cu.pdf(x), 1 / (2 * pi) * ones(x.shape)) + npt.assert_allclose(cu.pdf(x), 1.0 / (2.0 * pi) * ones(x.shape)) def test_shift(self): cu = CircularUniformDistribution() cu2 = cu.shift(3) - x = array([1, 2, 3, 4, 5, 6]) - npt.assert_allclose(cu2.pdf(x), 1 / (2 * pi) * ones(x.shape)) + x = array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]) + npt.assert_allclose(cu2.pdf(x), 1.0 / (2.0 * pi) * ones(x.shape)) + @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") def test_cdf(self): cu = CircularUniformDistribution() - x = array([1, 2, 3, 4, 5, 6]) + x = array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]) npt.assert_allclose(cu.cdf(x), cu.cdf_numerical(x)) + @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") def test_cdf_with_shift(self): cu = CircularUniformDistribution() - x = array([1, 2, 3, 4, 5, 6]) + x = array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]) cu2 = cu.shift(3) npt.assert_allclose(cu2.cdf(x), cu2.cdf_numerical(x)) @@ -39,20 +42,22 @@ def test_trigonometric_moment(self): npt.assert_allclose( cu.trigonometric_moment(0), cu.trigonometric_moment_numerical(0) ) - npt.assert_allclose(cu.trigonometric_moment(0), 1) + npt.assert_allclose(cu.trigonometric_moment(0), 1.0) def test_trigonometric_moment_with_shift(self): cu = CircularUniformDistribution() npt.assert_allclose( cu.trigonometric_moment(1), cu.trigonometric_moment_numerical(1), atol=1e-10 ) - npt.assert_allclose(cu.trigonometric_moment(1), 0, atol=1e-10) + npt.assert_allclose(cu.trigonometric_moment(1), 0.0, atol=1e-10) + @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") def test_integral(self): cu = CircularUniformDistribution() npt.assert_allclose(cu.integrate(), cu.integrate_numerically()) npt.assert_allclose(cu.integrate(), 1) + @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") def test_integral_with_range(self): cu = CircularUniformDistribution() npt.assert_allclose( diff --git a/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py b/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py index 9c01d5dd..8699dfa7 100644 --- a/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py +++ b/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py @@ -3,6 +3,8 @@ from pyrecest.backend import linspace from pyrecest.backend import eye from pyrecest.backend import array +from pyrecest.backend import arange +from pyrecest.backend import meshgrid import pyrecest.backend import unittest import numpy.testing as npt @@ -24,10 +26,10 @@ def setUp(self) -> None: self.pwn = PartiallyWrappedNormalDistribution( array([2.0, 3.0, 4.0, 5.0, 6.0, 7.0]), mat, 3 ) - grid = np.mgrid[-3:4, -3:4, -2:3, -2:3, -2:3, -2:3] - self.grid_flat = grid.reshape(6, -1).T + grid = meshgrid(arange(-3, 4), arange(-3, 4), arange(-2, 3), arange(-2, 3), arange(-2, 3), arange(-2, 3)) + self.grid_flat = array(grid).reshape(6, -1).T - self.vm = VonMisesDistribution(0.0, 1.0) + self.vm = VonMisesDistribution(array(0.0), array(1.0)) self.gauss = GaussianDistribution(array([1.0, 2.0]), eye(2)) def fun(x): @@ -58,7 +60,8 @@ def test_condition_on_linear(self): def test_condition_on_periodic(self): dist = self.chcd_vm_gauss_stacked.condition_on_periodic(array(1.0)) - grid = np.mgrid[-3:4, -3:4].reshape(2, -1).T + grid = meshgrid(arange(-3, 4), arange(-3, 4)) + self.grid_flat = array(grid).reshape(2, -1).T npt.assert_allclose(dist.pdf(grid), self.gauss.pdf(grid)) diff --git a/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py b/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py index 4338a936..56379dcf 100644 --- a/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py +++ b/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py @@ -196,7 +196,7 @@ def test_from_distribution_vmf(self, _, mu, kappa): def test_from_distribution_dirac(self): dirac_dist = HypersphericalDiracDistribution( array( - [[0.0, 0.0, 1.0], [0.0, 1.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 1.0] / linalg.norm([0.0, 1.0, 1.0])] + [[0.0, 0.0, 1.0], [0.0, 1.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 1.0] / linalg.norm(array([0.0, 1.0, 1.0]))] ) ) vmf = VonMisesFisherDistribution.from_distribution(dirac_dist) From b9ff269e790bf7ff49ed83bcaf9d9595f2a1145c Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Sun, 22 Oct 2023 13:13:51 +0100 Subject: [PATCH 094/232] More. --- .../abstract_hypersphere_subset_distribution.py | 6 +++--- .../abstract_hyperspherical_distribution.py | 2 +- .../test_von_mises_fisher_distribution.py | 14 +++++++------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py index 8829755b..c4f2b03b 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py @@ -152,7 +152,7 @@ def g_gen(f_hypersph_coords, dim): if dim == 1: def g_1d(phi): - return f_hypersph_coords(phi) + return f_hypersph_coords(array(phi)) return g_1d if dim == 2: @@ -165,7 +165,7 @@ def g_2d(phi1, phi2): def g_3d(phi1, phi2, phi3): return ( - f_hypersph_coords(phi1, phi2, phi3) + f_hypersph_coords(array(phi1), array(phi2), array(phi3)) * sin(phi2) * sin(phi3) ** 2 ) @@ -227,7 +227,7 @@ def integrate_fun_over_domain_part( ): if dim == 1: i, _ = quad( - f_hypersph_coords, + lambda phi: f_hypersph_coords(array(phi)), integration_boundaries[0], integration_boundaries[1], epsabs=0.01, diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py index 5edabc41..8c3bf28b 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py @@ -189,7 +189,7 @@ def entropy(self): def mode_numerical(self): def fun(s): - return -self.pdf(AbstractHypersphereSubsetDistribution.polar_to_cart(s)) + return -self.pdf(AbstractHypersphereSubsetDistribution.polar_to_cart(array(s))) s0 = random.rand(self.dim) * pi res = minimize( diff --git a/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py b/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py index 56379dcf..15834536 100644 --- a/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py +++ b/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py @@ -126,7 +126,7 @@ def test_pdf_3d(self): [1.0, 0.0, 0.0, -1.0], ] ) - xs = xs_unnorm / linalg.norm(xs_unnorm, axis=1, keepdims=True) + xs = xs_unnorm / linalg.norm(xs_unnorm, axis=1).reshape(-1, 1) npt.assert_array_almost_equal( dist.pdf(xs), @@ -169,15 +169,15 @@ def _test_hellinger_distance_helper( def test_hellinger_distance_2d(self): # 2D - vmf1 = VonMisesFisherDistribution(array([1.0, 0.0]), 0.9) - vmf2 = VonMisesFisherDistribution(array([0.0, 1.0]), 1.7) + vmf1 = VonMisesFisherDistribution(array([1.0, 0.0]), array(0.9)) + vmf2 = VonMisesFisherDistribution(array([0.0, 1.0]), array(1.7)) self._test_hellinger_distance_helper(vmf1, vmf2) def test_hellinger_distance_3d(self): # 3D - vmf1 = VonMisesFisherDistribution(array([1.0, 0.0, 0.0]), 0.6) - mu2 = array([1, 2, 3]) - vmf2 = VonMisesFisherDistribution(mu2 / linalg.norm(mu2), 2.1) + vmf1 = VonMisesFisherDistribution(array([1.0, 0.0, 0.0]), array(0.6)) + mu2 = array([1.0, 2.0, 3.0]) + vmf2 = VonMisesFisherDistribution(mu2 / linalg.norm(mu2), array(2.1)) self._test_hellinger_distance_helper(vmf1, vmf2, numerical_delta=1e-6) @parameterized.expand( @@ -196,7 +196,7 @@ def test_from_distribution_vmf(self, _, mu, kappa): def test_from_distribution_dirac(self): dirac_dist = HypersphericalDiracDistribution( array( - [[0.0, 0.0, 1.0], [0.0, 1.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 1.0] / linalg.norm(array([0.0, 1.0, 1.0]))] + [[0.0, 0.0, 1.0], [0.0, 1.0, 0.0], [1.0, 0.0, 0.0], array([0.0, 1.0, 1.0]) / linalg.norm(array([0.0, 1.0, 1.0]))] ) ) vmf = VonMisesFisherDistribution.from_distribution(dirac_dist) From 9baa1ab34da2d8dc8eb16dd94d8e11ee1ec29dd8 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Sun, 22 Oct 2023 13:23:15 +0100 Subject: [PATCH 095/232] More........ --- .../distributions/circle/wrapped_normal_distribution.py | 6 +++--- .../abstract_hyperspherical_distribution.py | 2 +- .../hypertorus/abstract_hypertoroidal_distribution.py | 2 +- .../hypertoroidal_wrapped_normal_distribution.py | 2 +- pyrecest/filters/wrapped_normal_filter.py | 2 +- .../distributions/test_wrapped_laplace_distribution.py | 8 ++++---- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/pyrecest/distributions/circle/wrapped_normal_distribution.py b/pyrecest/distributions/circle/wrapped_normal_distribution.py index c19db3ee..899e2bd9 100644 --- a/pyrecest/distributions/circle/wrapped_normal_distribution.py +++ b/pyrecest/distributions/circle/wrapped_normal_distribution.py @@ -154,9 +154,9 @@ def to_vm(self) -> VonMisesDistribution: return VonMisesDistribution(self.mu, kappa) @staticmethod - def from_moment(m: complex) -> "WrappedNormalDistribution": - mu = mod(angle(m), 2.0 * pi) - sigma = sqrt(-2 * log(abs(m))) + def from_moment(m) -> "WrappedNormalDistribution": + mu = mod(angle(m.squeeze()), 2.0 * pi) + sigma = sqrt(-2 * log(abs(m.squeeze()))) return WrappedNormalDistribution(mu, sigma) @staticmethod diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py index 8c3bf28b..98e296ba 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py @@ -198,7 +198,7 @@ def fun(s): method="BFGS", options={"disp": False, "gtol": 1e-12, "maxiter": 2000}, ) - m = AbstractHypersphereSubsetDistribution.polar_to_cart(res.x) + m = AbstractHypersphereSubsetDistribution.polar_to_cart(array(res.x)) return m def hellinger_distance(self, other): diff --git a/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py b/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py index 1ac7463b..fd525586 100644 --- a/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py +++ b/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py @@ -260,7 +260,7 @@ def sample_metropolis_hastings( burn_in: Union[int, int32, int64] = 10, skipping: Union[int, int32, int64] = 5, proposal: Callable | None = None, - start_point = None, + start_point=None, ): # jscpd:ignore-end if proposal is None: diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py b/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py index b873bfe7..706c7c94 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py @@ -32,7 +32,7 @@ def __init__(self, mu, C): :raises AssertionError: If C_ is not square, not symmetric, not positive definite, or its dimension does not match with mu_. """ numel_mu = 1 if mu.ndim == 0 else mu.shape[0] - assert C.ndim == 0 or C.ndim == 2 and C.shape[0] == C.shape[1], "C must be dim x dim" + assert C.ndim == 0 or C.ndim == 2 and C.shape[0] == C.shape[1], "C must be of shape (dim, dim)" assert allclose(C, C.T, atol=1e-8), "C must be symmetric" assert (C.ndim == 0 and C > 0.0 or len(linalg.cholesky(C)) > 0 # fails if not positiv definite diff --git a/pyrecest/filters/wrapped_normal_filter.py b/pyrecest/filters/wrapped_normal_filter.py index f36bece3..662b6aa8 100644 --- a/pyrecest/filters/wrapped_normal_filter.py +++ b/pyrecest/filters/wrapped_normal_filter.py @@ -22,7 +22,7 @@ def predict_identity(self, wn_sys): self.filter_state = self.filter_state.convolve(wn_sys) def update_identity(self, wn_meas, z): - mu_w_new = mod(z - wn_meas.mu, 2 * pi) + mu_w_new = mod(z - wn_meas.mu, 2.0 * pi) wn_meas_shifted = WrappedNormalDistribution(mu_w_new, wn_meas.sigma) self.filter_state = self.filter_state.multiply_vm(wn_meas_shifted) diff --git a/pyrecest/tests/distributions/test_wrapped_laplace_distribution.py b/pyrecest/tests/distributions/test_wrapped_laplace_distribution.py index 2f348609..10d9819e 100644 --- a/pyrecest/tests/distributions/test_wrapped_laplace_distribution.py +++ b/pyrecest/tests/distributions/test_wrapped_laplace_distribution.py @@ -36,7 +36,7 @@ def pdftemp(x): return sum(laplace(z) for z in x + 2.0 * pi * arange(-20, 21)) for x in [0.0, 1.0, 2.0, 3.0, 4.0]: - npt.assert_allclose(self.wl.pdf(x), pdftemp(x), rtol=1e-10) + npt.assert_allclose(self.wl.pdf(array(x)), pdftemp(array(x)), rtol=1e-10) @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") def test_integral(self): @@ -44,7 +44,7 @@ def test_integral(self): npt.assert_allclose(self.wl.integrate_numerically(), 1.0, rtol=1e-10) npt.assert_allclose( self.wl.integrate(array([0.0, pi])) + self.wl.integrate(array([pi, 2.0 * pi])), - 1, + 1.0, rtol=1e-10, ) @@ -58,8 +58,8 @@ def test_angular_moments(self): def test_periodicity(self): npt.assert_allclose( - self.wl.pdf(linspace(-2 * pi, 0, 100)), - self.wl.pdf(linspace(0, 2 * pi, 100)), + self.wl.pdf(linspace(-2.0 * pi, 0.0, 100)), + self.wl.pdf(linspace(0.0, 2.0 * pi, 100)), rtol=1e-10, ) From 58d4436dcb0f09f26081bc240585d85fa0a6e35b Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Sun, 22 Oct 2023 14:09:27 +0100 Subject: [PATCH 096/232] More.. --- .../distributions/hypersphere_subset/watson_distribution.py | 4 ++-- pyrecest/tests/distributions/test_watson_distribution.py | 2 +- pyrecest/tests/test_metrics.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pyrecest/distributions/hypersphere_subset/watson_distribution.py b/pyrecest/distributions/hypersphere_subset/watson_distribution.py index 2f304177..525aa695 100644 --- a/pyrecest/distributions/hypersphere_subset/watson_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/watson_distribution.py @@ -71,9 +71,9 @@ def to_bingham(self) -> BinghamDistribution: E = eye(self.input_dim) E[0, 0] = 0 M = M + E - Q, _ = qr(M) + Q, _ = array(qr(M)) M = hstack([Q[:, 1:], Q[:, 0].reshape(-1, 1)]) - Z = hstack([full((self.dim), -self.kappa), 0]) + Z = hstack((full((self.dim,), -self.kappa), array(0.0))) return BinghamDistribution(Z, M) def sample(self, n): diff --git a/pyrecest/tests/distributions/test_watson_distribution.py b/pyrecest/tests/distributions/test_watson_distribution.py index a7f834d6..5ebb7f1b 100644 --- a/pyrecest/tests/distributions/test_watson_distribution.py +++ b/pyrecest/tests/distributions/test_watson_distribution.py @@ -58,7 +58,7 @@ def test_to_bingham(self): watson_dist = WatsonDistribution(mu, kappa) bingham_dist = watson_dist.to_bingham() self.assertIsInstance(bingham_dist, BinghamDistribution) - npt.assert_almost_equal( + npt.assert_array_almost_equal( watson_dist.pdf(self.xs), bingham_dist.pdf(self.xs), decimal=5 ) diff --git a/pyrecest/tests/test_metrics.py b/pyrecest/tests/test_metrics.py index ca0c2b51..89b42e25 100644 --- a/pyrecest/tests/test_metrics.py +++ b/pyrecest/tests/test_metrics.py @@ -2,7 +2,7 @@ from pyrecest.backend import repeat from pyrecest.backend import array import unittest - +import numpy.testing as npt from pyrecest.utils.metrics import anees From 03016f8011e16ca55d515823b186c447b167ef4b Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Sun, 22 Oct 2023 14:19:33 +0100 Subject: [PATCH 097/232] Make linter ignore pytorch --- .github/workflows/mega-linter.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/mega-linter.yml b/.github/workflows/mega-linter.yml index f0454b90..8a00a80e 100644 --- a/.github/workflows/mega-linter.yml +++ b/.github/workflows/mega-linter.yml @@ -93,6 +93,12 @@ jobs: sed 's/==.*//' requirements-dev.txt > requirements-dev_no_version.txt shell: alpine.sh {0} + - name: Remove torch entry (unsupported by alpine) + if: steps.cache-wheels.outputs.cache-hit != 'true' + run: | + sed -i '/^torch/d' requirements-dev_no_version.txt + shell: alpine.sh {0} + - name: Run CMake to find LAPACK if: steps.cache-wheels.outputs.cache-hit != 'true' run: | From 9d5cb9e7cd48db75dfa0b47c37bb564a2a769c03 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Sun, 22 Oct 2023 14:19:46 +0100 Subject: [PATCH 098/232] More --- .../hypersphere_subset/von_mises_fisher_distribution.py | 3 +-- .../distributions/hypersphere_subset/watson_distribution.py | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py b/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py index 5f58a066..1360abef 100644 --- a/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py @@ -19,7 +19,6 @@ from beartype import beartype -from scipy.linalg import qr from scipy.special import iv from .abstract_hyperspherical_distribution import AbstractHypersphericalDistribution @@ -92,7 +91,7 @@ def sample_deterministic(self): def get_rotation_matrix(self): M = zeros((self.dim + 1, self.dim + 1)) M[:, 0] = self.mu - Q, R = qr(M) + Q, R = linalg.qr(M) if R[0, 0] < 0: Q = -Q return Q diff --git a/pyrecest/distributions/hypersphere_subset/watson_distribution.py b/pyrecest/distributions/hypersphere_subset/watson_distribution.py index 525aa695..a0c517cb 100644 --- a/pyrecest/distributions/hypersphere_subset/watson_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/watson_distribution.py @@ -71,7 +71,7 @@ def to_bingham(self) -> BinghamDistribution: E = eye(self.input_dim) E[0, 0] = 0 M = M + E - Q, _ = array(qr(M)) + Q, _ = linalg.qr(M) M = hstack([Q[:, 1:], Q[:, 0].reshape(-1, 1)]) Z = hstack((full((self.dim,), -self.kappa), array(0.0))) return BinghamDistribution(Z, M) From dafa89bef9339fc296b8c55b93b120efbf527f79 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Sun, 22 Oct 2023 16:06:49 +0100 Subject: [PATCH 099/232] Do not check backend with megalinter --- .mega-linter.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.mega-linter.yml b/.mega-linter.yml index 0e11e540..b7902081 100644 --- a/.mega-linter.yml +++ b/.mega-linter.yml @@ -13,3 +13,5 @@ DISABLE_LINTERS: - JSON_JSONLINT # Disable because there is only .devcontainer.json, for which it throws an unwanted warning - MAKEFILE_CHECKMAKE # Not using a Makefile - SPELL_LYCHEE # Takes pretty long + +FILTER_REGEX_EXCLUDE: 'pyrecest._backend/*' From c36ea765827381b34668aa6b95d053838403b997 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Sun, 22 Oct 2023 16:06:59 +0100 Subject: [PATCH 100/232] More --- pyrecest/_backend/__init__.py | 2 ++ pyrecest/_backend/numpy/__init__.py | 2 ++ pyrecest/_backend/pytorch/__init__.py | 20 +++++++++++++++++++ pyrecest/distributions/abstract_mixture.py | 6 +++--- .../nonperiodic/linear_dirac_distribution.py | 5 +++-- ...est_hypercylindrical_dirac_distribution.py | 2 +- .../test_hyperspherical_mixture.py | 3 ++- .../distributions/test_linear_mixture.py | 8 ++++---- .../filters/test_random_matrix_tracker.py | 1 + 9 files changed, 38 insertions(+), 11 deletions(-) diff --git a/pyrecest/_backend/__init__.py b/pyrecest/_backend/__init__.py index 8848591b..cc5936a6 100644 --- a/pyrecest/_backend/__init__.py +++ b/pyrecest/_backend/__init__.py @@ -182,6 +182,8 @@ def get_backend_name(): "kron", "angle", "arctan", + "cov", + "count_nonzero", ], "autodiff": [ "custom_gradient", diff --git a/pyrecest/_backend/numpy/__init__.py b/pyrecest/_backend/numpy/__init__.py index 42d7babf..10d3fd80 100644 --- a/pyrecest/_backend/numpy/__init__.py +++ b/pyrecest/_backend/numpy/__init__.py @@ -87,6 +87,8 @@ kron, angle, arctan, + cov, + count_nonzero ) from scipy.special import erf, gamma, polygamma # NOQA diff --git a/pyrecest/_backend/pytorch/__init__.py b/pyrecest/_backend/pytorch/__init__.py index cc4dd973..3ae9b251 100644 --- a/pyrecest/_backend/pytorch/__init__.py +++ b/pyrecest/_backend/pytorch/__init__.py @@ -48,6 +48,7 @@ kron, angle, arctan, + count_nonzero, ) from torch import repeat_interleave as repeat from torch import ( @@ -128,6 +129,25 @@ def _raise_not_implemented_error(*args, **kwargs): std = _preserve_input_dtype(_add_default_dtype_by_casting(target=_torch.std)) +def cov(input, correction=1, fweights=None, aweights=None, bias=False): + # for pyrecest + if not bias: + return _torch.cov(input, correction=correction, fweights=fweights, aweights=aweights) + else: + assert fweights==None + # Ensure weights sum to 1 + aweights = aweights / aweights.sum() + + # Calculate weighted means + means = (input * aweights).sum(dim=1, keepdim=True) + + deviation_centered = input - means + + # Calculate weighted biased covariance + cov_matrix = _torch.einsum('ij,kj,j->ik', deviation_centered, deviation_centered, aweights) + + return cov_matrix + def matmul(x, y, out=None): for array_ in [x, y]: diff --git a/pyrecest/distributions/abstract_mixture.py b/pyrecest/distributions/abstract_mixture.py index d7a5aabe..2a07e141 100644 --- a/pyrecest/distributions/abstract_mixture.py +++ b/pyrecest/distributions/abstract_mixture.py @@ -6,7 +6,7 @@ from pyrecest.backend import int32 from pyrecest.backend import empty from pyrecest.backend import zeros -from pyrecest.backend import nonzero +from pyrecest.backend import count_nonzero import collections import copy import warnings @@ -43,9 +43,9 @@ def __init__( if not all(dists[0].dim == dist.dim for dist in dists): raise ValueError("All distributions must have the same dimension") - non_zero_indices = nonzero(weights)[0] + non_zero_indices = count_nonzero(weights) - if len(non_zero_indices) < len(weights): + if non_zero_indices < len(weights): warnings.warn( "Elements with zero weights detected. Pruning elements in mixture with weight zero." ) diff --git a/pyrecest/distributions/nonperiodic/linear_dirac_distribution.py b/pyrecest/distributions/nonperiodic/linear_dirac_distribution.py index ea1dc2fd..a0c83dfc 100644 --- a/pyrecest/distributions/nonperiodic/linear_dirac_distribution.py +++ b/pyrecest/distributions/nonperiodic/linear_dirac_distribution.py @@ -1,5 +1,6 @@ from pyrecest.backend import reshape from pyrecest.backend import ones +from pyrecest.backend import cov import matplotlib.pyplot as plt @@ -51,8 +52,8 @@ def weighted_samples_to_mean_and_cov(samples, weights=None): if weights is None: weights = ones(samples.shape[1]) / samples.shape[1] - mean = np.average(samples, weights=weights, axis=0) + mean = (samples * weights.reshape(-1, 1)).sum(dim=0) deviation = samples - mean - covariance = np.cov(deviation.T, aweights=weights, bias=True) + covariance = cov(deviation.T, aweights=weights, bias=True) return mean, covariance \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py b/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py index 19872f0e..a75c6a4a 100644 --- a/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py @@ -50,7 +50,7 @@ def test_apply_function_identity(self): assert self.pwd.bound_dim == same.bound_dim def test_apply_function_shift(self): - shift_offset = array([1.4, -0.3, 1]) + shift_offset = array([1.4, -0.3, 1.0]) def shift(x, shift_by=shift_offset): return x + shift_by diff --git a/pyrecest/tests/distributions/test_hyperspherical_mixture.py b/pyrecest/tests/distributions/test_hyperspherical_mixture.py index 1a1e6538..ea64d227 100644 --- a/pyrecest/tests/distributions/test_hyperspherical_mixture.py +++ b/pyrecest/tests/distributions/test_hyperspherical_mixture.py @@ -3,6 +3,7 @@ from pyrecest.backend import stack from pyrecest.backend import sqrt from pyrecest.backend import meshgrid +from pyrecest.backend import arange from pyrecest.backend import linspace from pyrecest.backend import array import unittest @@ -43,7 +44,7 @@ def test_pdf_4d(self): w = array([0.3, 0.7]) smix = HypersphericalMixture([wad, vmf], w) - a, b, c, d = np.mgrid[-1:1:4j, -1:1:4j, -1:1:4j, -1:1:4j] + a, b, c, d = meshgrid(arange(-1, 4), arange(-1, 4), arange(-1, 4), arange(-1, 4)) points = array([a.ravel(), b.ravel(), c.ravel(), d.ravel()]).T points = points / sqrt(sum(points**2, axis=1, keepdims=True)) diff --git a/pyrecest/tests/distributions/test_linear_mixture.py b/pyrecest/tests/distributions/test_linear_mixture.py index 19da99b3..8da82e33 100644 --- a/pyrecest/tests/distributions/test_linear_mixture.py +++ b/pyrecest/tests/distributions/test_linear_mixture.py @@ -17,8 +17,8 @@ def test_constructor_warning(self): simplefilter("always") LinearMixture( [ - GaussianDistribution(array([1]), array([[1]])), - GaussianDistribution(array([50]), array([[1]])), + GaussianDistribution(array([1.0]), array([[1.0]])), + GaussianDistribution(array([50.0]), array([[1.0]])), ], array([0.3, 0.7]), ) @@ -30,8 +30,8 @@ def test_constructor_warning(self): ) def test_pdf(self): - gm1 = GaussianDistribution(array([1, 1]), diag([2, 3])) - gm2 = GaussianDistribution(-array([3, 1]), diag([2, 3])) + gm1 = GaussianDistribution(array([1.0, 1.0]), diag(array([2.0, 3.0]))) + gm2 = GaussianDistribution(-array([3.0, 1.0]), diag(array([2.0, 3.0]))) with catch_warnings(): simplefilter("ignore", category=UserWarning) diff --git a/pyrecest/tests/filters/test_random_matrix_tracker.py b/pyrecest/tests/filters/test_random_matrix_tracker.py index 4d5d76ad..ef42cca8 100644 --- a/pyrecest/tests/filters/test_random_matrix_tracker.py +++ b/pyrecest/tests/filters/test_random_matrix_tracker.py @@ -7,6 +7,7 @@ from pyrecest.backend import zeros import unittest from unittest.mock import patch +import numpy.testing as npt import matplotlib.pyplot as plt From f614fdd63523458b5a0340d5b7d31944aa523cdc Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Sun, 22 Oct 2023 16:17:56 +0100 Subject: [PATCH 101/232] More... --- .../distributions/test_linear_dirac_distribution.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/pyrecest/tests/distributions/test_linear_dirac_distribution.py b/pyrecest/tests/distributions/test_linear_dirac_distribution.py index da82a8fb..a6fee6a2 100644 --- a/pyrecest/tests/distributions/test_linear_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_linear_dirac_distribution.py @@ -5,6 +5,7 @@ from pyrecest.backend import all import unittest +import numpy.testing as npt from pyrecest.distributions import GaussianDistribution from pyrecest.distributions.nonperiodic.linear_dirac_distribution import ( @@ -18,14 +19,14 @@ def test_from_distribution(self): random.seed(0) C = wishart.rvs(3, eye(3)) hwn = GaussianDistribution(array([1.0, 2.0, 3.0]), array(C)) - hwd = LinearDiracDistribution.from_distribution(hwn, 150000) - self.assertTrue(allclose(hwd.mean(), hwn.mean(), atol=0.005)) - self.assertTrue(allclose(hwd.covariance(), hwn.covariance(), rtol=0.01)) + hwd = LinearDiracDistribution.from_distribution(hwn, 200000) + npt.assert_allclose(hwd.mean(), hwn.mean(), atol=0.005) + npt.assert_allclose(hwd.covariance(), hwn.covariance(), rtol=0.1) def test_mean_and_cov(self): random.seed(0) gd = GaussianDistribution(array([1.0, 2.0]), array([[2.0, -0.3], [-0.3, 1.0]])) - ddist = LinearDiracDistribution(gd.sample(10000)) + ddist = LinearDiracDistribution(gd.sample(15000)) self.assertTrue(allclose(ddist.mean(), gd.mean(), atol=0.05)) self.assertTrue(allclose(ddist.covariance(), gd.covariance(), atol=0.05)) From 5c770bda8f4e495df1353d7d13a4cff0a45b9d22 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Sun, 22 Oct 2023 17:25:51 +0100 Subject: [PATCH 102/232] More...... --- pyrecest/_backend/__init__.py | 1 + pyrecest/_backend/numpy/__init__.py | 3 +- pyrecest/_backend/pytorch/__init__.py | 1 + ...pherical_harmonics_distribution_complex.py | 6 +-- .../spherical_harmonics_distribution_real.py | 9 ++-- .../von_mises_fisher_distribution.py | 2 +- pyrecest/filters/kalman_filter.py | 6 ++- pyrecest/filters/random_matrix_tracker.py | 2 +- ...pherical_harmonics_distribution_complex.py | 52 +++++++++---------- ...t_spherical_harmonics_distribution_real.py | 2 +- pyrecest/tests/filters/test_kalman_filter.py | 15 ++++-- .../filters/test_random_matrix_tracker.py | 2 + 12 files changed, 56 insertions(+), 45 deletions(-) diff --git a/pyrecest/_backend/__init__.py b/pyrecest/_backend/__init__.py index cc5936a6..db1b6e80 100644 --- a/pyrecest/_backend/__init__.py +++ b/pyrecest/_backend/__init__.py @@ -184,6 +184,7 @@ def get_backend_name(): "arctan", "cov", "count_nonzero", + "full_like", ], "autodiff": [ "custom_gradient", diff --git a/pyrecest/_backend/numpy/__init__.py b/pyrecest/_backend/numpy/__init__.py index 10d3fd80..2104bcaf 100644 --- a/pyrecest/_backend/numpy/__init__.py +++ b/pyrecest/_backend/numpy/__init__.py @@ -88,7 +88,8 @@ angle, arctan, cov, - count_nonzero + count_nonzero, + full_like, ) from scipy.special import erf, gamma, polygamma # NOQA diff --git a/pyrecest/_backend/pytorch/__init__.py b/pyrecest/_backend/pytorch/__init__.py index 3ae9b251..24a91f5f 100644 --- a/pyrecest/_backend/pytorch/__init__.py +++ b/pyrecest/_backend/pytorch/__init__.py @@ -49,6 +49,7 @@ angle, arctan, count_nonzero, + full_like, ) from torch import repeat_interleave as repeat from torch import ( diff --git a/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py b/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py index f30782e8..bbac0de0 100644 --- a/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py +++ b/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py @@ -101,11 +101,11 @@ def to_spherical_harmonics_distribution_real(self): return shd def mean_direction(self): - if prod(self.coeff_mat.shape) <= 1: + if self.coeff_mat.shape[0] <= 1: raise ValueError("Too few coefficients available to calculate the mean") - y = imag(self.coeff_mat[1, 0] + self.coeff_mat[1, 2]) / sqrt(2) - x = real(self.coeff_mat[1, 0] - self.coeff_mat[1, 2]) / sqrt(2) + y = imag(self.coeff_mat[1, 0] + self.coeff_mat[1, 2]) / sqrt(2.0) + x = real(self.coeff_mat[1, 0] - self.coeff_mat[1, 2]) / sqrt(2.0) z = real(self.coeff_mat[1, 1]) if linalg.norm(array([x, y, z])) < 1e-9: diff --git a/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_real.py b/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_real.py index 506dc6d5..8e57dc0e 100644 --- a/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_real.py +++ b/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_real.py @@ -1,4 +1,4 @@ -from pyrecest.backend import full +from pyrecest.backend import full_like from pyrecest.backend import atleast_2d from pyrecest.backend import sqrt from pyrecest.backend import real @@ -6,6 +6,7 @@ from pyrecest.backend import all from pyrecest.backend import zeros from pyrecest.backend import isreal +from pyrecest.backend import complex128 @@ -63,19 +64,19 @@ def to_spherical_harmonics_distribution_complex(self): raise NotImplementedError("Transformation currently not supported") real_coeff_mat = self.coeff_mat - complex_coeff_mat = full_like(real_coeff_mat, float('NaN'), dtype=complex) + complex_coeff_mat = full_like(real_coeff_mat, float('NaN'), dtype=complex128) for n in range(real_coeff_mat.shape[0]): for m in range(-n, n + 1): if m < 0: complex_coeff_mat[n, n + m] = ( 1j * real_coeff_mat[n, n + m] + real_coeff_mat[n, n - m] - ) / sqrt(2) + ) / sqrt(2.0) elif m > 0: complex_coeff_mat[n, n + m] = ( (-1) ** m * (-1j * real_coeff_mat[n, n - m] + real_coeff_mat[n, n + m]) - / sqrt(2) + / sqrt(2.0) ) else: # m == 0 complex_coeff_mat[n, n] = real_coeff_mat[n, n] diff --git a/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py b/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py index 1360abef..dfca8050 100644 --- a/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py @@ -62,7 +62,7 @@ def sample(self, n): array: n von Mises-Fisher distributed random vectors. # Requires scipy 1.11 or later """ - assert pyrecest.backend.__name__ == "pyrec.backend.numpy", "Only supported on NumPy backend" + assert pyrecest.backend.__name__ == "pyrecest.numpy", "Only supported on NumPy backend" from scipy.stats import vonmises_fisher # Create a von Mises-Fisher distribution object diff --git a/pyrecest/filters/kalman_filter.py b/pyrecest/filters/kalman_filter.py index f7587af7..5aa6f346 100644 --- a/pyrecest/filters/kalman_filter.py +++ b/pyrecest/filters/kalman_filter.py @@ -6,7 +6,7 @@ from .abstract_euclidean_filter import AbstractEuclideanFilter - +import pyrecest.backend class KalmanFilter(AbstractEuclideanFilter): def __init__(self, initial_state): """ @@ -50,7 +50,7 @@ def filter_state(self, new_state): "new_state must be a GaussianDistribution or a tuple of (mean, covariance)" ) - def predict_identity(self, sys_noise_cov, sys_input = None): + def predict_identity(self, sys_noise_cov, sys_input=None): """ Predicts the next state assuming identity transition matrix. @@ -74,6 +74,7 @@ def predict_linear( :param sys_noise_cov: System noise covariance. :param sys_input: System input. """ + assert pyrecest.backend.__name__ == "pyrecest.numpy", "Only supported on NumPy backend" if sys_input is not None and system_matrix.shape[0] != sys_input.shape[0]: raise ValueError( "The number of rows in system_matrix should match the number of elements in sys_input" @@ -108,6 +109,7 @@ def update_linear( :param measurement_matrix: Measurement matrix. :param meas_noise: Covariance matrix for measurement. """ + assert pyrecest.backend.__name__ == "pyrecest.numpy", "Only supported on NumPy backend" self._filter_state.dim_z = measurement_matrix.shape[0] self._filter_state.update(z=measurement, R=meas_noise, H=measurement_matrix) diff --git a/pyrecest/filters/random_matrix_tracker.py b/pyrecest/filters/random_matrix_tracker.py index da34432d..c44e17ee 100644 --- a/pyrecest/filters/random_matrix_tracker.py +++ b/pyrecest/filters/random_matrix_tracker.py @@ -44,7 +44,7 @@ def predict(self, dt, Cw, tau, system_matrix): x_rows = self.kinematic_state.shape[0] y_rows = x_rows // 2 - if np.isscalar(Cw): + if Cw.shape in ((), (1,)): Cw = Cw * eye(x_rows) self.kinematic_state = F @ self.kinematic_state diff --git a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py index cdbb957e..93d87a1f 100644 --- a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py +++ b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py @@ -57,7 +57,7 @@ def setUp(self): ) def test_mormalization_error(self): - self.assertRaises(ValueError, SphericalHarmonicsDistributionComplex, 0) + self.assertRaises(ValueError, SphericalHarmonicsDistributionComplex, array(0.0)) def test_normalization(self): with self.assertWarns(Warning): @@ -67,8 +67,8 @@ def test_normalization(self): # Enforce unnormalized coefficients and compare ratio phi, theta = ( - random.rand(1, 10) * 2 * pi, - random.rand(1, 10) * pi - pi / 2, + random.rand(1, 10) * 2.0 * pi, + random.rand(1, 10) * pi - pi / 2.0, ) x, y, z = array( [cos(theta) * cos(phi), cos(theta) * sin(phi), sin(theta)] @@ -110,13 +110,13 @@ def test_integral_analytical(self, transformation): ) # First initialize and overwrite afterward to prevent normalization shd = SphericalHarmonicsDistributionComplex( - array([[1, float('NaN'), float('NaN')], [0.0, 0.0, 0]]) + array([[1.0, float('NaN'), float('NaN')], [0.0, 0.0, 0.0]]) ) shd.coeff_mat = unnormalized_coeffs shd.transformation = transformation int_val_num = shd.integrate_numerically() int_val_ana = shd.integrate() - self.assertAlmostEqual(int_val_ana, int_val_num, places=5) + npt.assert_almost_equal(int_val_ana, int_val_num) def test_truncation(self): shd = SphericalHarmonicsDistributionComplex(self.unnormalized_coeffs) @@ -874,19 +874,19 @@ def test_conversion(self, _, coeff_mat): [ [1, float('NaN'), float('NaN')], [ - sqrt(1 / 2) + 1j * sqrt(1 / 2), + sqrt(1.0 / 2.0) + 1j * sqrt(1.0 / 2.0), 0.0, - -sqrt(1 / 2) + 1j * sqrt(1 / 2), + -sqrt(1.0 / 2.0) + 1j * sqrt(1.0 / 2.0), ], ] ), - array([1, 1, 0]) / sqrt(2.0), + array([1.0, 1.0, 0.0]) / sqrt(2.0), SphericalHarmonicsDistributionComplex.mean_direction, ), ( "shd_xz", - array([[1, float('NaN'), float('NaN')], [sqrt(1 / 2), 1, -sqrt(1 / 2)]]), - array([1, 0.0, 1]) / sqrt(2), + array([[1.0, float('NaN'), float('NaN')], [sqrt(1 / 2), 1, -sqrt(1.0 / 2.0)]]), + array([1., 0.0, 1.0]) / sqrt(2.0), SphericalHarmonicsDistributionComplex.mean_direction, ), ( @@ -894,43 +894,41 @@ def test_conversion(self, _, coeff_mat): array( [[1, float('NaN'), float('NaN')], [1j * sqrt(1 / 2), 1, 1j * sqrt(1 / 2)]] ), - array([0.0, 1, 1]) / sqrt(2), + array([0.0, 1.0, 1.0]) / sqrt(2.0), SphericalHarmonicsDistributionComplex.mean_direction, ), ( "numerical_shd_x", - array([[1, float('NaN'), float('NaN')], [sqrt(1 / 2), 0.0, -sqrt(1 / 2)]]), - array([1, 0.0, 0]), + [[1, float('NaN'), float('NaN')], [sqrt(1 / 2), 0.0, -sqrt(1 / 2)]], + [1, 0.0, 0.0], SphericalHarmonicsDistributionComplex.mean_direction_numerical, ), ( "numerical_shd_y", - array( - [[1, float('NaN'), float('NaN')], [1j * sqrt(1 / 2), 0.0, 1j * sqrt(1 / 2)]] - ), - array([0.0, 1, 0]), + [[1.0, float('NaN'), float('NaN')], [1j * sqrt(1 / 2), 0.0, 1j * sqrt(1.0 / 2.0)]], + [0.0, 1.0, 0.0], SphericalHarmonicsDistributionComplex.mean_direction_numerical, ), ( "numerical_shd_z", - array([[1, float('NaN'), float('NaN')], [0.0, 1, 0]]), - array([0.0, 0.0, 1]), + [[1.0, float('NaN'), float('NaN')], [0.0, 1.0, 0]], + [0.0, 0.0, 1.0], SphericalHarmonicsDistributionComplex.mean_direction_numerical, ), ] ) def test_mean_direction(self, _, input_array, expected_output, fun_to_test): - shd = SphericalHarmonicsDistributionComplex(input_array) + shd = SphericalHarmonicsDistributionComplex(array(input_array)) npt.assert_allclose(fun_to_test(shd), expected_output, atol=1e-10) def test_from_distribution_via_integral_vmf(self): # Test approximating a VMF - dist = VonMisesFisherDistribution(array([-1, -1, 0] / sqrt(2)), 1) + dist = VonMisesFisherDistribution(array([-1.0, -1.0, 0.0]) / sqrt(2.0), array(1.0)) shd = SphericalHarmonicsDistributionComplex.from_distribution_via_integral( dist, 3 ) phi, theta = meshgrid( - linspace(0.0, 2 * pi, 10), linspace(-pi / 2, pi / 2, 10) + linspace(0.0, 2.0 * pi, 10), linspace(-pi / 2.0, pi / 2.0, 10) ) x, y, z = AbstractSphericalDistribution.sph_to_cart(phi.ravel(), theta.ravel()) npt.assert_allclose( @@ -1034,19 +1032,19 @@ def test_convergence(self): ( "xyminus", [ - [1 / sqrt(4 * pi), float('NaN'), float('NaN')], + [1.0 / sqrt(4 * pi), float('NaN'), float('NaN')], [ - -1j * sqrt(1 / 2) - sqrt(1 / 2), + -1j * sqrt(1 / 2) - sqrt(1.0 / 2.0), 0.0, - -1j * sqrt(1 / 2) + sqrt(1 / 2), + -1j * sqrt(1 / 2) + sqrt(1.0 / 2.0), ], ], - 1 / sqrt(2) * array([-1, -1, 0]), + 1 / sqrt(2) * array([-1.0, -1.0, 0.0]), ), ] ) def test_mean(self, _, coeff_mat, expected_output): - shd = SphericalHarmonicsDistributionComplex(coeff_mat) + shd = SphericalHarmonicsDistributionComplex(array(coeff_mat)) npt.assert_allclose(shd.mean_direction(), expected_output, atol=1e-6) diff --git a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py index 6be4d9f1..ab59b8d7 100644 --- a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py +++ b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py @@ -24,7 +24,7 @@ class SphericalHarmonicsDistributionRealTest(unittest.TestCase): def testNormalizationError(self): - self.assertRaises(ValueError, SphericalHarmonicsDistributionReal, 0) + self.assertRaises(ValueError, SphericalHarmonicsDistributionReal, array(0.0)) def testNormalizationWarning(self): with warnings.catch_warnings(record=True) as w: diff --git a/pyrecest/tests/filters/test_kalman_filter.py b/pyrecest/tests/filters/test_kalman_filter.py index e023d84a..df0a9cc5 100644 --- a/pyrecest/tests/filters/test_kalman_filter.py +++ b/pyrecest/tests/filters/test_kalman_filter.py @@ -6,7 +6,7 @@ import numpy.testing as npt import copy import unittest - +import pyrecest.backend from pyrecest.distributions import GaussianDistribution from pyrecest.filters.kalman_filter import KalmanFilter @@ -23,17 +23,20 @@ def test_initialization_gauss(self): ) npt.assert_equal(filter_custom.get_point_estimate(), array([4])) + @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") def test_update_with_likelihood_1d(self): kf = KalmanFilter((array([0]), array([[1]]))) kf.update_identity(array(1), array(3)) npt.assert_equal(kf.get_point_estimate(), 1.5) + @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") def test_update_with_meas_noise_and_meas_1d(self): kf = KalmanFilter((array([0]), array([[1]]))) kf.update_identity(array(1), array(4)) npt.assert_equal(kf.filter_state.C, 0.5) npt.assert_equal(kf.get_point_estimate(), 2) + @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") def test_update_linear_2d(self): filter_add = KalmanFilter((array([0, 1]), diag([1, 2]))) filter_id = copy.deepcopy(filter_add) @@ -47,18 +50,20 @@ def test_update_linear_2d(self): allclose(filter_add.filter_state.C, filter_id.filter_state.C) ) + @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") def test_predict_identity_1d(self): kf = KalmanFilter((array([0]), array([[1]]))) kf.predict_identity(array([[3]]), array([1])) npt.assert_equal(kf.get_point_estimate(), array(1)) npt.assert_equal(kf.filter_state.C, array(4)) + @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") def test_predict_linear_2d(self): - kf = KalmanFilter((array([0, 1]), diag([1, 2]))) - kf.predict_linear(diag([1, 2]), diag([2, 1])) + kf = KalmanFilter((array([0, 1]), diag(array([1, 2])))) + kf.predict_linear(diag(array([1, 2])), diag(array([2, 1]))) self.assertTrue(allclose(kf.get_point_estimate(), array([0, 2]))) - self.assertTrue(allclose(kf.filter_state.C, diag([3, 9]))) - kf.predict_linear(diag([1, 2]), diag([2, 1]), array([2, -2])) + self.assertTrue(allclose(kf.filter_state.C, diag(array([3, 9])))) + kf.predict_linear(diag(array([1, 2])), diag(array([2, 1])), array([2, -2])) self.assertTrue(allclose(kf.get_point_estimate(), array([2, 2]))) diff --git a/pyrecest/tests/filters/test_random_matrix_tracker.py b/pyrecest/tests/filters/test_random_matrix_tracker.py index ef42cca8..5e35a3b1 100644 --- a/pyrecest/tests/filters/test_random_matrix_tracker.py +++ b/pyrecest/tests/filters/test_random_matrix_tracker.py @@ -7,6 +7,7 @@ from pyrecest.backend import zeros import unittest from unittest.mock import patch +import pyrecest.backend import numpy.testing as npt import matplotlib.pyplot as plt @@ -76,6 +77,7 @@ def test_predict(self): self.tracker.extent, expected_extent, decimal=5 ) + @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") @parameterized.expand( [ ( From 0612b12143f4c8a8162758962a6a78a401d36d80 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Sun, 22 Oct 2023 17:58:54 +0100 Subject: [PATCH 103/232] More --- pyrecest/_backend/__init__.py | 1 + pyrecest/_backend/numpy/__init__.py | 1 + pyrecest/_backend/pytorch/__init__.py | 1 + .../circle/wrapped_laplace_distribution.py | 6 +++--- pyrecest/evaluation/determine_all_deviations.py | 11 ++++++----- 5 files changed, 12 insertions(+), 8 deletions(-) diff --git a/pyrecest/_backend/__init__.py b/pyrecest/_backend/__init__.py index db1b6e80..d567289d 100644 --- a/pyrecest/_backend/__init__.py +++ b/pyrecest/_backend/__init__.py @@ -185,6 +185,7 @@ def get_backend_name(): "cov", "count_nonzero", "full_like", + "isinf", ], "autodiff": [ "custom_gradient", diff --git a/pyrecest/_backend/numpy/__init__.py b/pyrecest/_backend/numpy/__init__.py index 2104bcaf..ccc5aed1 100644 --- a/pyrecest/_backend/numpy/__init__.py +++ b/pyrecest/_backend/numpy/__init__.py @@ -90,6 +90,7 @@ cov, count_nonzero, full_like, + isinf, ) from scipy.special import erf, gamma, polygamma # NOQA diff --git a/pyrecest/_backend/pytorch/__init__.py b/pyrecest/_backend/pytorch/__init__.py index 24a91f5f..6ece785c 100644 --- a/pyrecest/_backend/pytorch/__init__.py +++ b/pyrecest/_backend/pytorch/__init__.py @@ -50,6 +50,7 @@ arctan, count_nonzero, full_like, + isinf, ) from torch import repeat_interleave as repeat from torch import ( diff --git a/pyrecest/distributions/circle/wrapped_laplace_distribution.py b/pyrecest/distributions/circle/wrapped_laplace_distribution.py index 50614f5b..c3edacc6 100644 --- a/pyrecest/distributions/circle/wrapped_laplace_distribution.py +++ b/pyrecest/distributions/circle/wrapped_laplace_distribution.py @@ -26,16 +26,16 @@ def trigonometric_moment(self, n): def pdf(self, xs): assert ndim(xs) <= 1 - xs = mod(xs, 2 * pi) + xs = mod(xs, 2.0 * pi) p = ( self.lambda_ * self.kappa / (1 + self.kappa**2) * ( exp(-self.lambda_ * self.kappa * xs) - / (1 - exp(-2 * pi * self.lambda_ * self.kappa)) + / (1 - exp(-2.0 * pi * self.lambda_ * self.kappa)) + exp(self.lambda_ / self.kappa * xs) - / (exp(2 * pi * self.lambda_ / self.kappa) - 1) + / (exp(2.0 * pi * self.lambda_ / self.kappa) - 1.0) ) ) return p \ No newline at end of file diff --git a/pyrecest/evaluation/determine_all_deviations.py b/pyrecest/evaluation/determine_all_deviations.py index c95cff22..84f59c34 100644 --- a/pyrecest/evaluation/determine_all_deviations.py +++ b/pyrecest/evaluation/determine_all_deviations.py @@ -4,7 +4,8 @@ from pyrecest.backend import empty import warnings from typing import Callable - +import numpy as np +from pyrecest.backend import isinf from beartype import beartype @@ -21,7 +22,7 @@ def determine_all_deviations( assert ( ndim(groundtruths) == 2 - and isinstance(groundtruths[0, 0], ) + and isinstance(groundtruths[0, 0], np.ndarray) and ndim(groundtruths[0, 0]) in ( 1, @@ -33,7 +34,7 @@ def determine_all_deviations( for config_no, result_curr_config in enumerate(results): for run in range(len(groundtruths)): - if isinstance(result_curr_config[run], ): + if isinstance(result_curr_config[run], np.ndarray): # If estimates are already given as numpy array, use it final_estimate = result_curr_config[run] elif callable(extract_mean): @@ -50,10 +51,10 @@ def determine_all_deviations( warnings.warn("No estimate for this filter, setting error to inf.") all_deviations_last_mat[config_no][run] = float('inf') - if any(np.isinf(all_deviations_last_mat[config_no])): + if any(isinf(all_deviations_last_mat[config_no])): print( f"Warning: {result_curr_config['filterName']} with {result_curr_config['filterParams']} " - f"parameters apparently failed {sum(np.isinf(all_deviations_last_mat[config_no]))} " + f"parameters apparently failed {sum(isinf(all_deviations_last_mat[config_no]))} " "times. Check if this is plausible." ) From 552e8a93142f39c0c89f6f42bfafc31355207eb4 Mon Sep 17 00:00:00 2001 From: github-actions Date: Sun, 22 Oct 2023 17:00:21 +0000 Subject: [PATCH 104/232] Update requirements.txt --- poetry.lock | 182 +++++++++++++++++++++---------------------- requirements-dev.txt | 2 +- requirements.txt | 2 +- 3 files changed, 93 insertions(+), 93 deletions(-) diff --git a/poetry.lock b/poetry.lock index 67fb8c9d..a78fa8eb 100644 --- a/poetry.lock +++ b/poetry.lock @@ -97,101 +97,101 @@ files = [ [[package]] name = "charset-normalizer" -version = "3.3.0" +version = "3.3.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false python-versions = ">=3.7.0" files = [ - {file = "charset-normalizer-3.3.0.tar.gz", hash = "sha256:63563193aec44bce707e0c5ca64ff69fa72ed7cf34ce6e11d5127555756fd2f6"}, - {file = "charset_normalizer-3.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:effe5406c9bd748a871dbcaf3ac69167c38d72db8c9baf3ff954c344f31c4cbe"}, - {file = "charset_normalizer-3.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4162918ef3098851fcd8a628bf9b6a98d10c380725df9e04caf5ca6dd48c847a"}, - {file = "charset_normalizer-3.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0570d21da019941634a531444364f2482e8db0b3425fcd5ac0c36565a64142c8"}, - {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5707a746c6083a3a74b46b3a631d78d129edab06195a92a8ece755aac25a3f3d"}, - {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:278c296c6f96fa686d74eb449ea1697f3c03dc28b75f873b65b5201806346a69"}, - {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a4b71f4d1765639372a3b32d2638197f5cd5221b19531f9245fcc9ee62d38f56"}, - {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5969baeaea61c97efa706b9b107dcba02784b1601c74ac84f2a532ea079403e"}, - {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3f93dab657839dfa61025056606600a11d0b696d79386f974e459a3fbc568ec"}, - {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:db756e48f9c5c607b5e33dd36b1d5872d0422e960145b08ab0ec7fd420e9d649"}, - {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:232ac332403e37e4a03d209a3f92ed9071f7d3dbda70e2a5e9cff1c4ba9f0678"}, - {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e5c1502d4ace69a179305abb3f0bb6141cbe4714bc9b31d427329a95acfc8bdd"}, - {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:2502dd2a736c879c0f0d3e2161e74d9907231e25d35794584b1ca5284e43f596"}, - {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23e8565ab7ff33218530bc817922fae827420f143479b753104ab801145b1d5b"}, - {file = "charset_normalizer-3.3.0-cp310-cp310-win32.whl", hash = "sha256:1872d01ac8c618a8da634e232f24793883d6e456a66593135aeafe3784b0848d"}, - {file = "charset_normalizer-3.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:557b21a44ceac6c6b9773bc65aa1b4cc3e248a5ad2f5b914b91579a32e22204d"}, - {file = "charset_normalizer-3.3.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d7eff0f27edc5afa9e405f7165f85a6d782d308f3b6b9d96016c010597958e63"}, - {file = "charset_normalizer-3.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6a685067d05e46641d5d1623d7c7fdf15a357546cbb2f71b0ebde91b175ffc3e"}, - {file = "charset_normalizer-3.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0d3d5b7db9ed8a2b11a774db2bbea7ba1884430a205dbd54a32d61d7c2a190fa"}, - {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2935ffc78db9645cb2086c2f8f4cfd23d9b73cc0dc80334bc30aac6f03f68f8c"}, - {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fe359b2e3a7729010060fbca442ca225280c16e923b37db0e955ac2a2b72a05"}, - {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:380c4bde80bce25c6e4f77b19386f5ec9db230df9f2f2ac1e5ad7af2caa70459"}, - {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f0d1e3732768fecb052d90d62b220af62ead5748ac51ef61e7b32c266cac9293"}, - {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1b2919306936ac6efb3aed1fbf81039f7087ddadb3160882a57ee2ff74fd2382"}, - {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f8888e31e3a85943743f8fc15e71536bda1c81d5aa36d014a3c0c44481d7db6e"}, - {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:82eb849f085624f6a607538ee7b83a6d8126df6d2f7d3b319cb837b289123078"}, - {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7b8b8bf1189b3ba9b8de5c8db4d541b406611a71a955bbbd7385bbc45fcb786c"}, - {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:5adf257bd58c1b8632046bbe43ee38c04e1038e9d37de9c57a94d6bd6ce5da34"}, - {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c350354efb159b8767a6244c166f66e67506e06c8924ed74669b2c70bc8735b1"}, - {file = "charset_normalizer-3.3.0-cp311-cp311-win32.whl", hash = "sha256:02af06682e3590ab952599fbadac535ede5d60d78848e555aa58d0c0abbde786"}, - {file = "charset_normalizer-3.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:86d1f65ac145e2c9ed71d8ffb1905e9bba3a91ae29ba55b4c46ae6fc31d7c0d4"}, - {file = "charset_normalizer-3.3.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:3b447982ad46348c02cb90d230b75ac34e9886273df3a93eec0539308a6296d7"}, - {file = "charset_normalizer-3.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:abf0d9f45ea5fb95051c8bfe43cb40cda383772f7e5023a83cc481ca2604d74e"}, - {file = "charset_normalizer-3.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b09719a17a2301178fac4470d54b1680b18a5048b481cb8890e1ef820cb80455"}, - {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b3d9b48ee6e3967b7901c052b670c7dda6deb812c309439adaffdec55c6d7b78"}, - {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:edfe077ab09442d4ef3c52cb1f9dab89bff02f4524afc0acf2d46be17dc479f5"}, - {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3debd1150027933210c2fc321527c2299118aa929c2f5a0a80ab6953e3bd1908"}, - {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86f63face3a527284f7bb8a9d4f78988e3c06823f7bea2bd6f0e0e9298ca0403"}, - {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:24817cb02cbef7cd499f7c9a2735286b4782bd47a5b3516a0e84c50eab44b98e"}, - {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c71f16da1ed8949774ef79f4a0260d28b83b3a50c6576f8f4f0288d109777989"}, - {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:9cf3126b85822c4e53aa28c7ec9869b924d6fcfb76e77a45c44b83d91afd74f9"}, - {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:b3b2316b25644b23b54a6f6401074cebcecd1244c0b8e80111c9a3f1c8e83d65"}, - {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:03680bb39035fbcffe828eae9c3f8afc0428c91d38e7d61aa992ef7a59fb120e"}, - {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4cc152c5dd831641e995764f9f0b6589519f6f5123258ccaca8c6d34572fefa8"}, - {file = "charset_normalizer-3.3.0-cp312-cp312-win32.whl", hash = "sha256:b8f3307af845803fb0b060ab76cf6dd3a13adc15b6b451f54281d25911eb92df"}, - {file = "charset_normalizer-3.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:8eaf82f0eccd1505cf39a45a6bd0a8cf1c70dcfc30dba338207a969d91b965c0"}, - {file = "charset_normalizer-3.3.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dc45229747b67ffc441b3de2f3ae5e62877a282ea828a5bdb67883c4ee4a8810"}, - {file = "charset_normalizer-3.3.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f4a0033ce9a76e391542c182f0d48d084855b5fcba5010f707c8e8c34663d77"}, - {file = "charset_normalizer-3.3.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ada214c6fa40f8d800e575de6b91a40d0548139e5dc457d2ebb61470abf50186"}, - {file = "charset_normalizer-3.3.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b1121de0e9d6e6ca08289583d7491e7fcb18a439305b34a30b20d8215922d43c"}, - {file = "charset_normalizer-3.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1063da2c85b95f2d1a430f1c33b55c9c17ffaf5e612e10aeaad641c55a9e2b9d"}, - {file = "charset_normalizer-3.3.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:70f1d09c0d7748b73290b29219e854b3207aea922f839437870d8cc2168e31cc"}, - {file = "charset_normalizer-3.3.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:250c9eb0f4600361dd80d46112213dff2286231d92d3e52af1e5a6083d10cad9"}, - {file = "charset_normalizer-3.3.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:750b446b2ffce1739e8578576092179160f6d26bd5e23eb1789c4d64d5af7dc7"}, - {file = "charset_normalizer-3.3.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:fc52b79d83a3fe3a360902d3f5d79073a993597d48114c29485e9431092905d8"}, - {file = "charset_normalizer-3.3.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:588245972aca710b5b68802c8cad9edaa98589b1b42ad2b53accd6910dad3545"}, - {file = "charset_normalizer-3.3.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e39c7eb31e3f5b1f88caff88bcff1b7f8334975b46f6ac6e9fc725d829bc35d4"}, - {file = "charset_normalizer-3.3.0-cp37-cp37m-win32.whl", hash = "sha256:abecce40dfebbfa6abf8e324e1860092eeca6f7375c8c4e655a8afb61af58f2c"}, - {file = "charset_normalizer-3.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:24a91a981f185721542a0b7c92e9054b7ab4fea0508a795846bc5b0abf8118d4"}, - {file = "charset_normalizer-3.3.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:67b8cc9574bb518ec76dc8e705d4c39ae78bb96237cb533edac149352c1f39fe"}, - {file = "charset_normalizer-3.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ac71b2977fb90c35d41c9453116e283fac47bb9096ad917b8819ca8b943abecd"}, - {file = "charset_normalizer-3.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3ae38d325b512f63f8da31f826e6cb6c367336f95e418137286ba362925c877e"}, - {file = "charset_normalizer-3.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:542da1178c1c6af8873e143910e2269add130a299c9106eef2594e15dae5e482"}, - {file = "charset_normalizer-3.3.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:30a85aed0b864ac88309b7d94be09f6046c834ef60762a8833b660139cfbad13"}, - {file = "charset_normalizer-3.3.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aae32c93e0f64469f74ccc730a7cb21c7610af3a775157e50bbd38f816536b38"}, - {file = "charset_normalizer-3.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15b26ddf78d57f1d143bdf32e820fd8935d36abe8a25eb9ec0b5a71c82eb3895"}, - {file = "charset_normalizer-3.3.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7f5d10bae5d78e4551b7be7a9b29643a95aded9d0f602aa2ba584f0388e7a557"}, - {file = "charset_normalizer-3.3.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:249c6470a2b60935bafd1d1d13cd613f8cd8388d53461c67397ee6a0f5dce741"}, - {file = "charset_normalizer-3.3.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:c5a74c359b2d47d26cdbbc7845e9662d6b08a1e915eb015d044729e92e7050b7"}, - {file = "charset_normalizer-3.3.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:b5bcf60a228acae568e9911f410f9d9e0d43197d030ae5799e20dca8df588287"}, - {file = "charset_normalizer-3.3.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:187d18082694a29005ba2944c882344b6748d5be69e3a89bf3cc9d878e548d5a"}, - {file = "charset_normalizer-3.3.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:81bf654678e575403736b85ba3a7867e31c2c30a69bc57fe88e3ace52fb17b89"}, - {file = "charset_normalizer-3.3.0-cp38-cp38-win32.whl", hash = "sha256:85a32721ddde63c9df9ebb0d2045b9691d9750cb139c161c80e500d210f5e26e"}, - {file = "charset_normalizer-3.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:468d2a840567b13a590e67dd276c570f8de00ed767ecc611994c301d0f8c014f"}, - {file = "charset_normalizer-3.3.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e0fc42822278451bc13a2e8626cf2218ba570f27856b536e00cfa53099724828"}, - {file = "charset_normalizer-3.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:09c77f964f351a7369cc343911e0df63e762e42bac24cd7d18525961c81754f4"}, - {file = "charset_normalizer-3.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:12ebea541c44fdc88ccb794a13fe861cc5e35d64ed689513a5c03d05b53b7c82"}, - {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:805dfea4ca10411a5296bcc75638017215a93ffb584c9e344731eef0dcfb026a"}, - {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:96c2b49eb6a72c0e4991d62406e365d87067ca14c1a729a870d22354e6f68115"}, - {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aaf7b34c5bc56b38c931a54f7952f1ff0ae77a2e82496583b247f7c969eb1479"}, - {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:619d1c96099be5823db34fe89e2582b336b5b074a7f47f819d6b3a57ff7bdb86"}, - {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a0ac5e7015a5920cfce654c06618ec40c33e12801711da6b4258af59a8eff00a"}, - {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:93aa7eef6ee71c629b51ef873991d6911b906d7312c6e8e99790c0f33c576f89"}, - {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7966951325782121e67c81299a031f4c115615e68046f79b85856b86ebffc4cd"}, - {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:02673e456dc5ab13659f85196c534dc596d4ef260e4d86e856c3b2773ce09843"}, - {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:c2af80fb58f0f24b3f3adcb9148e6203fa67dd3f61c4af146ecad033024dde43"}, - {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:153e7b6e724761741e0974fc4dcd406d35ba70b92bfe3fedcb497226c93b9da7"}, - {file = "charset_normalizer-3.3.0-cp39-cp39-win32.whl", hash = "sha256:d47ecf253780c90ee181d4d871cd655a789da937454045b17b5798da9393901a"}, - {file = "charset_normalizer-3.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:d97d85fa63f315a8bdaba2af9a6a686e0eceab77b3089af45133252618e70884"}, - {file = "charset_normalizer-3.3.0-py3-none-any.whl", hash = "sha256:e46cd37076971c1040fc8c41273a8b3e2c624ce4f2be3f5dfcb7a430c1d3acc2"}, + {file = "charset-normalizer-3.3.1.tar.gz", hash = "sha256:d9137a876020661972ca6eec0766d81aef8a5627df628b664b234b73396e727e"}, + {file = "charset_normalizer-3.3.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8aee051c89e13565c6bd366813c386939f8e928af93c29fda4af86d25b73d8f8"}, + {file = "charset_normalizer-3.3.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:352a88c3df0d1fa886562384b86f9a9e27563d4704ee0e9d56ec6fcd270ea690"}, + {file = "charset_normalizer-3.3.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:223b4d54561c01048f657fa6ce41461d5ad8ff128b9678cfe8b2ecd951e3f8a2"}, + {file = "charset_normalizer-3.3.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4f861d94c2a450b974b86093c6c027888627b8082f1299dfd5a4bae8e2292821"}, + {file = "charset_normalizer-3.3.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1171ef1fc5ab4693c5d151ae0fdad7f7349920eabbaca6271f95969fa0756c2d"}, + {file = "charset_normalizer-3.3.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28f512b9a33235545fbbdac6a330a510b63be278a50071a336afc1b78781b147"}, + {file = "charset_normalizer-3.3.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0e842112fe3f1a4ffcf64b06dc4c61a88441c2f02f373367f7b4c1aa9be2ad5"}, + {file = "charset_normalizer-3.3.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3f9bc2ce123637a60ebe819f9fccc614da1bcc05798bbbaf2dd4ec91f3e08846"}, + {file = "charset_normalizer-3.3.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:f194cce575e59ffe442c10a360182a986535fd90b57f7debfaa5c845c409ecc3"}, + {file = "charset_normalizer-3.3.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:9a74041ba0bfa9bc9b9bb2cd3238a6ab3b7618e759b41bd15b5f6ad958d17605"}, + {file = "charset_normalizer-3.3.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:b578cbe580e3b41ad17b1c428f382c814b32a6ce90f2d8e39e2e635d49e498d1"}, + {file = "charset_normalizer-3.3.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:6db3cfb9b4fcecb4390db154e75b49578c87a3b9979b40cdf90d7e4b945656e1"}, + {file = "charset_normalizer-3.3.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:debb633f3f7856f95ad957d9b9c781f8e2c6303ef21724ec94bea2ce2fcbd056"}, + {file = "charset_normalizer-3.3.1-cp310-cp310-win32.whl", hash = "sha256:87071618d3d8ec8b186d53cb6e66955ef2a0e4fa63ccd3709c0c90ac5a43520f"}, + {file = "charset_normalizer-3.3.1-cp310-cp310-win_amd64.whl", hash = "sha256:e372d7dfd154009142631de2d316adad3cc1c36c32a38b16a4751ba78da2a397"}, + {file = "charset_normalizer-3.3.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ae4070f741f8d809075ef697877fd350ecf0b7c5837ed68738607ee0a2c572cf"}, + {file = "charset_normalizer-3.3.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:58e875eb7016fd014c0eea46c6fa92b87b62c0cb31b9feae25cbbe62c919f54d"}, + {file = "charset_normalizer-3.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dbd95e300367aa0827496fe75a1766d198d34385a58f97683fe6e07f89ca3e3c"}, + {file = "charset_normalizer-3.3.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:de0b4caa1c8a21394e8ce971997614a17648f94e1cd0640fbd6b4d14cab13a72"}, + {file = "charset_normalizer-3.3.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:985c7965f62f6f32bf432e2681173db41336a9c2611693247069288bcb0c7f8b"}, + {file = "charset_normalizer-3.3.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a15c1fe6d26e83fd2e5972425a772cca158eae58b05d4a25a4e474c221053e2d"}, + {file = "charset_normalizer-3.3.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ae55d592b02c4349525b6ed8f74c692509e5adffa842e582c0f861751701a673"}, + {file = "charset_normalizer-3.3.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:be4d9c2770044a59715eb57c1144dedea7c5d5ae80c68fb9959515037cde2008"}, + {file = "charset_normalizer-3.3.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:851cf693fb3aaef71031237cd68699dded198657ec1e76a76eb8be58c03a5d1f"}, + {file = "charset_normalizer-3.3.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:31bbaba7218904d2eabecf4feec0d07469284e952a27400f23b6628439439fa7"}, + {file = "charset_normalizer-3.3.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:871d045d6ccc181fd863a3cd66ee8e395523ebfbc57f85f91f035f50cee8e3d4"}, + {file = "charset_normalizer-3.3.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:501adc5eb6cd5f40a6f77fbd90e5ab915c8fd6e8c614af2db5561e16c600d6f3"}, + {file = "charset_normalizer-3.3.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f5fb672c396d826ca16a022ac04c9dce74e00a1c344f6ad1a0fdc1ba1f332213"}, + {file = "charset_normalizer-3.3.1-cp311-cp311-win32.whl", hash = "sha256:bb06098d019766ca16fc915ecaa455c1f1cd594204e7f840cd6258237b5079a8"}, + {file = "charset_normalizer-3.3.1-cp311-cp311-win_amd64.whl", hash = "sha256:8af5a8917b8af42295e86b64903156b4f110a30dca5f3b5aedea123fbd638bff"}, + {file = "charset_normalizer-3.3.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:7ae8e5142dcc7a49168f4055255dbcced01dc1714a90a21f87448dc8d90617d1"}, + {file = "charset_normalizer-3.3.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5b70bab78accbc672f50e878a5b73ca692f45f5b5e25c8066d748c09405e6a55"}, + {file = "charset_normalizer-3.3.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5ceca5876032362ae73b83347be8b5dbd2d1faf3358deb38c9c88776779b2e2f"}, + {file = "charset_normalizer-3.3.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:34d95638ff3613849f473afc33f65c401a89f3b9528d0d213c7037c398a51296"}, + {file = "charset_normalizer-3.3.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9edbe6a5bf8b56a4a84533ba2b2f489d0046e755c29616ef8830f9e7d9cf5728"}, + {file = "charset_normalizer-3.3.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f6a02a3c7950cafaadcd46a226ad9e12fc9744652cc69f9e5534f98b47f3bbcf"}, + {file = "charset_normalizer-3.3.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10b8dd31e10f32410751b3430996f9807fc4d1587ca69772e2aa940a82ab571a"}, + {file = "charset_normalizer-3.3.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edc0202099ea1d82844316604e17d2b175044f9bcb6b398aab781eba957224bd"}, + {file = "charset_normalizer-3.3.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b891a2f68e09c5ef989007fac11476ed33c5c9994449a4e2c3386529d703dc8b"}, + {file = "charset_normalizer-3.3.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:71ef3b9be10070360f289aea4838c784f8b851be3ba58cf796262b57775c2f14"}, + {file = "charset_normalizer-3.3.1-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:55602981b2dbf8184c098bc10287e8c245e351cd4fdcad050bd7199d5a8bf514"}, + {file = "charset_normalizer-3.3.1-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:46fb9970aa5eeca547d7aa0de5d4b124a288b42eaefac677bde805013c95725c"}, + {file = "charset_normalizer-3.3.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:520b7a142d2524f999447b3a0cf95115df81c4f33003c51a6ab637cbda9d0bf4"}, + {file = "charset_normalizer-3.3.1-cp312-cp312-win32.whl", hash = "sha256:8ec8ef42c6cd5856a7613dcd1eaf21e5573b2185263d87d27c8edcae33b62a61"}, + {file = "charset_normalizer-3.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:baec8148d6b8bd5cee1ae138ba658c71f5b03e0d69d5907703e3e1df96db5e41"}, + {file = "charset_normalizer-3.3.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:63a6f59e2d01310f754c270e4a257426fe5a591dc487f1983b3bbe793cf6bac6"}, + {file = "charset_normalizer-3.3.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d6bfc32a68bc0933819cfdfe45f9abc3cae3877e1d90aac7259d57e6e0f85b1"}, + {file = "charset_normalizer-3.3.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4f3100d86dcd03c03f7e9c3fdb23d92e32abbca07e7c13ebd7ddfbcb06f5991f"}, + {file = "charset_normalizer-3.3.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:39b70a6f88eebe239fa775190796d55a33cfb6d36b9ffdd37843f7c4c1b5dc67"}, + {file = "charset_normalizer-3.3.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e12f8ee80aa35e746230a2af83e81bd6b52daa92a8afaef4fea4a2ce9b9f4fa"}, + {file = "charset_normalizer-3.3.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7b6cefa579e1237ce198619b76eaa148b71894fb0d6bcf9024460f9bf30fd228"}, + {file = "charset_normalizer-3.3.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:61f1e3fb621f5420523abb71f5771a204b33c21d31e7d9d86881b2cffe92c47c"}, + {file = "charset_normalizer-3.3.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:4f6e2a839f83a6a76854d12dbebde50e4b1afa63e27761549d006fa53e9aa80e"}, + {file = "charset_normalizer-3.3.1-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:1ec937546cad86d0dce5396748bf392bb7b62a9eeb8c66efac60e947697f0e58"}, + {file = "charset_normalizer-3.3.1-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:82ca51ff0fc5b641a2d4e1cc8c5ff108699b7a56d7f3ad6f6da9dbb6f0145b48"}, + {file = "charset_normalizer-3.3.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:633968254f8d421e70f91c6ebe71ed0ab140220469cf87a9857e21c16687c034"}, + {file = "charset_normalizer-3.3.1-cp37-cp37m-win32.whl", hash = "sha256:c0c72d34e7de5604df0fde3644cc079feee5e55464967d10b24b1de268deceb9"}, + {file = "charset_normalizer-3.3.1-cp37-cp37m-win_amd64.whl", hash = "sha256:63accd11149c0f9a99e3bc095bbdb5a464862d77a7e309ad5938fbc8721235ae"}, + {file = "charset_normalizer-3.3.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5a3580a4fdc4ac05f9e53c57f965e3594b2f99796231380adb2baaab96e22761"}, + {file = "charset_normalizer-3.3.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2465aa50c9299d615d757c1c888bc6fef384b7c4aec81c05a0172b4400f98557"}, + {file = "charset_normalizer-3.3.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cb7cd68814308aade9d0c93c5bd2ade9f9441666f8ba5aa9c2d4b389cb5e2a45"}, + {file = "charset_normalizer-3.3.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:91e43805ccafa0a91831f9cd5443aa34528c0c3f2cc48c4cb3d9a7721053874b"}, + {file = "charset_normalizer-3.3.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:854cc74367180beb327ab9d00f964f6d91da06450b0855cbbb09187bcdb02de5"}, + {file = "charset_normalizer-3.3.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c15070ebf11b8b7fd1bfff7217e9324963c82dbdf6182ff7050519e350e7ad9f"}, + {file = "charset_normalizer-3.3.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c4c99f98fc3a1835af8179dcc9013f93594d0670e2fa80c83aa36346ee763d2"}, + {file = "charset_normalizer-3.3.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3fb765362688821404ad6cf86772fc54993ec11577cd5a92ac44b4c2ba52155b"}, + {file = "charset_normalizer-3.3.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:dced27917823df984fe0c80a5c4ad75cf58df0fbfae890bc08004cd3888922a2"}, + {file = "charset_normalizer-3.3.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a66bcdf19c1a523e41b8e9d53d0cedbfbac2e93c649a2e9502cb26c014d0980c"}, + {file = "charset_normalizer-3.3.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:ecd26be9f112c4f96718290c10f4caea6cc798459a3a76636b817a0ed7874e42"}, + {file = "charset_normalizer-3.3.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:3f70fd716855cd3b855316b226a1ac8bdb3caf4f7ea96edcccc6f484217c9597"}, + {file = "charset_normalizer-3.3.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:17a866d61259c7de1bdadef418a37755050ddb4b922df8b356503234fff7932c"}, + {file = "charset_normalizer-3.3.1-cp38-cp38-win32.whl", hash = "sha256:548eefad783ed787b38cb6f9a574bd8664468cc76d1538215d510a3cd41406cb"}, + {file = "charset_normalizer-3.3.1-cp38-cp38-win_amd64.whl", hash = "sha256:45f053a0ece92c734d874861ffe6e3cc92150e32136dd59ab1fb070575189c97"}, + {file = "charset_normalizer-3.3.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:bc791ec3fd0c4309a753f95bb6c749ef0d8ea3aea91f07ee1cf06b7b02118f2f"}, + {file = "charset_normalizer-3.3.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0c8c61fb505c7dad1d251c284e712d4e0372cef3b067f7ddf82a7fa82e1e9a93"}, + {file = "charset_normalizer-3.3.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2c092be3885a1b7899cd85ce24acedc1034199d6fca1483fa2c3a35c86e43041"}, + {file = "charset_normalizer-3.3.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c2000c54c395d9e5e44c99dc7c20a64dc371f777faf8bae4919ad3e99ce5253e"}, + {file = "charset_normalizer-3.3.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4cb50a0335382aac15c31b61d8531bc9bb657cfd848b1d7158009472189f3d62"}, + {file = "charset_normalizer-3.3.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c30187840d36d0ba2893bc3271a36a517a717f9fd383a98e2697ee890a37c273"}, + {file = "charset_normalizer-3.3.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe81b35c33772e56f4b6cf62cf4aedc1762ef7162a31e6ac7fe5e40d0149eb67"}, + {file = "charset_normalizer-3.3.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d0bf89afcbcf4d1bb2652f6580e5e55a840fdf87384f6063c4a4f0c95e378656"}, + {file = "charset_normalizer-3.3.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:06cf46bdff72f58645434d467bf5228080801298fbba19fe268a01b4534467f5"}, + {file = "charset_normalizer-3.3.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:3c66df3f41abee950d6638adc7eac4730a306b022570f71dd0bd6ba53503ab57"}, + {file = "charset_normalizer-3.3.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:cd805513198304026bd379d1d516afbf6c3c13f4382134a2c526b8b854da1c2e"}, + {file = "charset_normalizer-3.3.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:9505dc359edb6a330efcd2be825fdb73ee3e628d9010597aa1aee5aa63442e97"}, + {file = "charset_normalizer-3.3.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:31445f38053476a0c4e6d12b047b08ced81e2c7c712e5a1ad97bc913256f91b2"}, + {file = "charset_normalizer-3.3.1-cp39-cp39-win32.whl", hash = "sha256:bd28b31730f0e982ace8663d108e01199098432a30a4c410d06fe08fdb9e93f4"}, + {file = "charset_normalizer-3.3.1-cp39-cp39-win_amd64.whl", hash = "sha256:555fe186da0068d3354cdf4bbcbc609b0ecae4d04c921cc13e209eece7720727"}, + {file = "charset_normalizer-3.3.1-py3-none-any.whl", hash = "sha256:800561453acdecedaac137bf09cd719c7a440b6800ec182f077bb8e7025fb708"}, ] [[package]] diff --git a/requirements-dev.txt b/requirements-dev.txt index 1555d530..ef40946b 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -2,7 +2,7 @@ astropy==5.3.4 ; python_version >= "3.10" and python_version < "3.13" autopep8==2.0.4 ; python_version >= "3.10" and python_version < "3.13" beartype==0.16.4 ; python_version >= "3.10" and python_version < "3.13" certifi==2023.7.22 ; python_version >= "3.10" and python_version < "3.13" -charset-normalizer==3.3.0 ; python_version >= "3.10" and python_version < "3.13" +charset-normalizer==3.3.1 ; python_version >= "3.10" and python_version < "3.13" colorama==0.4.6 ; python_version >= "3.10" and python_version < "3.13" and (sys_platform == "win32" or platform_system == "Windows") contourpy==1.1.1 ; python_version >= "3.10" and python_version < "3.13" cycler==0.12.1 ; python_version >= "3.10" and python_version < "3.13" diff --git a/requirements.txt b/requirements.txt index ee5650ae..cd879482 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ astropy==5.3.4 ; python_version >= "3.10" and python_version < "3.13" beartype==0.16.4 ; python_version >= "3.10" and python_version < "3.13" certifi==2023.7.22 ; python_version >= "3.10" and python_version < "3.13" -charset-normalizer==3.3.0 ; python_version >= "3.10" and python_version < "3.13" +charset-normalizer==3.3.1 ; python_version >= "3.10" and python_version < "3.13" colorama==0.4.6 ; python_version >= "3.10" and python_version < "3.13" and platform_system == "Windows" contourpy==1.1.1 ; python_version >= "3.10" and python_version < "3.13" cycler==0.12.1 ; python_version >= "3.10" and python_version < "3.13" From 5f5f905b011e3eee00f95647fa27a2922e85ed05 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Sun, 22 Oct 2023 20:04:46 +0100 Subject: [PATCH 105/232] More --- pyrecest/_backend/__init__.py | 1 + pyrecest/_backend/numpy/__init__.py | 1 + pyrecest/_backend/pytorch/__init__.py | 1 + .../hypertorus/hypertoroidal_dirac_distribution.py | 6 +++--- .../hypertoroidal_wrapped_normal_distribution.py | 2 +- .../nonperiodic/gaussian_distribution.py | 2 +- pyrecest/evaluation/plot_results.py | 14 +++++++------- pyrecest/filters/wrapped_normal_filter.py | 10 ++++++---- pyrecest/sampling/hyperspherical_sampler.py | 3 ++- .../test_abstract_linear_distribution.py | 2 +- .../tests/filters/test_global_nearest_neighbor.py | 1 + .../filters/test_hypertoroidal_particle_filter.py | 2 +- .../tests/filters/test_random_matrix_tracker.py | 6 +++--- 13 files changed, 29 insertions(+), 22 deletions(-) diff --git a/pyrecest/_backend/__init__.py b/pyrecest/_backend/__init__.py index d567289d..47b642c0 100644 --- a/pyrecest/_backend/__init__.py +++ b/pyrecest/_backend/__init__.py @@ -186,6 +186,7 @@ def get_backend_name(): "count_nonzero", "full_like", "isinf", + "deg2rad", ], "autodiff": [ "custom_gradient", diff --git a/pyrecest/_backend/numpy/__init__.py b/pyrecest/_backend/numpy/__init__.py index ccc5aed1..9bf29940 100644 --- a/pyrecest/_backend/numpy/__init__.py +++ b/pyrecest/_backend/numpy/__init__.py @@ -91,6 +91,7 @@ count_nonzero, full_like, isinf, + deg2rad, ) from scipy.special import erf, gamma, polygamma # NOQA diff --git a/pyrecest/_backend/pytorch/__init__.py b/pyrecest/_backend/pytorch/__init__.py index 6ece785c..d2d3c6ce 100644 --- a/pyrecest/_backend/pytorch/__init__.py +++ b/pyrecest/_backend/pytorch/__init__.py @@ -51,6 +51,7 @@ count_nonzero, full_like, isinf, + deg2rad, ) from torch import repeat_interleave as repeat from torch import ( diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py b/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py index a5850906..5fbc92c8 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py @@ -65,9 +65,9 @@ def trigonometric_moment(self, n: Union[int, int32, int64]): exp(1j * n * self.d.T) * tile(self.w, (self.dim, 1)), axis=1 ) - def apply_function(self, f: Callable) -> "HypertoroidalDiracDistribution": - dist = super().apply_function(f) - dist.d = mod(dist.d, 2 * pi) + def apply_function(self, f: Callable, f_supports_multiple: bool = True) -> "HypertoroidalDiracDistribution": + dist = super().apply_function(f, f_supports_multiple) + dist.d = mod(dist.d, 2.0 * pi) return dist def to_toroidal_wd(self): diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py b/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py index 706c7c94..a9d8b805 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py @@ -86,7 +86,7 @@ def sample(self, n: Union[int, int32, int64]): if n <= 0: raise ValueError("n must be a positive integer") - s = random.multivariate_normal(self.mu, self.C, n) + s = random.multivariate_normal(self.mu, self.C, (n,)) s = mod(s, 2.0 * pi) # wrap the samples return s diff --git a/pyrecest/distributions/nonperiodic/gaussian_distribution.py b/pyrecest/distributions/nonperiodic/gaussian_distribution.py index a0536831..7360ed6b 100644 --- a/pyrecest/distributions/nonperiodic/gaussian_distribution.py +++ b/pyrecest/distributions/nonperiodic/gaussian_distribution.py @@ -84,7 +84,7 @@ def marginalize_out(self, dimensions): assert all(dim <= self.dim for dim in dimensions) remaining_dims = [i for i in range(self.dim) if i not in dimensions] new_mu = self.mu[remaining_dims] - new_C = self.C[np.ix_(remaining_dims, remaining_dims)] + new_C = self.C[remaining_dims][:, remaining_dims] # Instead of np.ix_ for interface compatibiliy return GaussianDistribution(new_mu, new_C, check_validity=False) def sample(self, n): diff --git a/pyrecest/evaluation/plot_results.py b/pyrecest/evaluation/plot_results.py index 8ef3301c..a60901dc 100644 --- a/pyrecest/evaluation/plot_results.py +++ b/pyrecest/evaluation/plot_results.py @@ -36,7 +36,7 @@ def plot_results( print("Not all warnings are enabled.") # Expand plot_log to handle all plots (pad it) - if np.size(plot_log) == 1: + if plot_log.shape in ((), (1,)): plot_log = False * ones((2, 3), dtype=bool) else: assert shape(plot_log) == (2, 3) @@ -67,10 +67,10 @@ def plot_results( # Iterate over all possible names and plot the lines for those that were evaluated color, style_marker, style_line = get_plot_style_for_filter(curr_filter_name) - params = np.asarray(results_grouped[curr_filter_name]["parameter"]) - errors_mean = np.asarray(results_grouped[curr_filter_name]["error_mean"]) - errors_std = np.asarray(results_grouped[curr_filter_name]["error_std"]) - times_mean = np.asarray(results_grouped[curr_filter_name]["time_mean"]) + params = array(results_grouped[curr_filter_name]["parameter"]) + errors_mean = array(results_grouped[curr_filter_name]["error_mean"]) + errors_std = array(results_grouped[curr_filter_name]["error_std"]) + times_mean = array(results_grouped[curr_filter_name]["time_mean"]) if curr_filter_name.startswith("ff") or curr_filter_name == "htgf": params = params**state_dim @@ -82,7 +82,7 @@ def plot_results( if ( params[0] is not None and not any(isnan(params)) - and np.size(params) > 1 + and params.shape[0] > 1 ): if plot_stds: plt.plot( @@ -121,7 +121,7 @@ def plot_results( if ( params[0] is not None and not any(isnan(params)) - and np.size(params) > 1 + and params.shape[0] > 1 ): plt.plot( params, diff --git a/pyrecest/filters/wrapped_normal_filter.py b/pyrecest/filters/wrapped_normal_filter.py index 662b6aa8..60d38e5b 100644 --- a/pyrecest/filters/wrapped_normal_filter.py +++ b/pyrecest/filters/wrapped_normal_filter.py @@ -4,6 +4,8 @@ from pyrecest.backend import array from collections.abc import Callable from functools import partial +from pyrecest.backend import amax +from pyrecest.backend import amin from pyrecest.distributions import CircularDiracDistribution, WrappedNormalDistribution @@ -46,16 +48,16 @@ def update_nonlinear_progressive( while lambda_ > 0: wd = self.filter_state.to_dirac5() likelihood_vals = array([likelihood(z, x) for x in wd.d]) - likelihood_vals_min: Any = np.min(likelihood_vals) - likelihood_vals_max: Any = np.max(likelihood_vals) + likelihood_vals_min= amin(likelihood_vals) + likelihood_vals_max = amax(likelihood_vals) if likelihood_vals_max == 0: raise ValueError( "Progressive update failed because likelihood is 0 everywhere" ) - w_min: Any = np.min(wd.w) - w_max: Any = np.max(wd.w) + w_min = amin(wd.w) + w_max = amax(wd.w) if likelihood_vals_min == 0 or w_min == 0: raise ZeroDivisionError("Cannot perform division by zero") diff --git a/pyrecest/sampling/hyperspherical_sampler.py b/pyrecest/sampling/hyperspherical_sampler.py index 450df534..20a5f06c 100644 --- a/pyrecest/sampling/hyperspherical_sampler.py +++ b/pyrecest/sampling/hyperspherical_sampler.py @@ -9,6 +9,7 @@ from pyrecest.backend import arange from pyrecest.backend import empty from pyrecest.backend import column_stack +from pyrecest.backend import deg2rad import itertools from abc import abstractmethod @@ -115,7 +116,7 @@ def get_grid_spherical_coordinates( phi_theta_stacked_deg = array( list(itertools.product(phi_deg_mat, theta_deg_mat)) ) - phi_theta_stacked_rad = np.radians(phi_theta_stacked_deg) + phi_theta_stacked_rad = deg2rad(phi_theta_stacked_deg) phi = phi_theta_stacked_rad[:, 0] theta = phi_theta_stacked_rad[:, 1] diff --git a/pyrecest/tests/distributions/test_abstract_linear_distribution.py b/pyrecest/tests/distributions/test_abstract_linear_distribution.py index 252bbcc0..a6dc685a 100644 --- a/pyrecest/tests/distributions/test_abstract_linear_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_linear_distribution.py @@ -81,7 +81,7 @@ def test_covariance_numerical_gaussian_2D(self): ) def test_plot_state_r2(self): - gd = GaussianDistribution(array([1.0, 2.0]), array([[1, 0.5], [0.5, 1]])) + gd = GaussianDistribution(array([1.0, 2.0]), array([[1.0, 0.5], [0.5, 1.0]])) gd.plot() diff --git a/pyrecest/tests/filters/test_global_nearest_neighbor.py b/pyrecest/tests/filters/test_global_nearest_neighbor.py index 8fa8e2e3..364540e6 100644 --- a/pyrecest/tests/filters/test_global_nearest_neighbor.py +++ b/pyrecest/tests/filters/test_global_nearest_neighbor.py @@ -65,6 +65,7 @@ def test_get_state_returns_correct_shape(self): @parameterized.expand( [("no_inputs", zeros(4)), ("with_inputs", array([1.0, -1.0, 1.0, -1.0]))] ) + @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") def test_predict_linear(self, name, sys_input): import numpy as _np # Can use scipy.linalg.block_diag instead of native backend functions here because the efficiency does not matter diff --git a/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py b/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py index e4b020c0..43e66ffd 100644 --- a/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py +++ b/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py @@ -19,7 +19,7 @@ def setUp(self): self.mu = array([1, 1, 1]) + pi / 2 self.hwnd = HypertoroidalWNDistribution(self.mu, self.covariance_matrix) self.hpf = HypertoroidalParticleFilter(500, 3) - self.forced_mean = array([1, 2, 3]) + self.forced_mean = array([1.0, 2.0, 3.0]) random.seed(self.seed) def test_set_state(self): diff --git a/pyrecest/tests/filters/test_random_matrix_tracker.py b/pyrecest/tests/filters/test_random_matrix_tracker.py index 5e35a3b1..a6204b8e 100644 --- a/pyrecest/tests/filters/test_random_matrix_tracker.py +++ b/pyrecest/tests/filters/test_random_matrix_tracker.py @@ -77,21 +77,21 @@ def test_predict(self): self.tracker.extent, expected_extent, decimal=5 ) - @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") @parameterized.expand( [ ( "smaller", - array([[0.1, 0], [0, 0.1], [-0.1, 0], [0, -0.1]]), + array([[0.1, 0.0], [0.0, 0.1], [-0.1, 0.0], [0.0, -0.1]]), "The extent should now be smaller since the measurements are closely spaced", ), ( "larger", - array([[1, 0], [0, 1], [-1, 0], [0, -1]]), + array([[1.0, 0.0], [0.0, 1.0], [-1.0, 0.0], [0.0, -1.0]]), "The extent should now be larger since the measurements are spaced more widely", ), ] ) + @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") def test_update(self, name, offset, _): ys = array([self.initial_state + offset_row for offset_row in offset]).T Cv = array([[0.1, 0.0], [0.0, 0.1]]) From b2249ac4c61d39fa6618834987466a00daaaa43b Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Sun, 22 Oct 2023 21:34:21 +0100 Subject: [PATCH 106/232] More --- pyrecest/_backend/__init__.py | 4 ++++ pyrecest/_backend/numpy/__init__.py | 1 + pyrecest/_backend/numpy/fft.py | 7 +++++++ pyrecest/_backend/pytorch/__init__.py | 1 + pyrecest/_backend/pytorch/fft.py | 6 ++++++ .../circle/circular_fourier_distribution.py | 6 +++--- .../test_circular_fourier_distribution.py | 12 +++++------- 7 files changed, 27 insertions(+), 10 deletions(-) create mode 100644 pyrecest/_backend/numpy/fft.py create mode 100644 pyrecest/_backend/pytorch/fft.py diff --git a/pyrecest/_backend/__init__.py b/pyrecest/_backend/__init__.py index 47b642c0..7d0a8a20 100644 --- a/pyrecest/_backend/__init__.py +++ b/pyrecest/_backend/__init__.py @@ -231,6 +231,10 @@ def get_backend_name(): "seed", "uniform", ], + "fft": [ # For pyrecest + "rfft", + "irfft", + ], } diff --git a/pyrecest/_backend/numpy/__init__.py b/pyrecest/_backend/numpy/__init__.py index 9bf29940..1947179c 100644 --- a/pyrecest/_backend/numpy/__init__.py +++ b/pyrecest/_backend/numpy/__init__.py @@ -149,6 +149,7 @@ from . import autodiff # NOQA from . import linalg # NOQA from . import random # NOQA +from . import fft # NOQA from ._common import ( _box_binary_scalar, _box_unary_scalar, diff --git a/pyrecest/_backend/numpy/fft.py b/pyrecest/_backend/numpy/fft.py new file mode 100644 index 00000000..543e578b --- /dev/null +++ b/pyrecest/_backend/numpy/fft.py @@ -0,0 +1,7 @@ +import numpy as _np +import scipy as _scipy +# For ffts. Added for pyrecest. +from numpy.fft import ( + rfft, + irfft, +) \ No newline at end of file diff --git a/pyrecest/_backend/pytorch/__init__.py b/pyrecest/_backend/pytorch/__init__.py index d2d3c6ce..08d0e871 100644 --- a/pyrecest/_backend/pytorch/__init__.py +++ b/pyrecest/_backend/pytorch/__init__.py @@ -72,6 +72,7 @@ from . import autodiff # NOQA from . import linalg # NOQA from . import random # NOQA +from . import fft # NOQA from ._common import array, cast, from_numpy from ._dtype import ( _add_default_dtype_by_casting, diff --git a/pyrecest/_backend/pytorch/fft.py b/pyrecest/_backend/pytorch/fft.py new file mode 100644 index 00000000..ffeeb5b4 --- /dev/null +++ b/pyrecest/_backend/pytorch/fft.py @@ -0,0 +1,6 @@ +# For ffts. Added for pyrecest. +import torch as _torch +from torch.fft import ( + rfft, + irfft, +) \ No newline at end of file diff --git a/pyrecest/distributions/circle/circular_fourier_distribution.py b/pyrecest/distributions/circle/circular_fourier_distribution.py index 45fc901d..b60c39c1 100644 --- a/pyrecest/distributions/circle/circular_fourier_distribution.py +++ b/pyrecest/distributions/circle/circular_fourier_distribution.py @@ -20,7 +20,7 @@ import matplotlib.pyplot as plt from beartype import beartype -from numpy.fft import irfft, rfft +from pyrecest.backend import fft from .abstract_circular_distribution import AbstractCircularDistribution from .circular_dirac_distribution import CircularDiracDistribution @@ -215,7 +215,7 @@ def integrate(self, integration_boundaries=None) -> float: return integral def plot_grid(self): - grid_values = irfft(self.get_c(), self.n) + grid_values = fft.irfft(self.get_c(), self.n) xs = linspace(0, 2 * pi, grid_values.shape[0], endpoint=False) vals = grid_values.squeeze() @@ -327,7 +327,7 @@ def from_function_values( transformation: str = "sqrt", store_values_multiplied_by_n: bool = True, ) -> "CircularFourierDistribution": - c = rfft(fvals) + c = fft.rfft(fvals) if not store_values_multiplied_by_n: c = c * (1.0 / fvals.shape[0]) diff --git a/pyrecest/tests/distributions/test_circular_fourier_distribution.py b/pyrecest/tests/distributions/test_circular_fourier_distribution.py index 8eb8579e..8464e92d 100644 --- a/pyrecest/tests/distributions/test_circular_fourier_distribution.py +++ b/pyrecest/tests/distributions/test_circular_fourier_distribution.py @@ -9,6 +9,7 @@ import pyrecest.backend import copy import unittest +import numpy.testing as npt import numpy.testing as npt from parameterized import parameterized @@ -49,7 +50,7 @@ class TestCircularFourierDistribution(unittest.TestCase): ) # pylint: disable=too-many-arguments def test_fourier_conversion( - self, transformation, dist_class, mu, param_range, coeffs, tolerance + self, transformation, dist_class, mu, param_range, coeffs ): """ Test fourier conversion of the given distribution with varying parameter. @@ -65,10 +66,7 @@ def test_fourier_conversion( ceil(coeffs / 2.0), "Length of Fourier Coefficients mismatch.", ) - self.assertTrue( - allclose(fd.pdf(xvals), dist.pdf(xvals)), - "PDF values do not match.", - ) + npt.assert_allclose(fd.pdf(xvals), dist.pdf(xvals), atol=1e-5) @parameterized.expand( [ @@ -143,9 +141,9 @@ def test_integrate(self, mult_by_n, transformation): transformation=transformation, store_values_multiplied_by_n=mult_by_n, ) - npt.assert_array_almost_equal(fd.integrate(), 1) + npt.assert_array_almost_equal(fd.integrate(), 1.0) fd_real = fd.to_real_fd() - npt.assert_array_almost_equal(fd_real.integrate(), 1) + npt.assert_array_almost_equal(fd_real.integrate(), 1.0) fd_unnorm = copy.copy(fd) fd_unnorm.c = fd.c * scale_by if transformation == "identity": From b6ae08546bdf84aa69fbc973163e81339eeb3aad Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Sun, 22 Oct 2023 21:36:59 +0100 Subject: [PATCH 107/232] More... --- pyrecest/filters/global_nearest_neighbor.py | 10 +++++----- pyrecest/tests/filters/test_global_nearest_neighbor.py | 1 + 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/pyrecest/filters/global_nearest_neighbor.py b/pyrecest/filters/global_nearest_neighbor.py index ebc05666..c3c256f9 100644 --- a/pyrecest/filters/global_nearest_neighbor.py +++ b/pyrecest/filters/global_nearest_neighbor.py @@ -64,7 +64,7 @@ def find_association( all_cov_mat_state_equal = all( all_cov_mats_prior == repeat( - all_cov_mats_prior[:, :, 0][:, :, np.newaxis], + all_cov_mats_prior[:, :, 0][:, :, None], all_cov_mats_prior.shape[2], axis=2, ) @@ -72,7 +72,7 @@ def find_association( all_cov_mat_meas_equal = cov_mats_meas.ndim == 2 or all( cov_mats_meas == repeat( - cov_mats_meas[:, :, 0][:, :, np.newaxis], + cov_mats_meas[:, :, 0][:, :, None], cov_mats_meas.shape[2], axis=2, ) @@ -108,7 +108,7 @@ def find_association( ) for i in range(n_targets): dists[i, :] = cdist( - (measurement_matrix @ all_means_prior[:, i]).T[np.newaxis], + (measurement_matrix @ all_means_prior[:, i]).T[None], measurements.T, "mahalanobis", VI=all_mats_mahalanobis[:, :, i], @@ -125,9 +125,9 @@ def find_association( dists[i, j] = squeeze( cdist( (measurement_matrix @ all_means_prior[:, i]).T[ - np.newaxis + None ], - measurements[:, j].T[np.newaxis], + measurements[:, j].T[None], "mahalanobis", VI=curr_cov_mahalanobis, ) diff --git a/pyrecest/tests/filters/test_global_nearest_neighbor.py b/pyrecest/tests/filters/test_global_nearest_neighbor.py index 364540e6..d21b953f 100644 --- a/pyrecest/tests/filters/test_global_nearest_neighbor.py +++ b/pyrecest/tests/filters/test_global_nearest_neighbor.py @@ -93,6 +93,7 @@ def test_predict_linear(self, name, sys_input): tracker.filter_bank[i].filter_state.C, C_matrices[i] ) + @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") def test_predict_linear_different_mats_and_inputs(self): tracker = GlobalNearestNeighbor() tracker.filter_state = self.kfs_init From 38a697b156b24f66635e2d816c5864784dc85c87 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 23 Oct 2023 06:04:27 +0100 Subject: [PATCH 108/232] More.... --- pyrecest/_backend/__init__.py | 1 + pyrecest/_backend/numpy/__init__.py | 1 + pyrecest/_backend/pytorch/__init__.py | 1 + pyrecest/evaluation/evaluate_for_simulation_config.py | 4 ++-- pyrecest/evaluation/iterate_configs_and_runs.py | 2 +- pyrecest/tests/test_evaluation_basic.py | 1 + 6 files changed, 7 insertions(+), 3 deletions(-) diff --git a/pyrecest/_backend/__init__.py b/pyrecest/_backend/__init__.py index 7d0a8a20..a345d014 100644 --- a/pyrecest/_backend/__init__.py +++ b/pyrecest/_backend/__init__.py @@ -30,6 +30,7 @@ def get_backend_name(): "complex64", "complex128", "uint8", + "uint32", # For pyrecest # Functions "abs", "all", diff --git a/pyrecest/_backend/numpy/__init__.py b/pyrecest/_backend/numpy/__init__.py index 1947179c..a660c87f 100644 --- a/pyrecest/_backend/numpy/__init__.py +++ b/pyrecest/_backend/numpy/__init__.py @@ -92,6 +92,7 @@ full_like, isinf, deg2rad, + uint32, ) from scipy.special import erf, gamma, polygamma # NOQA diff --git a/pyrecest/_backend/pytorch/__init__.py b/pyrecest/_backend/pytorch/__init__.py index 08d0e871..d8c1352d 100644 --- a/pyrecest/_backend/pytorch/__init__.py +++ b/pyrecest/_backend/pytorch/__init__.py @@ -52,6 +52,7 @@ full_like, isinf, deg2rad, + uint32, ) from torch import repeat_interleave as repeat from torch import ( diff --git a/pyrecest/evaluation/evaluate_for_simulation_config.py b/pyrecest/evaluation/evaluate_for_simulation_config.py index 6b9972c7..67a6b6dc 100644 --- a/pyrecest/evaluation/evaluate_for_simulation_config.py +++ b/pyrecest/evaluation/evaluate_for_simulation_config.py @@ -1,6 +1,6 @@ import random from typing import Any, Optional - +from pyrecest.backend import uint32 from beartype import beartype @@ -64,7 +64,7 @@ def evaluate_for_simulation_config( def get_all_seeds(n_runs: int, seed_input=None, consecutive_seed: bool = True): if seed_input is None: - seed_input = np.uint32(random.randint(1, 0xFFFFFFFF)) # nosec + seed_input = random.randint(1, 0xFFFFFFFF, dtype=uint32) # nosec if seed_input.shape[0] == n_runs: all_seeds = seed_input diff --git a/pyrecest/evaluation/iterate_configs_and_runs.py b/pyrecest/evaluation/iterate_configs_and_runs.py index 94aa0ad1..450cb68e 100644 --- a/pyrecest/evaluation/iterate_configs_and_runs.py +++ b/pyrecest/evaluation/iterate_configs_and_runs.py @@ -22,7 +22,7 @@ def iterate_configs_and_runs( ) raise NotImplementedError("This is not implemented yet.") - n_configs = sum(np.size(f["parameter"]) for f in filter_configs) + n_configs = sum((f["parameter"]).shape[0] for f in filter_configs) n_runs = groundtruths.shape[0] run_times = empty((n_configs, n_runs)) run_failed = zeros((n_configs, n_runs), dtype=bool) diff --git a/pyrecest/tests/test_evaluation_basic.py b/pyrecest/tests/test_evaluation_basic.py index d6477e8e..7d5c407d 100644 --- a/pyrecest/tests/test_evaluation_basic.py +++ b/pyrecest/tests/test_evaluation_basic.py @@ -11,6 +11,7 @@ from pyrecest.backend import all from pyrecest.backend import empty from pyrecest.backend import zeros +import numpy as np import os import tempfile import unittest From 2bfa38391cdb049f964b072408ec06b691e3eb37 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 23 Oct 2023 06:10:18 +0100 Subject: [PATCH 109/232] More --- pyrecest/sampling/hyperspherical_sampler.py | 5 +++-- pyrecest/sampling/hypertoroidal_sampler.py | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/pyrecest/sampling/hyperspherical_sampler.py b/pyrecest/sampling/hyperspherical_sampler.py index 20a5f06c..1958da44 100644 --- a/pyrecest/sampling/hyperspherical_sampler.py +++ b/pyrecest/sampling/hyperspherical_sampler.py @@ -70,11 +70,12 @@ def sample_stochastic( class AbstractSphericalCoordinatesBasedSampler(AbstractSphericalUniformSampler): @abstractmethod def get_grid_spherical_coordinates( - self, grid_density_parameter: int + self, grid_density_parameter: int, ): raise NotImplementedError() - def get_grid(self, grid_density_parameter: int): + def get_grid(self, grid_density_parameter: int, dim: int = 2): + assert dim == 2, "AbstractSphericalCoordinatesBasedSampler is supposed to be used for the circle (which is one-dimensional) only." phi, theta, grid_specific_description = self.get_grid_spherical_coordinates( grid_density_parameter ) diff --git a/pyrecest/sampling/hypertoroidal_sampler.py b/pyrecest/sampling/hypertoroidal_sampler.py index 4fc17cd6..78cd269b 100644 --- a/pyrecest/sampling/hypertoroidal_sampler.py +++ b/pyrecest/sampling/hypertoroidal_sampler.py @@ -16,7 +16,8 @@ class AbstractCircularSampler(AbstractHypertoroidalSampler): class CircularUniformSampler(AbstractCircularSampler): - def sample_stochastic(self, n_samples: int): + def sample_stochastic(self, n_samples: int, dim: int): + assert dim == 1, "CircularUniformSampler is supposed to be used for the circle (which is one-dimensional) only." return CircularUniformDistribution().sample(n_samples) def get_grid(self, grid_density_parameter: int): From def523451ceb87c2a7acb44c94f0e44511070846 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 23 Oct 2023 06:34:36 +0100 Subject: [PATCH 110/232] More + linter changes --- .github/workflows/tests.yml | 2 +- .jscpd.json | 5 +- .mega-linter.yml | 2 +- pyrecest/distributions/__init__.py | 2 +- .../abstract_bounded_domain_distribution.py | 2 +- ...stract_bounded_nonperiodic_distribution.py | 2 +- .../abstract_custom_distribution.py | 10 +- ...bstract_custom_nonperiodic_distribution.py | 2 +- .../abstract_dirac_distribution.py | 30 +- .../abstract_disk_distribution.py | 5 +- .../abstract_distribution_type.py | 2 +- .../abstract_ellipsoidal_ball_distribution.py | 7 +- ...abstract_manifold_specific_distribution.py | 16 +- pyrecest/distributions/abstract_mixture.py | 25 +- .../abstract_nonperiodic_distribution.py | 2 +- .../abstract_orthogonal_basis_distribution.py | 8 +- .../abstract_periodic_distribution.py | 12 +- .../abstract_se3_distribution.py | 10 +- .../abstract_uniform_distribution.py | 14 +- .../abstract_cart_prod_distribution.py | 2 +- ...stom_lin_bounded_cart_prod_distribution.py | 3 +- .../abstract_hypercylindrical_distribution.py | 94 ++- ...ract_lin_bounded_cart_prod_distribution.py | 11 +- ...t_lin_hemisphere_cart_prod_distribution.py | 2 +- ..._hyperhemisphere_cart_prod_distribution.py | 2 +- ..._lin_hypersphere_cart_prod_distribution.py | 2 +- ...persphere_subset_cart_prod_distribution.py | 2 +- ...act_lin_periodic_cart_prod_distribution.py | 4 +- .../cart_prod_stacked_distribution.py | 10 +- .../custom_hypercylindrical_distribution.py | 2 +- .../hypercylindrical_dirac_distribution.py | 14 +- ...in_bounded_cart_prod_dirac_distribution.py | 5 +- ...ypersphere_cart_prod_dirac_distribution.py | 7 +- ...n_hypersphere_subset_dirac_distribution.py | 5 +- ...n_periodic_cart_prod_dirac_distribution.py | 2 +- .../partially_wrapped_normal_distribution.py | 54 +- .../circle/abstract_circular_distribution.py | 14 +- .../circle/circular_dirac_distribution.py | 4 +- .../circle/circular_fourier_distribution.py | 62 +- .../distributions/circle/circular_mixture.py | 7 +- .../circle/circular_uniform_distribution.py | 3 +- .../circle/custom_circular_distribution.py | 13 +- .../circle/von_mises_distribution.py | 36 +- .../circle/wrapped_cauchy_distribution.py | 19 +- .../circle/wrapped_laplace_distribution.py | 6 +- .../circle/wrapped_normal_distribution.py | 41 +- .../abstract_conditional_distribution.py | 2 +- .../custom_hyperrectangular_distribution.py | 4 +- .../disk_uniform_distribution.py | 6 +- .../ellipsoidal_ball_uniform_distribution.py | 13 +- .../abstract_hemispherical_distribution.py | 2 +- ...bstract_hyperhemispherical_distribution.py | 50 +- ...t_hypersphere_subset_dirac_distribution.py | 6 +- ...bstract_hypersphere_subset_distribution.py | 51 +- ...hypersphere_subset_uniform_distribution.py | 10 +- .../abstract_hyperspherical_distribution.py | 43 +- .../abstract_sphere_subset_distribution.py | 22 +- .../abstract_spherical_distribution.py | 2 +- ...stract_spherical_harmonics_distribution.py | 27 +- .../bingham_distribution.py | 15 +- .../custom_hemispherical_distribution.py | 3 +- .../custom_hyperhemispherical_distribution.py | 13 +- .../custom_hyperspherical_distribution.py | 2 +- .../hemispherical_uniform_distribution.py | 2 +- .../hyperhemispherical_dirac_distribution.py | 2 +- ...hyperhemispherical_uniform_distribution.py | 6 +- .../hyperhemispherical_watson_distribution.py | 11 +- .../hyperspherical_dirac_distribution.py | 7 +- .../hyperspherical_mixture.py | 9 +- .../hyperspherical_uniform_distribution.py | 12 +- ...pherical_harmonics_distribution_complex.py | 47 +- .../spherical_harmonics_distribution_real.py | 26 +- .../von_mises_fisher_distribution.py | 43 +- .../hypersphere_subset/watson_distribution.py | 38 +- .../abstract_hypertoroidal_distribution.py | 65 +- .../abstract_toroidal_distribution.py | 10 +- .../custom_hypertoroidal_distribution.py | 10 +- .../custom_toroidal_distribution.py | 2 +- .../hypertoroidal_dirac_distribution.py | 48 +- .../hypertorus/hypertoroidal_mixture.py | 13 +- .../hypertoroidal_uniform_distribution.py | 23 +- ...pertoroidal_wrapped_normal_distribution.py | 47 +- .../hypertorus/toroidal_dirac_distribution.py | 16 +- .../hypertorus/toroidal_mixture.py | 4 +- .../toroidal_uniform_distribution.py | 2 +- .../toroidal_von_mises_sine_distribution.py | 14 +- .../toroidal_wrapped_normal_distribution.py | 5 +- .../abstract_hyperrectangular_distribution.py | 7 +- .../abstract_linear_distribution.py | 120 ++-- .../nonperiodic/custom_linear_distribution.py | 10 +- .../nonperiodic/gaussian_distribution.py | 13 +- .../nonperiodic/gaussian_mixture.py | 11 +- .../hyperrectangular_uniform_distribution.py | 2 +- .../nonperiodic/linear_dirac_distribution.py | 7 +- .../nonperiodic/linear_mixture.py | 4 +- .../se3_cart_prod_stacked_distribution.py | 6 +- .../distributions/se3_dirac_distribution.py | 5 +- pyrecest/evaluation/__init__.py | 2 +- pyrecest/evaluation/check_and_fix_config.py | 2 +- pyrecest/evaluation/configure_for_filter.py | 2 +- .../evaluation/determine_all_deviations.py | 13 +- pyrecest/evaluation/eot_shape_database.py | 9 +- pyrecest/evaluation/evaluate_for_file.py | 15 +- .../evaluate_for_simulation_config.py | 4 +- pyrecest/evaluation/evaluate_for_variables.py | 4 +- pyrecest/evaluation/generate_groundtruth.py | 8 +- pyrecest/evaluation/generate_measurements.py | 21 +- .../generate_simulated_scenarios.py | 5 +- pyrecest/evaluation/get_axis_label.py | 2 +- pyrecest/evaluation/get_distance_function.py | 10 +- pyrecest/evaluation/get_extract_mean.py | 2 +- .../evaluation/group_results_by_filter.py | 2 +- .../evaluation/iterate_configs_and_runs.py | 2 +- .../perform_predict_update_cycles.py | 8 +- pyrecest/evaluation/plot_results.py | 28 +- pyrecest/evaluation/simulation_database.py | 18 +- .../evaluation/summarize_filter_results.py | 7 +- pyrecest/filters/__init__.py | 2 +- pyrecest/filters/abstract_circular_filter.py | 2 +- pyrecest/filters/abstract_euclidean_filter.py | 2 +- .../abstract_extended_object_tracker.py | 2 +- pyrecest/filters/abstract_filter.py | 2 +- pyrecest/filters/abstract_filter_type.py | 2 +- .../abstract_hypercylindrical_filter.py | 2 +- .../abstract_hyperhemispherical_filter.py | 2 +- .../abstract_hypersphere_subset_filter.py | 2 +- .../filters/abstract_hyperspherical_filter.py | 2 +- .../filters/abstract_hypertoroidal_filter.py | 4 +- .../filters/abstract_lin_bounded_filter.py | 2 +- .../filters/abstract_lin_periodic_filter.py | 2 +- .../abstract_manifold_specific_filter.py | 2 +- .../filters/abstract_multitarget_tracker.py | 2 +- .../abstract_nearest_neighbor_tracker.py | 8 +- pyrecest/filters/abstract_particle_filter.py | 24 +- pyrecest/filters/abstract_se2_filter.py | 2 +- pyrecest/filters/abstract_toroidal_filter.py | 2 +- .../filters/abstract_tracker_with_logging.py | 14 +- pyrecest/filters/circular_particle_filter.py | 11 +- pyrecest/filters/euclidean_particle_filter.py | 10 +- pyrecest/filters/global_nearest_neighbor.py | 19 +- .../filters/hypertoroidal_particle_filter.py | 44 +- pyrecest/filters/kalman_filter.py | 19 +- .../filters/lin_bounded_particle_filter.py | 2 +- .../filters/lin_periodic_particle_filter.py | 2 +- pyrecest/filters/random_matrix_tracker.py | 9 +- pyrecest/filters/toroidal_particle_filter.py | 6 +- .../filters/toroidal_wrapped_normal_filter.py | 6 +- pyrecest/filters/von_mises_filter.py | 8 +- pyrecest/filters/von_mises_fisher_filter.py | 6 +- pyrecest/filters/wrapped_normal_filter.py | 13 +- pyrecest/sampling/__init__.py | 2 +- pyrecest/sampling/abstract_sampler.py | 4 +- pyrecest/sampling/euclidean_sampler.py | 6 +- pyrecest/sampling/hyperspherical_sampler.py | 5 +- pyrecest/sampling/hypertoroidal_sampler.py | 3 +- .../test_abstract_circular_distribution.py | 24 +- ..._abstract_hypercylindrical_distribution.py | 36 +- ...bstract_hyperhemispherical_distribution.py | 16 +- ...bstract_hypersphere_subset_distribution.py | 9 +- ...st_abstract_hyperspherical_distribution.py | 9 +- ...est_abstract_hypertoroidal_distribution.py | 13 +- .../test_abstract_linear_distribution.py | 38 +- .../distributions/test_abstract_mixture.py | 17 +- .../test_bingham_distribution.py | 8 +- .../test_circular_fourier_distribution.py | 31 +- .../test_circular_uniform_distribution.py | 35 +- .../test_custom_hemispherical_distribution.py | 11 +- ...st_custom_hypercylindrical_distribution.py | 42 +- ...st_custom_hyperrectangular_distribution.py | 18 +- ...test_custom_hyperspherical_distribution.py | 9 +- .../test_custom_linear_distribution.py | 12 +- .../test_disk_uniform_distribution.py | 12 +- ...t_ellipsoidal_ball_uniform_distribution.py | 7 +- .../test_gaussian_distribution.py | 10 +- ...test_hemispherical_uniform_distribution.py | 13 +- ...est_hypercylindrical_dirac_distribution.py | 34 +- ...hyperhemispherical_uniform_distribution.py | 22 +- .../test_hyperspherical_dirac_distribution.py | 31 +- .../test_hyperspherical_mixture.py | 17 +- ...est_hyperspherical_uniform_distribution.py | 14 +- .../test_hypertoroidal_dirac_distribution.py | 32 +- ...pertoroidal_wrapped_normal_distribution.py | 6 +- .../test_linear_dirac_distribution.py | 9 +- .../distributions/test_linear_mixture.py | 10 +- ...t_partially_wrapped_normal_distribution.py | 11 +- .../test_se3_dirac_distribution.py | 14 +- .../test_sphere_subset_distribution.py | 8 +- ...pherical_harmonics_distribution_complex.py | 620 ++++++++++++------ ...t_spherical_harmonics_distribution_real.py | 265 +++++--- .../test_toroidal_uniform_distribution.py | 31 +- ...st_toroidal_von_mises_sine_distribution.py | 25 +- ...st_toroidal_wrapped_normal_distribution.py | 17 +- .../test_von_mises_distribution.py | 9 +- .../test_von_mises_fisher_distribution.py | 29 +- .../distributions/test_watson_distribution.py | 16 +- .../test_wrapped_cauchy_distribution.py | 22 +- .../test_wrapped_laplace_distribution.py | 21 +- .../test_wrapped_normal_distribution.py | 29 +- .../filters/test_circular_particle_filter.py | 15 +- .../filters/test_euclidean_particle_filter.py | 17 +- .../filters/test_global_nearest_neighbor.py | 134 ++-- .../test_hypertoroidal_particle_filter.py | 15 +- pyrecest/tests/filters/test_kalman_filter.py | 41 +- .../filters/test_random_matrix_tracker.py | 28 +- .../filters/test_toroidal_particle_filter.py | 10 +- .../test_toroidal_wrapped_normal_filter.py | 10 +- .../tests/filters/test_von_mises_filter.py | 4 +- .../filters/test_von_mises_fisher_filter.py | 9 +- .../filters/test_wrapped_normal_filter.py | 10 +- pyrecest/tests/test_eot_shape_database.py | 2 +- pyrecest/tests/test_euclidean_sampler.py | 11 +- pyrecest/tests/test_evaluation_basic.py | 8 +- pyrecest/tests/test_hyperspherical_sampler.py | 13 +- pyrecest/tests/test_hypertoroidal_sampler.py | 10 +- pyrecest/tests/test_metrics.py | 12 +- pyrecest/utils/metrics.py | 7 +- pyrecest/utils/plotting.py | 28 +- requirements-dev_no_version.txt | 10 + 218 files changed, 1988 insertions(+), 1991 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 47fd1368..ffb364d9 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -31,7 +31,7 @@ jobs: python -m pip install --upgrade pip python -m pip install poetry poetry env use python - poetry install --extras healpy_support --extras pytorch_support + poetry install --extras healpy_support --extras pytorch_support - name: List files and check Python and package versions run: | diff --git a/.jscpd.json b/.jscpd.json index 227ac63f..fbcefc4d 100644 --- a/.jscpd.json +++ b/.jscpd.json @@ -1,6 +1,3 @@ { - "ignore": [ - "pyrecest/_backend/**" - ] + "ignore": ["pyrecest/_backend/**"] } - \ No newline at end of file diff --git a/.mega-linter.yml b/.mega-linter.yml index b7902081..3752a085 100644 --- a/.mega-linter.yml +++ b/.mega-linter.yml @@ -14,4 +14,4 @@ DISABLE_LINTERS: - MAKEFILE_CHECKMAKE # Not using a Makefile - SPELL_LYCHEE # Takes pretty long -FILTER_REGEX_EXCLUDE: 'pyrecest._backend/*' +FILTER_REGEX_EXCLUDE: "pyrecest._backend/*" diff --git a/pyrecest/distributions/__init__.py b/pyrecest/distributions/__init__.py index 907f1b80..52826c95 100644 --- a/pyrecest/distributions/__init__.py +++ b/pyrecest/distributions/__init__.py @@ -337,4 +337,4 @@ "LinearMixture", "SE3CartProdStackedDistribution", "SE3DiracDistribution", -] \ No newline at end of file +] diff --git a/pyrecest/distributions/abstract_bounded_domain_distribution.py b/pyrecest/distributions/abstract_bounded_domain_distribution.py index 0a5072db..a4a16dc0 100644 --- a/pyrecest/distributions/abstract_bounded_domain_distribution.py +++ b/pyrecest/distributions/abstract_bounded_domain_distribution.py @@ -11,4 +11,4 @@ class AbstractBoundedDomainDistribution(AbstractManifoldSpecificDistribution): serves as the base class for all distributions that are defined over bounded domains. This class does not define any methods or properties and is intended to be subclassed by specific distributions. - """ \ No newline at end of file + """ diff --git a/pyrecest/distributions/abstract_bounded_nonperiodic_distribution.py b/pyrecest/distributions/abstract_bounded_nonperiodic_distribution.py index a02c02a2..e65b7c12 100644 --- a/pyrecest/distributions/abstract_bounded_nonperiodic_distribution.py +++ b/pyrecest/distributions/abstract_bounded_nonperiodic_distribution.py @@ -11,4 +11,4 @@ class AbstractBoundedNonPeriodicDistribution(AbstractBoundedDomainDistribution): """ def mean(self): - raise ValueError("Mean currently not supported.") \ No newline at end of file + raise ValueError("Mean currently not supported.") diff --git a/pyrecest/distributions/abstract_custom_distribution.py b/pyrecest/distributions/abstract_custom_distribution.py index b2cb7ab0..47758f9c 100644 --- a/pyrecest/distributions/abstract_custom_distribution.py +++ b/pyrecest/distributions/abstract_custom_distribution.py @@ -1,10 +1,8 @@ import copy import warnings from abc import abstractmethod -from collections.abc import Callable -import pyrecest.backend -from beartype import beartype +import pyrecest.backend from .abstract_distribution_type import AbstractDistributionType @@ -61,7 +59,9 @@ def normalize(self, verify: bool | None = None) -> "AbstractCustomDistribution": :param verify: Whether to verify if the density is properly normalized, default is None. :returns: A copy of the original distribution, with the PDF normalized. """ - assert pyrecest.backend.__name__ == 'pyrecest.numpy', "Only supported for numpy backend" + assert ( + pyrecest.backend.__name__ == "pyrecest.numpy" + ), "Only supported for numpy backend" cd = copy.deepcopy(self) integral = self.integrate() @@ -70,4 +70,4 @@ def normalize(self, verify: bool | None = None) -> "AbstractCustomDistribution": if verify and abs(cd.integrate()[0] - 1) > 0.001: warnings.warn("Density is not yet properly normalized.", UserWarning) - return cd \ No newline at end of file + return cd diff --git a/pyrecest/distributions/abstract_custom_nonperiodic_distribution.py b/pyrecest/distributions/abstract_custom_nonperiodic_distribution.py index 1f700b56..202e9f63 100644 --- a/pyrecest/distributions/abstract_custom_nonperiodic_distribution.py +++ b/pyrecest/distributions/abstract_custom_nonperiodic_distribution.py @@ -10,4 +10,4 @@ class AbstractCustomNonPeriodicDistribution( Custom non-periodic distributions are distributions that are defined by a given probability density function and are not periodic. - """ \ No newline at end of file + """ diff --git a/pyrecest/distributions/abstract_dirac_distribution.py b/pyrecest/distributions/abstract_dirac_distribution.py index e2545b58..16ba809e 100644 --- a/pyrecest/distributions/abstract_dirac_distribution.py +++ b/pyrecest/distributions/abstract_dirac_distribution.py @@ -1,20 +1,20 @@ -from pyrecest.backend import random -from typing import Union -from pyrecest.backend import sum -from pyrecest.backend import ones -from pyrecest.backend import log -from pyrecest.backend import isclose -from pyrecest.backend import argmax -from pyrecest.backend import all -from pyrecest.backend import int64 -from pyrecest.backend import int32 -from pyrecest.backend import apply_along_axis -from pyrecest.backend import array import copy import warnings from collections.abc import Callable +from typing import Union -from beartype import beartype +from pyrecest.backend import ( + all, + apply_along_axis, + argmax, + int32, + int64, + isclose, + log, + ones, + random, + sum, +) from .abstract_distribution_type import AbstractDistributionType @@ -24,7 +24,7 @@ class AbstractDiracDistribution(AbstractDistributionType): This class represents an abstract base for Dirac distributions. """ - def __init__(self, d, w = None): + def __init__(self, d, w=None): """ Initialize a Dirac distribution with given Dirac locations and weights. @@ -138,4 +138,4 @@ def is_valid_for_conversion(cls, distribution): def from_distribution(cls, distribution, n_particles): assert cls.is_valid_for_conversion(distribution) samples = distribution.sample(n_particles) - return cls(samples) \ No newline at end of file + return cls(samples) diff --git a/pyrecest/distributions/abstract_disk_distribution.py b/pyrecest/distributions/abstract_disk_distribution.py index 3d4f176f..17b98f3a 100644 --- a/pyrecest/distributions/abstract_disk_distribution.py +++ b/pyrecest/distributions/abstract_disk_distribution.py @@ -1,5 +1,4 @@ -from pyrecest.backend import eye -from pyrecest.backend import array +from pyrecest.backend import array, eye from .abstract_ellipsoidal_ball_distribution import AbstractEllipsoidalBallDistribution @@ -14,4 +13,4 @@ def __init__(self): super().__init__(array([0, 0]), eye(2)) def mean(self): - raise TypeError("Mean not defined for distributions on the disk.") \ No newline at end of file + raise TypeError("Mean not defined for distributions on the disk.") diff --git a/pyrecest/distributions/abstract_distribution_type.py b/pyrecest/distributions/abstract_distribution_type.py index ef422669..eef203a1 100644 --- a/pyrecest/distributions/abstract_distribution_type.py +++ b/pyrecest/distributions/abstract_distribution_type.py @@ -5,4 +5,4 @@ class AbstractDistributionType(ABC): """ This class represents an abstract base for specific types of distributions, regardless of their domain (uniform, mixture, custom, etc.) - """ \ No newline at end of file + """ diff --git a/pyrecest/distributions/abstract_ellipsoidal_ball_distribution.py b/pyrecest/distributions/abstract_ellipsoidal_ball_distribution.py index cad97283..19e5fd55 100644 --- a/pyrecest/distributions/abstract_ellipsoidal_ball_distribution.py +++ b/pyrecest/distributions/abstract_ellipsoidal_ball_distribution.py @@ -1,9 +1,6 @@ -from pyrecest.backend import linalg from math import pi -from pyrecest.backend import sqrt -import numbers -from beartype import beartype +from pyrecest.backend import linalg, sqrt from scipy.special import gamma from .abstract_bounded_nonperiodic_distribution import ( @@ -50,4 +47,4 @@ def get_manifold_size(self): else: c = (pi ** (self.dim / 2)) / gamma((self.dim / 2) + 1) - return c * sqrt(linalg.det(self.shape_matrix)) \ No newline at end of file + return c * sqrt(linalg.det(self.shape_matrix)) diff --git a/pyrecest/distributions/abstract_manifold_specific_distribution.py b/pyrecest/distributions/abstract_manifold_specific_distribution.py index bf878b63..a137403e 100644 --- a/pyrecest/distributions/abstract_manifold_specific_distribution.py +++ b/pyrecest/distributions/abstract_manifold_specific_distribution.py @@ -1,14 +1,8 @@ -from pyrecest.backend import random -from pyrecest.backend import squeeze -from pyrecest.backend import int64 -from pyrecest.backend import int32 -from pyrecest.backend import empty -from typing import Union -import numbers from abc import ABC, abstractmethod from collections.abc import Callable +from typing import Union -from beartype import beartype +from pyrecest.backend import empty, int32, int64, random, squeeze class AbstractManifoldSpecificDistribution(ABC): @@ -52,7 +46,7 @@ def mean(self): Convenient access to a reasonable "mean" for different manifolds. :return: The mean of the distribution. - :rtype: + :rtype: """ def set_mode(self, _): @@ -73,7 +67,7 @@ def sample_metropolis_hastings( burn_in: Union[int, int32, int64] = 10, skipping: Union[int, int32, int64] = 5, proposal: Callable | None = None, - start_point = None, + start_point=None, ): # jscpd:ignore-end """Metropolis Hastings sampling algorithm.""" @@ -105,4 +99,4 @@ def sample_metropolis_hastings( i += 1 relevant_samples = s[burn_in::skipping, :] - return squeeze(relevant_samples) \ No newline at end of file + return squeeze(relevant_samples) diff --git a/pyrecest/distributions/abstract_mixture.py b/pyrecest/distributions/abstract_mixture.py index 2a07e141..dbf1d88c 100644 --- a/pyrecest/distributions/abstract_mixture.py +++ b/pyrecest/distributions/abstract_mixture.py @@ -1,18 +1,18 @@ -from pyrecest.backend import random -from typing import Union -from pyrecest.backend import sum -from pyrecest.backend import ones -from pyrecest.backend import int64 -from pyrecest.backend import int32 -from pyrecest.backend import empty -from pyrecest.backend import zeros -from pyrecest.backend import count_nonzero import collections import copy import warnings +from typing import Union - -from beartype import beartype +from pyrecest.backend import ( + count_nonzero, + empty, + int32, + int64, + ones, + random, + sum, + zeros, +) from .abstract_distribution_type import AbstractDistributionType from .abstract_manifold_specific_distribution import ( @@ -65,7 +65,6 @@ def input_dim(self) -> int: return self.dists[0].input_dim def sample(self, n: Union[int, int32, int64]): - occurrences = random.multinomial(n, self.w) count = 0 s = empty((n, self.input_dim)) @@ -84,4 +83,4 @@ def pdf(self, xs): for i, dist in enumerate(self.dists): p += self.w[i] * dist.pdf(xs) - return p \ No newline at end of file + return p diff --git a/pyrecest/distributions/abstract_nonperiodic_distribution.py b/pyrecest/distributions/abstract_nonperiodic_distribution.py index 865e1ae1..7eeff3c6 100644 --- a/pyrecest/distributions/abstract_nonperiodic_distribution.py +++ b/pyrecest/distributions/abstract_nonperiodic_distribution.py @@ -6,4 +6,4 @@ class AbstractNonperiodicDistribution(AbstractManifoldSpecificDistribution): """ Abstract base class for all distributions on non-periodic manifolds. - """ \ No newline at end of file + """ diff --git a/pyrecest/distributions/abstract_orthogonal_basis_distribution.py b/pyrecest/distributions/abstract_orthogonal_basis_distribution.py index c92f454e..4c7280fe 100644 --- a/pyrecest/distributions/abstract_orthogonal_basis_distribution.py +++ b/pyrecest/distributions/abstract_orthogonal_basis_distribution.py @@ -1,12 +1,8 @@ -from pyrecest.backend import real -from pyrecest.backend import imag -from pyrecest.backend import exp -from pyrecest.backend import all import copy import warnings from abc import abstractmethod -from beartype import beartype +from pyrecest.backend import all, exp, imag, real from .abstract_distribution_type import AbstractDistributionType @@ -69,4 +65,4 @@ def pdf(self, xs): warnings.warn("Density may not be normalized") return exp(val) - raise ValueError("Transformation not recognized or unsupported") \ No newline at end of file + raise ValueError("Transformation not recognized or unsupported") diff --git a/pyrecest/distributions/abstract_periodic_distribution.py b/pyrecest/distributions/abstract_periodic_distribution.py index 25db756a..c4a1fe8e 100644 --- a/pyrecest/distributions/abstract_periodic_distribution.py +++ b/pyrecest/distributions/abstract_periodic_distribution.py @@ -1,9 +1,7 @@ -from typing import Union -from pyrecest.backend import int64 -from pyrecest.backend import int32 from abc import abstractmethod +from typing import Union -from beartype import beartype +from pyrecest.backend import int32, int64 from .abstract_bounded_domain_distribution import AbstractBoundedDomainDistribution @@ -20,7 +18,7 @@ def mean(self): throughout manifolds. :return: The mean of the distribution. - :rtype: + :rtype: """ return self.mean_direction() @@ -31,6 +29,6 @@ def mean_direction(self): Returns ------- - mean_direction: + mean_direction: The mean direction of the distribution. - """ \ No newline at end of file + """ diff --git a/pyrecest/distributions/abstract_se3_distribution.py b/pyrecest/distributions/abstract_se3_distribution.py index af4fffa3..1802bde6 100644 --- a/pyrecest/distributions/abstract_se3_distribution.py +++ b/pyrecest/distributions/abstract_se3_distribution.py @@ -1,14 +1,10 @@ -from pyrecest.backend import column_stack -from typing import Union -from pyrecest.backend import concatenate -from pyrecest.backend import int64 -from pyrecest.backend import int32 import time from abc import abstractmethod +from typing import Union import matplotlib.pyplot as plt - import quaternion +from pyrecest.backend import column_stack, concatenate, int32, int64 from .cart_prod.abstract_lin_bounded_cart_prod_distribution import ( AbstractLinBoundedCartProdDistribution, @@ -111,4 +107,4 @@ def plot_trajectory(periodicStates, linStates, animate=False, delay=0.05): return h def get_manifold_size(self): - return float('inf') \ No newline at end of file + return float("inf") diff --git a/pyrecest/distributions/abstract_uniform_distribution.py b/pyrecest/distributions/abstract_uniform_distribution.py index 6709ffd2..54ba39c6 100644 --- a/pyrecest/distributions/abstract_uniform_distribution.py +++ b/pyrecest/distributions/abstract_uniform_distribution.py @@ -1,8 +1,6 @@ -from pyrecest.backend import ones from abc import abstractmethod - -from beartype import beartype +from pyrecest.backend import ones from .abstract_distribution_type import AbstractDistributionType @@ -14,10 +12,10 @@ def pdf(self, xs): """Compute the probability density function at each point in xs. :param xs: Points at which to compute the pdf. - :type xs: + :type xs: :return: The pdf evaluated at each point in xs. - :rtype: + :rtype: """ return 1 / self.get_manifold_size() * ones(xs.shape[0]) @@ -27,12 +25,12 @@ def get_manifold_size(self): Compute the probability density function at each point in xs. :param xs: Points at which to compute the pdf. - :type xs: + :type xs: :return: The pdf evaluated at each point in xs. - :rtype: + :rtype: """ def mode(self): """Mode is not defined for a uniform distribution.""" - raise AttributeError("Mode not available for uniform distribution") \ No newline at end of file + raise AttributeError("Mode not available for uniform distribution") diff --git a/pyrecest/distributions/cart_prod/abstract_cart_prod_distribution.py b/pyrecest/distributions/cart_prod/abstract_cart_prod_distribution.py index e6e1b34b..92c35886 100644 --- a/pyrecest/distributions/cart_prod/abstract_cart_prod_distribution.py +++ b/pyrecest/distributions/cart_prod/abstract_cart_prod_distribution.py @@ -7,4 +7,4 @@ class AbstractCartProdDistribution(AbstractManifoldSpecificDistribution): """ For arbitrary Cartesian products, such as ones of linear and bounded or hypertori and hypersphere, etc. - """ \ No newline at end of file + """ diff --git a/pyrecest/distributions/cart_prod/abstract_custom_lin_bounded_cart_prod_distribution.py b/pyrecest/distributions/cart_prod/abstract_custom_lin_bounded_cart_prod_distribution.py index c7d66174..e881967f 100644 --- a/pyrecest/distributions/cart_prod/abstract_custom_lin_bounded_cart_prod_distribution.py +++ b/pyrecest/distributions/cart_prod/abstract_custom_lin_bounded_cart_prod_distribution.py @@ -1,6 +1,5 @@ from typing import Callable -from beartype import beartype from ..abstract_custom_distribution import AbstractCustomDistribution from .abstract_lin_periodic_cart_prod_distribution import ( @@ -36,4 +35,4 @@ def from_distribution(distribution: AbstractLinPeriodicCartProdDistribution): chhd = AbstractCustomLinBoundedCartProdDistribution( distribution.pdf, distribution.bound_dim, distribution.lin_dim ) - return chhd \ No newline at end of file + return chhd diff --git a/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py b/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py index 9496263d..6cc5acba 100644 --- a/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py +++ b/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py @@ -1,29 +1,28 @@ -from pyrecest.backend import full -from pyrecest.backend import column_stack +from abc import abstractmethod from math import pi from typing import Union -from pyrecest.backend import vstack -from pyrecest.backend import tile -from pyrecest.backend import sqrt -from pyrecest.backend import ones -from pyrecest.backend import ndim -from pyrecest.backend import mod -from pyrecest.backend import isnan -from pyrecest.backend import concatenate -from pyrecest.backend import array -from pyrecest.backend import any -from pyrecest.backend import allclose -from pyrecest.backend import all -from pyrecest.backend import int64 -from pyrecest.backend import int32 -from pyrecest.backend import empty -from pyrecest.backend import zeros -from abc import abstractmethod - import scipy.integrate import scipy.optimize -from beartype import beartype +from pyrecest.backend import ( + allclose, + any, + array, + column_stack, + concatenate, + empty, + full, + int32, + int64, + isnan, + mod, + ndim, + ones, + sqrt, + tile, + vstack, + zeros, +) from scipy.integrate import nquad from ..hypertorus.custom_hypertoroidal_distribution import ( @@ -97,7 +96,7 @@ def linear_covariance(self, approximate_mean=None): The linear covariance. """ if approximate_mean is None: - approximate_mean = full((self.lin_dim,), float('NaN')) + approximate_mean = full((self.lin_dim,), float("NaN")) assert approximate_mean.shape[0] == self.lin_dim @@ -121,29 +120,41 @@ def linear_covariance_numerical(self, approximate_mean=None): if self.bound_dim == 1 and self.lin_dim == 1: C, _ = nquad( lambda x, y: (y - approximate_mean) ** 2 * self.pdf([x, y]), - [[0, 2 * pi], [-float('inf'), float('inf')]], + [[0, 2 * pi], [-float("inf"), float("inf")]], ) elif self.bound_dim == 2 and self.lin_dim == 1: C, _ = nquad( lambda x, y, z: (z - approximate_mean) ** 2 * self.pdf([x, y, z]), - [[0, 2 * pi], [0, 2 * pi], [-float('inf'), float('inf')]], + [[0, 2 * pi], [0, 2 * pi], [-float("inf"), float("inf")]], ) elif self.bound_dim == 1 and self.lin_dim == 2: C = empty((2, 2)) C[0, 0], _ = nquad( lambda x, y, z: (y - approximate_mean[0]) ** 2 * self.pdf([x, y, z]), - [[0, 2 * pi], [-float('inf'), float('inf')], [-float('inf'), float('inf')]], + [ + [0, 2 * pi], + [-float("inf"), float("inf")], + [-float("inf"), float("inf")], + ], ) C[0, 1], _ = nquad( lambda x, y, z: (y - approximate_mean[0]) * (z - approximate_mean[1]) * self.pdf([x, y, z]), - [[0, 2 * pi], [-float('inf'), float('inf')], [-float('inf'), float('inf')]], + [ + [0, 2 * pi], + [-float("inf"), float("inf")], + [-float("inf"), float("inf")], + ], ) C[1, 0] = C[0, 1] C[1, 1], _ = nquad( lambda x, y, z: (z - approximate_mean[1]) ** 2 * self.pdf([x, y, z]), - [[0, 2 * pi], [-float('inf'), float('inf')], [-float('inf'), float('inf')]], + [ + [0, 2 * pi], + [-float("inf"), float("inf")], + [-float("inf"), float("inf")], + ], ) else: raise ValueError("Cannot determine linear covariance for this dimension.") @@ -165,7 +176,10 @@ def condition_on_linear(self, input_lin, normalize=True): The distribution after conditioning. """ assert ( - input_lin.ndim == 0 and self.lin_dim == 1 or ndim(input_lin) == 1 and input_lin.shape[0] == self.lin_dim + input_lin.ndim == 0 + and self.lin_dim == 1 + or ndim(input_lin) == 1 + and input_lin.shape[0] == self.lin_dim ), "Input should be of size (lin_dim,)." def f_cond_unnorm(x, input_lin=input_lin): @@ -195,7 +209,9 @@ def condition_on_periodic(self, input_periodic, normalize=True): CustomLinearDistribution instance """ assert ( - input_periodic.ndim == 0 or input_periodic.shape[0] == self.bound_dim and ndim(input_periodic) == 2 + input_periodic.ndim == 0 + or input_periodic.shape[0] == self.bound_dim + and ndim(input_periodic) == 2 ), "Input should be of size (lin_dim,)." input_periodic = mod(input_periodic, 2.0 * pi) @@ -217,22 +233,30 @@ def linear_mean_numerical(self): if self.lin_dim == 1 and self.bound_dim == 1: mu = scipy.integrate.nquad( lambda x, y: (y * self.pdf(array([x, y])))[0], - [[0.0, 2 * pi], [-float('inf'), float('inf')]], + [[0.0, 2 * pi], [-float("inf"), float("inf")]], )[0] elif self.bound_dim == 2 and self.lin_dim == 1: mu = scipy.integrate.nquad( lambda x, y, z: (z * self.pdf([x, y, z]))[0], - [[0.0, 2 * pi], [0.0, 2 * pi], [-float('inf'), float('inf')]], + [[0.0, 2 * pi], [0.0, 2 * pi], [-float("inf"), float("inf")]], )[0] elif self.bound_dim == 1 and self.lin_dim == 2: mu = empty(2) mu[0] = scipy.integrate.nquad( lambda x, y, z: (y * self.pdf([x, y, z]))[0], - [[0.0, 2 * pi], [-float('inf'), float('inf')], [-float('inf'), float('inf')]], + [ + [0.0, 2 * pi], + [-float("inf"), float("inf")], + [-float("inf"), float("inf")], + ], )[0] mu[1] = scipy.integrate.nquad( lambda x, y, z: (z * self.pdf([x, y, z]))[0], - [[0, 2 * pi], [-float('inf'), float('inf')], [-float('inf'), float('inf')]], + [ + [0, 2 * pi], + [-float("inf"), float("inf")], + [-float("inf"), float("inf")], + ], )[0] else: raise ValueError("Cannot determine linear mean for this dimension.") @@ -259,7 +283,7 @@ def mode_numerical(self, starting_point=None): # Define bounds for the optimization bounds = [ - (0.0, 2.0 * pi) if i < self.bound_dim else (-float('inf'), float('inf')) + (0.0, 2.0 * pi) if i < self.bound_dim else (-float("inf"), float("inf")) for i in range(self.bound_dim + self.lin_dim) ] @@ -278,4 +302,4 @@ def mode_numerical(self, starting_point=None): @property def input_dim(self): - return self.dim \ No newline at end of file + return self.dim diff --git a/pyrecest/distributions/cart_prod/abstract_lin_bounded_cart_prod_distribution.py b/pyrecest/distributions/cart_prod/abstract_lin_bounded_cart_prod_distribution.py index 211da7d6..f713f27c 100644 --- a/pyrecest/distributions/cart_prod/abstract_lin_bounded_cart_prod_distribution.py +++ b/pyrecest/distributions/cart_prod/abstract_lin_bounded_cart_prod_distribution.py @@ -1,10 +1,7 @@ -from typing import Union -from pyrecest.backend import int64 -from pyrecest.backend import int32 from abc import abstractmethod +from typing import Union - -from beartype import beartype +from pyrecest.backend import int32, int64 from .abstract_cart_prod_distribution import AbstractCartProdDistribution @@ -42,7 +39,7 @@ def mean(self): throughout manifolds. :return: The mean of the distribution. - :rtype: + :rtype: """ return self.hybrid_mean() @@ -58,4 +55,4 @@ def marginalize_linear(self): @abstractmethod def marginalize_periodic(self): - pass \ No newline at end of file + pass diff --git a/pyrecest/distributions/cart_prod/abstract_lin_hemisphere_cart_prod_distribution.py b/pyrecest/distributions/cart_prod/abstract_lin_hemisphere_cart_prod_distribution.py index a866a73b..42f37471 100644 --- a/pyrecest/distributions/cart_prod/abstract_lin_hemisphere_cart_prod_distribution.py +++ b/pyrecest/distributions/cart_prod/abstract_lin_hemisphere_cart_prod_distribution.py @@ -6,4 +6,4 @@ class AbstractLinHemisphereCartProdDistribution( AbstractLinHyperhemisphereCartProdDistribution ): - pass \ No newline at end of file + pass diff --git a/pyrecest/distributions/cart_prod/abstract_lin_hyperhemisphere_cart_prod_distribution.py b/pyrecest/distributions/cart_prod/abstract_lin_hyperhemisphere_cart_prod_distribution.py index 8a99a3e5..c28bad24 100644 --- a/pyrecest/distributions/cart_prod/abstract_lin_hyperhemisphere_cart_prod_distribution.py +++ b/pyrecest/distributions/cart_prod/abstract_lin_hyperhemisphere_cart_prod_distribution.py @@ -10,4 +10,4 @@ class AbstractLinHyperhemisphereCartProdDistribution( AbstractLinHypersphereSubsetCartProdDistribution, AbstractLinPeriodicCartProdDistribution, ): - pass \ No newline at end of file + pass diff --git a/pyrecest/distributions/cart_prod/abstract_lin_hypersphere_cart_prod_distribution.py b/pyrecest/distributions/cart_prod/abstract_lin_hypersphere_cart_prod_distribution.py index 2439382c..f3368d09 100644 --- a/pyrecest/distributions/cart_prod/abstract_lin_hypersphere_cart_prod_distribution.py +++ b/pyrecest/distributions/cart_prod/abstract_lin_hypersphere_cart_prod_distribution.py @@ -10,4 +10,4 @@ class AbstractLinHypersphereCartProdDistribution( AbstractLinHypersphereSubsetCartProdDistribution, AbstractLinPeriodicCartProdDistribution, ): - pass \ No newline at end of file + pass diff --git a/pyrecest/distributions/cart_prod/abstract_lin_hypersphere_subset_cart_prod_distribution.py b/pyrecest/distributions/cart_prod/abstract_lin_hypersphere_subset_cart_prod_distribution.py index a343314e..938447bc 100644 --- a/pyrecest/distributions/cart_prod/abstract_lin_hypersphere_subset_cart_prod_distribution.py +++ b/pyrecest/distributions/cart_prod/abstract_lin_hypersphere_subset_cart_prod_distribution.py @@ -6,4 +6,4 @@ class AbstractLinHypersphereSubsetCartProdDistribution( AbstractLinBoundedCartProdDistribution ): - pass \ No newline at end of file + pass diff --git a/pyrecest/distributions/cart_prod/abstract_lin_periodic_cart_prod_distribution.py b/pyrecest/distributions/cart_prod/abstract_lin_periodic_cart_prod_distribution.py index ae27c9c4..e7d24f6d 100644 --- a/pyrecest/distributions/cart_prod/abstract_lin_periodic_cart_prod_distribution.py +++ b/pyrecest/distributions/cart_prod/abstract_lin_periodic_cart_prod_distribution.py @@ -1,5 +1,3 @@ - - from .abstract_lin_bounded_cart_prod_distribution import ( AbstractLinBoundedCartProdDistribution, ) @@ -18,4 +16,4 @@ def get_manifold_size(self): assert ( self.lin_dim > 0 ), "This class is not intended to be used for purely periodic domains." - return float('inf') \ No newline at end of file + return float("inf") diff --git a/pyrecest/distributions/cart_prod/cart_prod_stacked_distribution.py b/pyrecest/distributions/cart_prod/cart_prod_stacked_distribution.py index 0365faf3..7dc5f509 100644 --- a/pyrecest/distributions/cart_prod/cart_prod_stacked_distribution.py +++ b/pyrecest/distributions/cart_prod/cart_prod_stacked_distribution.py @@ -1,8 +1,4 @@ -from pyrecest.backend import prod -from pyrecest.backend import hstack -from pyrecest.backend import concatenate -from pyrecest.backend import empty - +from pyrecest.backend import concatenate, empty, hstack, prod from .abstract_cart_prod_distribution import AbstractCartProdDistribution @@ -51,9 +47,9 @@ def mean(self): throughout manifolds. :return: The mean of the distribution. - :rtype: + :rtype: """ return self.hybrid_mean() def mode(self): - return concatenate([dist.mode() for dist in self.dists]) \ No newline at end of file + return concatenate([dist.mode() for dist in self.dists]) diff --git a/pyrecest/distributions/cart_prod/custom_hypercylindrical_distribution.py b/pyrecest/distributions/cart_prod/custom_hypercylindrical_distribution.py index 46ccff7b..8606a58e 100644 --- a/pyrecest/distributions/cart_prod/custom_hypercylindrical_distribution.py +++ b/pyrecest/distributions/cart_prod/custom_hypercylindrical_distribution.py @@ -66,4 +66,4 @@ def marginalize_linear(self): # Needed because abstract method needs to be implemented def marginalize_periodic(self): - return AbstractCustomLinBoundedCartProdDistribution.marginalize_periodic(self) \ No newline at end of file + return AbstractCustomLinBoundedCartProdDistribution.marginalize_periodic(self) diff --git a/pyrecest/distributions/cart_prod/hypercylindrical_dirac_distribution.py b/pyrecest/distributions/cart_prod/hypercylindrical_dirac_distribution.py index d9afafe6..a16ff6fa 100644 --- a/pyrecest/distributions/cart_prod/hypercylindrical_dirac_distribution.py +++ b/pyrecest/distributions/cart_prod/hypercylindrical_dirac_distribution.py @@ -1,12 +1,6 @@ -from pyrecest.backend import full from typing import Union -from pyrecest.backend import tile -from pyrecest.backend import sum -from pyrecest.backend import sin -from pyrecest.backend import cos -from pyrecest.backend import int64 -from pyrecest.backend import int32 +from pyrecest.backend import cos, full, int32, int64, sin, sum, tile from ..hypertorus.hypertoroidal_dirac_distribution import HypertoroidalDiracDistribution from .abstract_hypercylindrical_distribution import AbstractHypercylindricalDistribution @@ -37,13 +31,11 @@ def marginalize_linear(self): def hybrid_moment(self): # Specific for Cartesian products of hypertori and R^lin_dim - S = full((self.bound_dim * 2 + self.lin_dim, self.d.shape[0]), float('NaN')) + S = full((self.bound_dim * 2 + self.lin_dim, self.d.shape[0]), float("NaN")) S[2 * self.bound_dim :, :] = self.d[:, self.bound_dim :].T # noqa: E203 for i in range(self.bound_dim): S[2 * i, :] = cos(self.d[:, i]) # noqa: E203 S[2 * i + 1, :] = sin(self.d[:, i]) # noqa: E203 - return sum( - tile(self.w, (self.lin_dim + 2 * self.bound_dim, 1)) * S, axis=1 - ) \ No newline at end of file + return sum(tile(self.w, (self.lin_dim + 2 * self.bound_dim, 1)) * S, axis=1) diff --git a/pyrecest/distributions/cart_prod/lin_bounded_cart_prod_dirac_distribution.py b/pyrecest/distributions/cart_prod/lin_bounded_cart_prod_dirac_distribution.py index e6988c14..d656215c 100644 --- a/pyrecest/distributions/cart_prod/lin_bounded_cart_prod_dirac_distribution.py +++ b/pyrecest/distributions/cart_prod/lin_bounded_cart_prod_dirac_distribution.py @@ -1,8 +1,7 @@ -from pyrecest.backend import concatenate import warnings from abc import abstractmethod - +from pyrecest.backend import concatenate from ..abstract_dirac_distribution import AbstractDiracDistribution from ..nonperiodic.linear_dirac_distribution import LinearDiracDistribution @@ -49,4 +48,4 @@ def from_distribution(cls, distribution, n_particles): """ assert cls.is_valid_for_conversion(distribution) samples = distribution.sample(n_particles) - return cls(distribution.bound_dim, samples) \ No newline at end of file + return cls(distribution.bound_dim, samples) diff --git a/pyrecest/distributions/cart_prod/lin_hypersphere_cart_prod_dirac_distribution.py b/pyrecest/distributions/cart_prod/lin_hypersphere_cart_prod_dirac_distribution.py index d2e19447..d5077dbe 100644 --- a/pyrecest/distributions/cart_prod/lin_hypersphere_cart_prod_dirac_distribution.py +++ b/pyrecest/distributions/cart_prod/lin_hypersphere_cart_prod_dirac_distribution.py @@ -1,7 +1,4 @@ -from pyrecest.backend import linalg -from pyrecest.backend import abs -from pyrecest.backend import amax - +from pyrecest.backend import abs, amax, linalg from ..abstract_se3_distribution import AbstractSE3Distribution from .lin_bounded_cart_prod_dirac_distribution import ( @@ -21,4 +18,4 @@ def __init__(self, bound_dim, d, w=None): @property def input_dim(self): - return self.dim + 1 \ No newline at end of file + return self.dim + 1 diff --git a/pyrecest/distributions/cart_prod/lin_hypersphere_subset_dirac_distribution.py b/pyrecest/distributions/cart_prod/lin_hypersphere_subset_dirac_distribution.py index 68a5f80f..6f172ba1 100644 --- a/pyrecest/distributions/cart_prod/lin_hypersphere_subset_dirac_distribution.py +++ b/pyrecest/distributions/cart_prod/lin_hypersphere_subset_dirac_distribution.py @@ -1,7 +1,6 @@ from typing import Union -from pyrecest.backend import int64 -from pyrecest.backend import int32 +from pyrecest.backend import int32, int64 from .abstract_lin_hyperhemisphere_cart_prod_distribution import ( AbstractLinHypersphereSubsetCartProdDistribution, @@ -19,4 +18,4 @@ def __init__(self, bound_dim: Union[int, int32, int64], d, w=None): AbstractLinHypersphereSubsetCartProdDistribution.__init__( self, bound_dim, d.shape[-1] - bound_dim - 1 ) - LinBoundedCartProdDiracDistribution.__init__(self, d=d, w=w) \ No newline at end of file + LinBoundedCartProdDiracDistribution.__init__(self, d=d, w=w) diff --git a/pyrecest/distributions/cart_prod/lin_periodic_cart_prod_dirac_distribution.py b/pyrecest/distributions/cart_prod/lin_periodic_cart_prod_dirac_distribution.py index 3f184e53..3f40da74 100644 --- a/pyrecest/distributions/cart_prod/lin_periodic_cart_prod_dirac_distribution.py +++ b/pyrecest/distributions/cart_prod/lin_periodic_cart_prod_dirac_distribution.py @@ -4,4 +4,4 @@ class LinPeriodicCartProdDiracDistribution(LinBoundedCartProdDiracDistribution): - pass \ No newline at end of file + pass diff --git a/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py b/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py index b7ae72db..cad6510b 100644 --- a/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py +++ b/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py @@ -1,29 +1,27 @@ -from pyrecest.backend import atleast_2d -from pyrecest.backend import linalg +import copy from math import pi -from pyrecest.backend import random from typing import Union -from pyrecest.backend import tile -from pyrecest.backend import sum -from pyrecest.backend import sin -from pyrecest.backend import shape -from pyrecest.backend import repeat -from pyrecest.backend import ndim -from pyrecest.backend import mod -from pyrecest.backend import meshgrid -from pyrecest.backend import exp -from pyrecest.backend import cos -from pyrecest.backend import concatenate -from pyrecest.backend import array -from pyrecest.backend import allclose -from pyrecest.backend import all -from pyrecest.backend import int64 -from pyrecest.backend import int32 -from pyrecest.backend import empty -import copy - -from beartype import beartype +from pyrecest.backend import ( + allclose, + array, + atleast_2d, + concatenate, + cos, + empty, + exp, + int32, + int64, + linalg, + meshgrid, + mod, + ndim, + random, + repeat, + sin, + sum, + tile, +) from scipy.stats import multivariate_normal from ..hypertorus.hypertoroidal_wrapped_normal_distribution import ( @@ -34,14 +32,14 @@ class PartiallyWrappedNormalDistribution(AbstractHypercylindricalDistribution): - def __init__( - self, mu, C, bound_dim: Union[int, int32, int64] - ): + def __init__(self, mu, C, bound_dim: Union[int, int32, int64]): assert bound_dim >= 0, "bound_dim must be non-negative" assert ndim(mu) == 1, "mu must be a 1-dimensional array" assert C.shape == (mu.shape[-1], mu.shape[-1]), "C must match size of mu" assert allclose(C, C.T), "C must be symmetric" - assert len(linalg.cholesky(C)) > 0, "C must be positive definite" # Will fail if not positive definite + assert ( + len(linalg.cholesky(C)) > 0 + ), "C must be positive definite" # Will fail if not positive definite assert bound_dim <= mu.shape[0] if bound_dim > 0: # This decreases the need for many wrappings mu[:bound_dim] = mod(mu[:bound_dim], 2 * pi) @@ -152,4 +150,4 @@ def marginalize_linear(self): return HypertoroidalWrappedNormalDistribution( self.mu[: self.bound_dim], self.C[: self.bound_dim, : self.bound_dim], # noqa: E203 - ) \ No newline at end of file + ) diff --git a/pyrecest/distributions/circle/abstract_circular_distribution.py b/pyrecest/distributions/circle/abstract_circular_distribution.py index 47eea95c..8d75b322 100644 --- a/pyrecest/distributions/circle/abstract_circular_distribution.py +++ b/pyrecest/distributions/circle/abstract_circular_distribution.py @@ -1,16 +1,12 @@ from math import pi -from pyrecest.backend import sin -from pyrecest.backend import mod -from pyrecest.backend import linspace -from pyrecest.backend import cos -from pyrecest.backend import array -import numbers import matplotlib.pyplot as plt +from pyrecest.backend import array, cos, linspace, mod, sin -from beartype import beartype +from ..hypertorus.abstract_hypertoroidal_distribution import ( + AbstractHypertoroidalDistribution, +) -from ..hypertorus.abstract_hypertoroidal_distribution import AbstractHypertoroidalDistribution class AbstractCircularDistribution(AbstractHypertoroidalDistribution): def __init__(self): @@ -73,4 +69,4 @@ def to_wn(self): def plot_circle(*args, **kwargs): theta = np.append(linspace(0.0, 2.0 * pi, 320), 0) p = plt.plot(cos(theta), sin(theta), *args, **kwargs) - return p \ No newline at end of file + return p diff --git a/pyrecest/distributions/circle/circular_dirac_distribution.py b/pyrecest/distributions/circle/circular_dirac_distribution.py index 5be161d3..494d85d1 100644 --- a/pyrecest/distributions/circle/circular_dirac_distribution.py +++ b/pyrecest/distributions/circle/circular_dirac_distribution.py @@ -1,6 +1,4 @@ -from beartype import beartype - from ..hypertorus.hypertoroidal_dirac_distribution import HypertoroidalDiracDistribution from .abstract_circular_distribution import AbstractCircularDistribution @@ -26,4 +24,4 @@ def plot_interpolated(self, _): """ Raises an exception since interpolation is not available for WDDistribution. """ - raise NotImplementedError("No interpolation available for WDDistribution.") \ No newline at end of file + raise NotImplementedError("No interpolation available for WDDistribution.") diff --git a/pyrecest/distributions/circle/circular_fourier_distribution.py b/pyrecest/distributions/circle/circular_fourier_distribution.py index b60c39c1..a4d7c20e 100644 --- a/pyrecest/distributions/circle/circular_fourier_distribution.py +++ b/pyrecest/distributions/circle/circular_fourier_distribution.py @@ -1,26 +1,26 @@ +import warnings from math import pi from typing import Union -from pyrecest.backend import sum -from pyrecest.backend import sqrt -from pyrecest.backend import sin -from pyrecest.backend import real -from pyrecest.backend import linspace -from pyrecest.backend import imag -from pyrecest.backend import hstack -from pyrecest.backend import exp -from pyrecest.backend import cos -from pyrecest.backend import concatenate -from pyrecest.backend import arange -from pyrecest.backend import int64 -from pyrecest.backend import int32 -from pyrecest.backend import array -from pyrecest.backend import conj -import warnings import matplotlib.pyplot as plt - -from beartype import beartype -from pyrecest.backend import fft +from pyrecest.backend import ( + arange, + array, + concatenate, + conj, + cos, + exp, + fft, + hstack, + imag, + int32, + int64, + linspace, + real, + sin, + sqrt, + sum, +) from .abstract_circular_distribution import AbstractCircularDistribution from .circular_dirac_distribution import CircularDiracDistribution @@ -35,9 +35,9 @@ class CircularFourierDistribution(AbstractCircularDistribution): def __init__( self, transformation: str = "sqrt", - c = None, - a = None, - b = None, + c=None, + a=None, + b=None, n: int | None = None, multiplied_by_n: bool = True, ): @@ -202,9 +202,7 @@ def integrate(self, integration_boundaries=None) -> float: else: c = self.c from_c0 = (real(c[0])) ** 2 - from_c1_to_end = sum((real(c[1:])) ** 2) + sum( - (imag(c[1:])) ** 2 - ) + from_c1_to_end = sum((real(c[1:])) ** 2) + sum((imag(c[1:])) ** 2) a0_non_rooted = 2.0 * from_c0 + 4.0 * from_c1_to_end integral = a0_non_rooted * pi @@ -281,12 +279,8 @@ def to_real_fd(self): def get_full_c(self): assert self.c is not None - neg_c = conj( - self.c[-1:0:-1] - ) # Create array for negative-frequency components - full_c = concatenate( - [neg_c, self.c] - ) # Concatenate arrays to get full spectrum + neg_c = conj(self.c[-1:0:-1]) # Create array for negative-frequency components + full_c = concatenate([neg_c, self.c]) # Concatenate arrays to get full spectrum return full_c @staticmethod @@ -307,7 +301,9 @@ def from_distribution( warnings.warn("Scaling up for WD (this is not recommended).") fd.c = fd.c * fd.n else: - xs = arange(0.0, 2.0 * pi, 2.0 * pi/n) # Like linspace without endpoint but with compatbiility for pytroch + xs = arange( + 0.0, 2.0 * pi, 2.0 * pi / n + ) # Like linspace without endpoint but with compatbiility for pytroch fvals = distribution.pdf(xs) if transformation == "identity": pass @@ -338,4 +334,4 @@ def from_function_values( multiplied_by_n=store_values_multiplied_by_n, ) - return fd \ No newline at end of file + return fd diff --git a/pyrecest/distributions/circle/circular_mixture.py b/pyrecest/distributions/circle/circular_mixture.py index 4ad82bfe..720f5512 100644 --- a/pyrecest/distributions/circle/circular_mixture.py +++ b/pyrecest/distributions/circle/circular_mixture.py @@ -1,10 +1,7 @@ -from pyrecest.backend import sum -from pyrecest.backend import shape import collections import warnings - -from beartype import beartype +from pyrecest.backend import shape, sum from ..hypertorus.hypertoroidal_mixture import HypertoroidalMixture from .abstract_circular_distribution import AbstractCircularDistribution @@ -46,4 +43,4 @@ def __init__( ) self.dists = dists - self.w = w / sum(w) \ No newline at end of file + self.w = w / sum(w) diff --git a/pyrecest/distributions/circle/circular_uniform_distribution.py b/pyrecest/distributions/circle/circular_uniform_distribution.py index f354f0c8..53b38ad3 100644 --- a/pyrecest/distributions/circle/circular_uniform_distribution.py +++ b/pyrecest/distributions/circle/circular_uniform_distribution.py @@ -1,6 +1,5 @@ from math import pi - from ..hypertorus.hypertoroidal_uniform_distribution import ( HypertoroidalUniformDistribution, ) @@ -45,4 +44,4 @@ def cdf(self, xa, starting_point=0): val = (xa - starting_point) / (2 * pi) val[val < 0] = val[val < 0] + 1 - return val \ No newline at end of file + return val diff --git a/pyrecest/distributions/circle/custom_circular_distribution.py b/pyrecest/distributions/circle/custom_circular_distribution.py index f5ca8b5e..c83e3a6e 100644 --- a/pyrecest/distributions/circle/custom_circular_distribution.py +++ b/pyrecest/distributions/circle/custom_circular_distribution.py @@ -1,10 +1,7 @@ -from math import pi -from pyrecest.backend import mod -from pyrecest.backend import array from collections.abc import Callable +from math import pi - -from beartype import beartype +from pyrecest.backend import array, mod from ..abstract_custom_distribution import AbstractCustomDistribution from .abstract_circular_distribution import AbstractCircularDistribution @@ -40,9 +37,7 @@ def pdf(self, xs): Returns: : The value of the pdf at xs. """ - return AbstractCustomDistribution.pdf( - self, mod(xs + self.shift_by, 2 * pi) - ) + return AbstractCustomDistribution.pdf(self, mod(xs + self.shift_by, 2 * pi)) def integrate(self, integration_boundaries=None) -> float: """ @@ -57,4 +52,4 @@ def integrate(self, integration_boundaries=None) -> float: """ if integration_boundaries is None: integration_boundaries = array([0.0, 2.0 * pi]) - return AbstractCircularDistribution.integrate(self, integration_boundaries) \ No newline at end of file + return AbstractCircularDistribution.integrate(self, integration_boundaries) diff --git a/pyrecest/distributions/circle/von_mises_distribution.py b/pyrecest/distributions/circle/von_mises_distribution.py index 2e12b5fb..9146f9a5 100644 --- a/pyrecest/distributions/circle/von_mises_distribution.py +++ b/pyrecest/distributions/circle/von_mises_distribution.py @@ -1,20 +1,19 @@ from math import pi -from pyrecest.backend import where -from pyrecest.backend import sqrt -from pyrecest.backend import sin -from pyrecest.backend import real -from pyrecest.backend import mod -from pyrecest.backend import log -from pyrecest.backend import imag -from pyrecest.backend import exp -from pyrecest.backend import cos -from pyrecest.backend import arctan2 -from pyrecest.backend import abs -from pyrecest.backend import zeros_like -import numbers - - -from beartype import beartype + +from pyrecest.backend import ( + abs, + arctan2, + cos, + exp, + imag, + log, + mod, + real, + sin, + sqrt, + where, + zeros_like, +) from scipy.optimize import fsolve from scipy.special import iv from scipy.stats import vonmises @@ -49,8 +48,7 @@ def pdf(self, xs): return p @staticmethod - def besselratio( - nu, kappa): + def besselratio(nu, kappa): return iv(nu + 1, kappa) / iv(nu, kappa) def cdf(self, xs, starting_point=0): @@ -139,4 +137,4 @@ def from_moment(m): return vm def __str__(self) -> str: - return f"VonMisesDistribution: mu = {self.mu}, kappa = {self.kappa}" \ No newline at end of file + return f"VonMisesDistribution: mu = {self.mu}, kappa = {self.kappa}" diff --git a/pyrecest/distributions/circle/wrapped_cauchy_distribution.py b/pyrecest/distributions/circle/wrapped_cauchy_distribution.py index b3ea9885..787446d4 100644 --- a/pyrecest/distributions/circle/wrapped_cauchy_distribution.py +++ b/pyrecest/distributions/circle/wrapped_cauchy_distribution.py @@ -1,14 +1,6 @@ from math import pi -from pyrecest.backend import tanh -from pyrecest.backend import tan -from pyrecest.backend import sinh -from pyrecest.backend import sin -from pyrecest.backend import mod -from pyrecest.backend import exp -from pyrecest.backend import cosh -from pyrecest.backend import cos -from pyrecest.backend import arctan +from pyrecest.backend import arctan, cos, cosh, exp, mod, sinh, tan, tanh from .abstract_circular_distribution import AbstractCircularDistribution @@ -23,12 +15,7 @@ def __init__(self, mu, gamma): def pdf(self, xs): assert xs.ndim == 1 xs = mod(xs - self.mu, 2 * pi) - return ( - 1 - / (2 * pi) - * sinh(self.gamma) - / (cosh(self.gamma) - cos(xs - self.mu)) - ) + return 1 / (2 * pi) * sinh(self.gamma) / (cosh(self.gamma) - cos(xs - self.mu)) def cdf(self, xs): def coth(x): @@ -39,4 +26,4 @@ def coth(x): def trigonometric_moment(self, n): m = exp(1j * n * self.mu - abs(n) * self.gamma) - return m \ No newline at end of file + return m diff --git a/pyrecest/distributions/circle/wrapped_laplace_distribution.py b/pyrecest/distributions/circle/wrapped_laplace_distribution.py index c3edacc6..7da024fa 100644 --- a/pyrecest/distributions/circle/wrapped_laplace_distribution.py +++ b/pyrecest/distributions/circle/wrapped_laplace_distribution.py @@ -1,8 +1,6 @@ from math import pi -from pyrecest.backend import ndim -from pyrecest.backend import mod -from pyrecest.backend import exp +from pyrecest.backend import exp, mod, ndim from .abstract_circular_distribution import AbstractCircularDistribution @@ -38,4 +36,4 @@ def pdf(self, xs): / (exp(2.0 * pi * self.lambda_ / self.kappa) - 1.0) ) ) - return p \ No newline at end of file + return p diff --git a/pyrecest/distributions/circle/wrapped_normal_distribution.py b/pyrecest/distributions/circle/wrapped_normal_distribution.py index 899e2bd9..e32972d4 100644 --- a/pyrecest/distributions/circle/wrapped_normal_distribution.py +++ b/pyrecest/distributions/circle/wrapped_normal_distribution.py @@ -1,23 +1,22 @@ from math import pi -from pyrecest.backend import random from typing import Union -from pyrecest.backend import where -from pyrecest.backend import squeeze -from pyrecest.backend import sqrt -from pyrecest.backend import ndim -from pyrecest.backend import mod -from pyrecest.backend import log -from pyrecest.backend import exp -from pyrecest.backend import array -from pyrecest.backend import abs -from pyrecest.backend import int64 -from pyrecest.backend import int32 -from pyrecest.backend import zeros -from pyrecest.backend import angle -import numbers - - -from beartype import beartype + +from pyrecest.backend import ( + abs, + angle, + array, + exp, + int32, + int64, + log, + mod, + ndim, + random, + sqrt, + squeeze, + where, + zeros, +) from scipy.special import erf # pylint: disable=no-name-in-module from ..hypertorus.hypertoroidal_wrapped_normal_distribution import ( @@ -124,9 +123,7 @@ def ncdf(from_, to): val = where(xs < startingPoint, 1 + val, val) return squeeze(val) - def trigonometric_moment( - self, n: Union[int, int32, int64] - ): + def trigonometric_moment(self, n: Union[int, int32, int64]): return exp(1j * n * self.mu - n**2 * self.sigma**2 / 2) def multiply( @@ -162,4 +159,4 @@ def from_moment(m) -> "WrappedNormalDistribution": @staticmethod def sigma_to_kappa(sigma): # Approximate conversion from sigma to kappa for a Von Mises distribution - return 1.0 / sigma**2 \ No newline at end of file + return 1.0 / sigma**2 diff --git a/pyrecest/distributions/conditional/abstract_conditional_distribution.py b/pyrecest/distributions/conditional/abstract_conditional_distribution.py index 2dc392d2..84002112 100644 --- a/pyrecest/distributions/conditional/abstract_conditional_distribution.py +++ b/pyrecest/distributions/conditional/abstract_conditional_distribution.py @@ -2,4 +2,4 @@ class AbstractConditionalDistribution(ABC): - pass \ No newline at end of file + pass diff --git a/pyrecest/distributions/custom_hyperrectangular_distribution.py b/pyrecest/distributions/custom_hyperrectangular_distribution.py index 6855f2d5..ffe0de5c 100644 --- a/pyrecest/distributions/custom_hyperrectangular_distribution.py +++ b/pyrecest/distributions/custom_hyperrectangular_distribution.py @@ -1,8 +1,6 @@ from collections.abc import Callable -from beartype import beartype - from .abstract_custom_nonperiodic_distribution import ( AbstractCustomNonPeriodicDistribution, ) @@ -19,4 +17,4 @@ def __init__(self, f: Callable, bounds): AbstractCustomNonPeriodicDistribution.__init__(self, f) def pdf(self, xs): - return AbstractCustomNonPeriodicDistribution.pdf(self, xs) \ No newline at end of file + return AbstractCustomNonPeriodicDistribution.pdf(self, xs) diff --git a/pyrecest/distributions/disk_uniform_distribution.py b/pyrecest/distributions/disk_uniform_distribution.py index 15c2bf26..edd24e4b 100644 --- a/pyrecest/distributions/disk_uniform_distribution.py +++ b/pyrecest/distributions/disk_uniform_distribution.py @@ -1,6 +1,4 @@ -from pyrecest.backend import eye -from pyrecest.backend import array - +from pyrecest.backend import array, eye from .abstract_disk_distribution import AbstractDiskDistribution from .ellipsoidal_ball_uniform_distribution import EllipsoidalBallUniformDistribution @@ -21,4 +19,4 @@ def __init__(self): The center of the disk is at [0, 0] and the shape matrix of the ellipsoid is an identity covariance matrix. """ AbstractDiskDistribution.__init__(self) - EllipsoidalBallUniformDistribution.__init__(self, array([0, 0]), eye(2)) \ No newline at end of file + EllipsoidalBallUniformDistribution.__init__(self, array([0, 0]), eye(2)) diff --git a/pyrecest/distributions/ellipsoidal_ball_uniform_distribution.py b/pyrecest/distributions/ellipsoidal_ball_uniform_distribution.py index 6ffe05e1..24ba17f6 100644 --- a/pyrecest/distributions/ellipsoidal_ball_uniform_distribution.py +++ b/pyrecest/distributions/ellipsoidal_ball_uniform_distribution.py @@ -1,15 +1,6 @@ -from pyrecest.backend import linalg -from math import pi -from pyrecest.backend import random from typing import Union -from pyrecest.backend import sqrt -from pyrecest.backend import power -from pyrecest.backend import dot -from pyrecest.backend import int64 -from pyrecest.backend import int32 -from pyrecest.backend import zeros -from beartype import beartype +from pyrecest.backend import dot, int32, int64, linalg, random, zeros from .abstract_ellipsoidal_ball_distribution import AbstractEllipsoidalBallDistribution from .abstract_uniform_distribution import AbstractUniformDistribution @@ -90,4 +81,4 @@ def sample(self, n: Union[int, int32, int64]): # For points (d, n), this would be L @ random_points transformed_points = random_points @ L.T + self.center.reshape(1, -1) - return transformed_points \ No newline at end of file + return transformed_points diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hemispherical_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hemispherical_distribution.py index b01badd9..92393dc2 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hemispherical_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hemispherical_distribution.py @@ -18,4 +18,4 @@ def __init__(self): Initializes a new instance of the AbstractHemisphericalDistribution class. """ AbstractSphereSubsetDistribution.__init__(self) - AbstractHyperhemisphericalDistribution.__init__(self, dim=2) \ No newline at end of file + AbstractHyperhemisphericalDistribution.__init__(self, dim=2) diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py index 93ad0389..594285ab 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py @@ -1,22 +1,22 @@ -from pyrecest.backend import linalg -from math import pi -from pyrecest.backend import random -from typing import Union -from pyrecest.backend import vstack -from pyrecest.backend import ones -from pyrecest.backend import meshgrid -from pyrecest.backend import linspace -from pyrecest.backend import concatenate -from pyrecest.backend import int64 -from pyrecest.backend import int32 -from pyrecest.backend import zeros -from pyrecest.backend import array import warnings from collections.abc import Callable +from math import pi +from typing import Union import matplotlib.pyplot as plt - -from beartype import beartype +from pyrecest.backend import ( + array, + concatenate, + int32, + int64, + linalg, + linspace, + meshgrid, + ones, + random, + vstack, + zeros, +) from scipy.optimize import minimize from .abstract_hypersphere_subset_distribution import ( @@ -31,7 +31,7 @@ def mean(self): throughout manifolds. :return: The mean of the distribution. - :rtype: + :rtype: """ return self.mean_axis() @@ -42,7 +42,7 @@ def sample_metropolis_hastings( burn_in: Union[int, int32, int64] = 10, skipping: Union[int, int32, int64] = 5, proposal: Callable | None = None, - start_point = None, + start_point=None, ): # jscpd:ignore-end if proposal is None: @@ -106,14 +106,12 @@ def get_full_integration_boundaries(dim: Union[int, int32, int64]): integration_boundaries = vstack( ( zeros(dim), - concatenate( - (array([2 * pi]), pi * ones(dim - 2), array([pi / 2])) - ), + concatenate((array([2 * pi]), pi * ones(dim - 2), array([pi / 2]))), ) ).T return integration_boundaries - def integrate(self, integration_boundaries = None) -> float: + def integrate(self, integration_boundaries=None) -> float: if integration_boundaries is None: integration_boundaries = ( AbstractHyperhemisphericalDistribution.get_full_integration_boundaries( @@ -122,9 +120,7 @@ def integrate(self, integration_boundaries = None) -> float: ) return super().integrate(integration_boundaries) - def integrate_numerically( - self, integration_boundaries=None - ) -> float: + def integrate_numerically(self, integration_boundaries=None) -> float: if integration_boundaries is None: integration_boundaries = ( AbstractHyperhemisphericalDistribution.get_full_integration_boundaries( @@ -146,7 +142,9 @@ def integrate_fun_over_domain( def mode_numerical(self): def objective_function_2d(s): - return -self.pdf(AbstractHypersphereSubsetDistribution.polar_to_cart(array(s))) + return -self.pdf( + AbstractHypersphereSubsetDistribution.polar_to_cart(array(s)) + ) assert self.dim == 2, "Currently only implemented for 2D hemispheres." @@ -183,4 +181,4 @@ def get_manifold_size(self): * AbstractHypersphereSubsetDistribution.compute_unit_hypersphere_surface( self.dim ) - ) \ No newline at end of file + ) diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_dirac_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_dirac_distribution.py index 8312e2b6..0d73b52f 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_dirac_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_dirac_distribution.py @@ -1,6 +1,4 @@ -from pyrecest.backend import sum -from pyrecest.backend import log - +from pyrecest.backend import log, sum from ..abstract_dirac_distribution import AbstractDiracDistribution from .abstract_hypersphere_subset_distribution import ( @@ -24,4 +22,4 @@ def entropy(self): return result def integrate(self, integration_boundaries=None): - raise NotImplementedError() \ No newline at end of file + raise NotImplementedError() diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py index c4f2b03b..8a89c6ec 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py @@ -1,27 +1,27 @@ -from pyrecest.backend import full -from pyrecest.backend import atleast_2d -from pyrecest.backend import column_stack -from pyrecest.backend import linalg -from math import pi -from typing import Union -from pyrecest.backend import sort -from pyrecest.backend import squeeze -from pyrecest.backend import sqrt -from pyrecest.backend import sin -from pyrecest.backend import log -from pyrecest.backend import cos -from pyrecest.backend import abs -from pyrecest.backend import int64 -from pyrecest.backend import int32 -from pyrecest.backend import float64 -from pyrecest.backend import zeros -from pyrecest.backend import empty -from pyrecest.backend import array from abc import abstractmethod from collections.abc import Callable +from math import pi +from typing import Union - -from beartype import beartype +from pyrecest.backend import ( + abs, + array, + atleast_2d, + column_stack, + cos, + empty, + float64, + full, + int32, + int64, + linalg, + log, + sin, + sort, + sqrt, + squeeze, + zeros, +) from scipy.integrate import nquad, quad from scipy.special import gamma @@ -54,9 +54,9 @@ def mean_direction_numerical(self, integration_boundaries=None): def f(x, i=i): return x[i] * self.pdf(x) - + fangles = self.gen_fun_hyperspherical_coords(f, self.dim) - + # Casts the floats to arrays, relevant for operations on torch.tensors # that are not backward compatible def fangles_array(*args): @@ -64,7 +64,6 @@ def fangles_array(*args): result = fangles(*tensors) return result.item() - if self.dim == 1: mu[i], _ = quad( fangles_array, @@ -139,7 +138,7 @@ def moment_numerical(self): self.dim + 1, self.dim + 1, ), - float('NaN'), + float("NaN"), ) def f_gen(i, j): @@ -382,4 +381,4 @@ def compute_unit_hypersphere_surface(dim: Union[int, int32, int64]) -> float: surface_area = 2 * pi**2 else: surface_area = 2 * pi ** ((dim + 1) / 2) / gamma((dim + 1) / 2) - return surface_area \ No newline at end of file + return surface_area diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_uniform_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_uniform_distribution.py index d4004c5b..8bef3347 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_uniform_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_uniform_distribution.py @@ -1,7 +1,5 @@ from pyrecest.backend import ones -from beartype import beartype - from ..abstract_uniform_distribution import AbstractUniformDistribution from .abstract_hypersphere_subset_distribution import ( AbstractHypersphereSubsetDistribution, @@ -32,6 +30,10 @@ def pdf(self, xs): raise ValueError("Manifold size cannot be zero.") if not isinstance(manifold_size, (int, float)): raise TypeError("Manifold size must be a numeric value.") - p = (1 / manifold_size) * ones(xs.shape[0]) if xs.ndim > 1 else 1 / manifold_size + p = ( + (1 / manifold_size) * ones(xs.shape[0]) + if xs.ndim > 1 + else 1 / manifold_size + ) - return p \ No newline at end of file + return p diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py index 98e296ba..b27c76f0 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py @@ -1,23 +1,22 @@ +from collections.abc import Callable from math import pi -from pyrecest.backend import random from typing import Union -from pyrecest.backend import vstack -from pyrecest.backend import sin -from pyrecest.backend import ones -from pyrecest.backend import meshgrid -from pyrecest.backend import linspace -from pyrecest.backend import cos -from pyrecest.backend import concatenate -from pyrecest.backend import array -from pyrecest.backend import int64 -from pyrecest.backend import int32 -from pyrecest.backend import zeros -from pyrecest.backend import meshgrid -from collections.abc import Callable import matplotlib.pyplot as plt - -from beartype import beartype +from pyrecest.backend import ( + array, + concatenate, + cos, + int32, + int64, + linspace, + meshgrid, + ones, + random, + sin, + vstack, + zeros, +) from scipy.optimize import minimize from .abstract_hypersphere_subset_distribution import ( @@ -36,7 +35,7 @@ def mean(self): throughout manifolds. :return: The mean of the distribution. - :rtype: + :rtype: """ return self.mean_direction() @@ -47,7 +46,7 @@ def sample_metropolis_hastings( burn_in: Union[int, int32, int64] = 10, skipping: Union[int, int32, int64] = 5, proposal: Callable | None = None, - start_point = None, + start_point=None, ): # jscpd:ignore-end """ @@ -189,7 +188,9 @@ def entropy(self): def mode_numerical(self): def fun(s): - return -self.pdf(AbstractHypersphereSubsetDistribution.polar_to_cart(array(s))) + return -self.pdf( + AbstractHypersphereSubsetDistribution.polar_to_cart(array(s)) + ) s0 = random.rand(self.dim) * pi res = minimize( @@ -211,7 +212,7 @@ def total_variation_distance(self, other: "AbstractHypersphericalDistribution"): def create_sphere(faces): phi_linspace = linspace(0.0, pi, faces) theta_linspace = linspace(0.0, 2.0 * pi, faces) - phi, theta = meshgrid(phi_linspace, theta_linspace, indexing='ij') + phi, theta = meshgrid(phi_linspace, theta_linspace, indexing="ij") x = sin(phi) * cos(theta) y = sin(phi) * sin(theta) z = cos(phi) @@ -258,4 +259,4 @@ def plot_unit_sphere(): def get_manifold_size(self): return AbstractHypersphereSubsetDistribution.compute_unit_hypersphere_surface( self.dim - ) \ No newline at end of file + ) diff --git a/pyrecest/distributions/hypersphere_subset/abstract_sphere_subset_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_sphere_subset_distribution.py index c30d250a..88f1028e 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_sphere_subset_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_sphere_subset_distribution.py @@ -1,12 +1,6 @@ from math import pi -from pyrecest.backend import where -from pyrecest.backend import sin -from pyrecest.backend import ndim -from pyrecest.backend import cos -from pyrecest.backend import arctan2 -from pyrecest.backend import arccos -from beartype import beartype +from pyrecest.backend import arccos, arctan2, cos, ndim, sin, where from .abstract_hypersphere_subset_distribution import ( AbstractHypersphereSubsetDistribution, @@ -52,9 +46,7 @@ def sph_to_cart(phi, theta, mode="colatitude") -> tuple: return x, y, z @staticmethod - def cart_to_sph( - x, y, z, mode="colatitude" - ) -> tuple: + def cart_to_sph(x, y, z, mode="colatitude") -> tuple: """ Convert Cartesian coordinates to spherical coordinates. @@ -66,9 +58,7 @@ def cart_to_sph( Returns: tuple: Spherical coordinates. """ - assert ( - ndim(x) == 1 and ndim(y) == 1 and ndim(z) - ), "Inputs must be 1-dimensional" + assert ndim(x) == 1 and ndim(y) == 1 and ndim(z), "Inputs must be 1-dimensional" if mode == "colatitude": phi, theta = AbstractSphereSubsetDistribution._cart_to_sph_colatitude( x, y, z @@ -84,9 +74,7 @@ def cart_to_sph( @staticmethod def _sph_to_cart_colatitude(azimuth, colatitude) -> tuple: - assert ndim(azimuth) == 1 and ndim( - colatitude - ), "Inputs must be 1-dimensional" + assert ndim(azimuth) == 1 and ndim(colatitude), "Inputs must be 1-dimensional" x = sin(colatitude) * cos(azimuth) y = sin(colatitude) * sin(azimuth) z = cos(colatitude) @@ -131,4 +119,4 @@ def _cart_to_sph_elevation(x, y, z) -> tuple: azimuth = arctan2(y, x) azimuth = where(azimuth < 0, azimuth + 2 * pi, azimuth) elevation = pi / 2 - arccos(z / radius) # elevation is π/2 - colatitude - return azimuth, elevation \ No newline at end of file + return azimuth, elevation diff --git a/pyrecest/distributions/hypersphere_subset/abstract_spherical_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_spherical_distribution.py index e5d90c2a..74b2e341 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_spherical_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_spherical_distribution.py @@ -7,4 +7,4 @@ class AbstractSphericalDistribution( ): def __init__(self): AbstractSphereSubsetDistribution.__init__(self) - AbstractHypersphericalDistribution.__init__(self, dim=2) \ No newline at end of file + AbstractHypersphericalDistribution.__init__(self, dim=2) diff --git a/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py index 6d1bf7a1..e9371a8e 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py @@ -1,17 +1,16 @@ -from pyrecest.backend import full -from math import pi -from pyrecest.backend import sqrt -from pyrecest.backend import real -from pyrecest.backend import isnan -from pyrecest.backend import imag -from pyrecest.backend import array -from pyrecest.backend import abs -from pyrecest.backend import zeros -from pyrecest.backend import atleast_2d import copy import warnings +from math import pi - +from pyrecest.backend import ( + abs, + atleast_2d, + imag, + isnan, + real, + sqrt, + zeros, +) from scipy.linalg import norm from ..abstract_orthogonal_basis_distribution import AbstractOrthogonalBasisDistribution @@ -32,7 +31,7 @@ def __init__(self, coeff_mat, transformation="identity"): n = coeff_mat.shape[0] for i in range(n): # Set the irrelevant elements to nan - coeff_mat[i, 2*i+1:] = float('NaN') + coeff_mat[i, 2 * i + 1 :] = float("NaN") AbstractOrthogonalBasisDistribution.__init__(self, coeff_mat, transformation) def pdf(self, xs): @@ -93,7 +92,7 @@ def truncate(self, degree): : 2 * result.coeff_mat.shape[0] - 1, # noqa: E203 ] = result.coeff_mat for i in range(new_coeff_mat.shape[0] - 1): - new_coeff_mat[i, 2 * i + 1 :] = float('NaN') # noqa: E203 + new_coeff_mat[i, 2 * i + 1 :] = float("NaN") # noqa: E203 result.coeff_mat = new_coeff_mat - return result \ No newline at end of file + return result diff --git a/pyrecest/distributions/hypersphere_subset/bingham_distribution.py b/pyrecest/distributions/hypersphere_subset/bingham_distribution.py index 83683332..948af359 100644 --- a/pyrecest/distributions/hypersphere_subset/bingham_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/bingham_distribution.py @@ -1,13 +1,6 @@ -from pyrecest.backend import diag -from pyrecest.backend import linalg from math import pi -from pyrecest.backend import sum -from pyrecest.backend import eye -from pyrecest.backend import exp -from pyrecest.backend import all -from pyrecest.backend import abs -from pyrecest.backend import amax +from pyrecest.backend import abs, all, amax, diag, exp, eye, linalg, sum from scipy.integrate import quad from scipy.special import iv @@ -26,9 +19,7 @@ def __init__(self, Z, M): # Verify that M is orthogonal epsilon = 0.001 - assert ( - amax(abs(M @ M.T - eye(self.dim + 1))) < epsilon - ), "M is not orthogonal" + assert amax(abs(M @ M.T - eye(self.dim + 1))) < epsilon, "M is not orthogonal" self.Z = Z self.M = M @@ -131,4 +122,4 @@ def moment(self): D = D / sum(diag(D)) S = self.M @ D @ self.M.T S = (S + S.T) / 2 # Enforce symmetry - return S \ No newline at end of file + return S diff --git a/pyrecest/distributions/hypersphere_subset/custom_hemispherical_distribution.py b/pyrecest/distributions/hypersphere_subset/custom_hemispherical_distribution.py index 1abb5634..e8ef0b1a 100644 --- a/pyrecest/distributions/hypersphere_subset/custom_hemispherical_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/custom_hemispherical_distribution.py @@ -1,7 +1,6 @@ import warnings from collections.abc import Callable -from beartype import beartype from .abstract_hemispherical_distribution import AbstractHemisphericalDistribution from .abstract_hyperhemispherical_distribution import ( @@ -44,4 +43,4 @@ def from_distribution(distribution: "AbstractHypersphericalDistribution"): chsd.scale_by = 1 / norm_const_inv return chsd - raise ValueError("Input variable dist is of wrong class.") \ No newline at end of file + raise ValueError("Input variable dist is of wrong class.") diff --git a/pyrecest/distributions/hypersphere_subset/custom_hyperhemispherical_distribution.py b/pyrecest/distributions/hypersphere_subset/custom_hyperhemispherical_distribution.py index c2b66506..ed996d87 100644 --- a/pyrecest/distributions/hypersphere_subset/custom_hyperhemispherical_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/custom_hyperhemispherical_distribution.py @@ -1,10 +1,7 @@ -from typing import Union -from pyrecest.backend import int64 -from pyrecest.backend import int32 from collections.abc import Callable +from typing import Union - -from beartype import beartype +from pyrecest.backend import int32, int64 from ..abstract_custom_distribution import AbstractCustomDistribution from .abstract_hyperhemispherical_distribution import ( @@ -17,9 +14,7 @@ class CustomHyperhemisphericalDistribution( AbstractCustomDistribution, AbstractHyperhemisphericalDistribution ): - def __init__( - self, f: Callable, dim: Union[int, int32, int64], scale_by: float = 1 - ): + def __init__(self, f: Callable, dim: Union[int, int32, int64], scale_by: float = 1): """ Initialize a CustomHyperhemisphericalDistribution. @@ -83,4 +78,4 @@ def from_distribution(distribution: "AbstractHypersphericalDistribution"): distribution.pdf / norm_const_inv, distribution.dim ) - raise ValueError("Input variable distribution is of the wrong class.") \ No newline at end of file + raise ValueError("Input variable distribution is of the wrong class.") diff --git a/pyrecest/distributions/hypersphere_subset/custom_hyperspherical_distribution.py b/pyrecest/distributions/hypersphere_subset/custom_hyperspherical_distribution.py index 50317bca..e32e2251 100644 --- a/pyrecest/distributions/hypersphere_subset/custom_hyperspherical_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/custom_hyperspherical_distribution.py @@ -19,4 +19,4 @@ def from_distribution(distribution): def integrate(self, integration_boundaries=None): return AbstractHypersphericalDistribution.integrate( self, integration_boundaries - ) \ No newline at end of file + ) diff --git a/pyrecest/distributions/hypersphere_subset/hemispherical_uniform_distribution.py b/pyrecest/distributions/hypersphere_subset/hemispherical_uniform_distribution.py index bcc3125c..7742a943 100644 --- a/pyrecest/distributions/hypersphere_subset/hemispherical_uniform_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/hemispherical_uniform_distribution.py @@ -7,4 +7,4 @@ class HemisphericalUniformDistribution( AbstractHypersphereSubsetUniformDistribution, AbstractHemisphericalDistribution ): - pass \ No newline at end of file + pass diff --git a/pyrecest/distributions/hypersphere_subset/hyperhemispherical_dirac_distribution.py b/pyrecest/distributions/hypersphere_subset/hyperhemispherical_dirac_distribution.py index 76cf9127..6be43cd0 100644 --- a/pyrecest/distributions/hypersphere_subset/hyperhemispherical_dirac_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/hyperhemispherical_dirac_distribution.py @@ -9,4 +9,4 @@ class HyperhemisphericalDiracDistribution( AbstractHypersphereSubsetDiracDistribution, AbstractHyperhemisphericalDistribution ): - pass \ No newline at end of file + pass diff --git a/pyrecest/distributions/hypersphere_subset/hyperhemispherical_uniform_distribution.py b/pyrecest/distributions/hypersphere_subset/hyperhemispherical_uniform_distribution.py index 443afa33..49c3beb5 100644 --- a/pyrecest/distributions/hypersphere_subset/hyperhemispherical_uniform_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/hyperhemispherical_uniform_distribution.py @@ -1,8 +1,6 @@ from typing import Union -from pyrecest.backend import int64 -from pyrecest.backend import int32 -from beartype import beartype +from pyrecest.backend import int32, int64 from .abstract_hyperhemispherical_distribution import ( AbstractHyperhemisphericalDistribution, @@ -49,4 +47,4 @@ def get_manifold_size(self) -> float: self.dim ) / 2 - ) \ No newline at end of file + ) diff --git a/pyrecest/distributions/hypersphere_subset/hyperhemispherical_watson_distribution.py b/pyrecest/distributions/hypersphere_subset/hyperhemispherical_watson_distribution.py index a3f927ba..8aae6ef1 100644 --- a/pyrecest/distributions/hypersphere_subset/hyperhemispherical_watson_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/hyperhemispherical_watson_distribution.py @@ -1,13 +1,6 @@ from typing import Union -from pyrecest.backend import allclose -from pyrecest.backend import all -from pyrecest.backend import int64 -from pyrecest.backend import int32 -from pyrecest.backend import zeros -import numbers - -from beartype import beartype +from pyrecest.backend import allclose, int32, int64, zeros from .abstract_hyperhemispherical_distribution import ( AbstractHyperhemisphericalDistribution, @@ -61,4 +54,4 @@ def shift(self, shift_by) -> "HyperhemisphericalWatsonDistribution": ), "There is no true shifting for the hyperhemisphere. This is a function for compatibility and only works when mu is [0,0,...,1]." dist_shifted = self dist_shifted.mu = shift_by - return dist_shifted \ No newline at end of file + return dist_shifted diff --git a/pyrecest/distributions/hypersphere_subset/hyperspherical_dirac_distribution.py b/pyrecest/distributions/hypersphere_subset/hyperspherical_dirac_distribution.py index a8b6bbc2..1d71282f 100644 --- a/pyrecest/distributions/hypersphere_subset/hyperspherical_dirac_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/hyperspherical_dirac_distribution.py @@ -1,8 +1,5 @@ -from pyrecest.backend import linalg -from pyrecest.backend import sum -from pyrecest.backend import reshape import matplotlib.pyplot as plt - +from pyrecest.backend import linalg, reshape, sum from ..circle.circular_dirac_distribution import CircularDiracDistribution from .abstract_hypersphere_subset_dirac_distribution import ( @@ -38,4 +35,4 @@ def to_circular_dirac_distribution(self): def mean_direction(self): vec_sum = sum(self.d * reshape(self.w, (-1, 1)), axis=0) mu = vec_sum / linalg.norm(vec_sum) - return mu \ No newline at end of file + return mu diff --git a/pyrecest/distributions/hypersphere_subset/hyperspherical_mixture.py b/pyrecest/distributions/hypersphere_subset/hyperspherical_mixture.py index 529f906c..82e0bcfc 100644 --- a/pyrecest/distributions/hypersphere_subset/hyperspherical_mixture.py +++ b/pyrecest/distributions/hypersphere_subset/hyperspherical_mixture.py @@ -1,6 +1,4 @@ -from beartype import beartype - from ..abstract_mixture import AbstractMixture from .abstract_hyperspherical_distribution import AbstractHypersphericalDistribution @@ -10,10 +8,7 @@ class HypersphericalMixture(AbstractMixture, AbstractHypersphericalDistribution) A class used to represent a mixture of hyperspherical distributions. """ - def __init__( - self, - dists: list[AbstractHypersphericalDistribution], - w): + def __init__(self, dists: list[AbstractHypersphericalDistribution], w): """ Initializes the HypersphericalMixture with a list of distributions and weights. @@ -26,4 +21,4 @@ def __init__( isinstance(dist, AbstractHypersphericalDistribution) for dist in dists ), "dists must be a list of hyperspherical distributions" - AbstractMixture.__init__(self, dists, w) \ No newline at end of file + AbstractMixture.__init__(self, dists, w) diff --git a/pyrecest/distributions/hypersphere_subset/hyperspherical_uniform_distribution.py b/pyrecest/distributions/hypersphere_subset/hyperspherical_uniform_distribution.py index 03e7999a..f466e2a9 100644 --- a/pyrecest/distributions/hypersphere_subset/hyperspherical_uniform_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/hyperspherical_uniform_distribution.py @@ -1,15 +1,7 @@ -from pyrecest.backend import linalg from math import pi -from pyrecest.backend import random from typing import Union -from pyrecest.backend import sqrt -from pyrecest.backend import sin -from pyrecest.backend import cos -from pyrecest.backend import int64 -from pyrecest.backend import int32 -from pyrecest.backend import empty -from beartype import beartype +from pyrecest.backend import cos, empty, int32, int64, linalg, random, sin, sqrt from .abstract_hypersphere_subset_uniform_distribution import ( AbstractHypersphereSubsetUniformDistribution, @@ -47,4 +39,4 @@ def sample(self, n: Union[int, int32, int64]): return s def get_manifold_size(self): - return AbstractHypersphericalDistribution.get_manifold_size(self) \ No newline at end of file + return AbstractHypersphericalDistribution.get_manifold_size(self) diff --git a/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py b/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py index bbac0de0..005c879a 100644 --- a/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py +++ b/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py @@ -1,25 +1,26 @@ -from pyrecest.backend import full -from pyrecest.backend import atleast_2d -from pyrecest.backend import conj -from pyrecest.backend import column_stack -from pyrecest.backend import linalg -from pyrecest.backend import complex128 from math import pi -from pyrecest.backend import sqrt -from pyrecest.backend import sin -from pyrecest.backend import shape -from pyrecest.backend import reshape -from pyrecest.backend import real -from pyrecest.backend import prod -from pyrecest.backend import isnan -from pyrecest.backend import imag -from pyrecest.backend import array -from pyrecest.backend import all -from pyrecest.backend import abs -from pyrecest.backend import empty -from pyrecest.backend import zeros import scipy +from pyrecest.backend import ( + abs, + all, + array, + atleast_2d, + column_stack, + complex128, + conj, + empty, + full, + imag, + isnan, + linalg, + real, + reshape, + shape, + sin, + sqrt, + zeros, +) # pylint: disable=E0611 from scipy.special import sph_harm @@ -87,9 +88,7 @@ def to_spherical_harmonics_distribution_real(self): ) elif m > 0: coeff_mat_real[n, n + m] = ( - sqrt(2) - * (-1 if m % 2 else 1) - * real(self.coeff_mat[n, n + m]) + sqrt(2) * (-1 if m % 2 else 1) * real(self.coeff_mat[n, n + m]) ) else: # m == 0 coeff_mat_real[n, n] = real(self.coeff_mat[n, n]) @@ -157,7 +156,7 @@ def from_function_via_integral_sph(fun, degree, transformation="identity"): else: raise ValueError("Transformation not supported") - coeff_mat = full((degree + 1, 2 * degree + 1), float('NaN'), dtype=complex128) + coeff_mat = full((degree + 1, 2 * degree + 1), float("NaN"), dtype=complex128) def real_part(phi, theta, n, m): return real( @@ -188,4 +187,4 @@ def imag_part(phi, theta, n, m): coeff_mat[n, m + n] = real_integral + 1j * imag_integral - return SphericalHarmonicsDistributionComplex(coeff_mat, transformation) \ No newline at end of file + return SphericalHarmonicsDistributionComplex(coeff_mat, transformation) diff --git a/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_real.py b/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_real.py index 8e57dc0e..f612aec7 100644 --- a/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_real.py +++ b/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_real.py @@ -1,14 +1,14 @@ -from pyrecest.backend import full_like -from pyrecest.backend import atleast_2d -from pyrecest.backend import sqrt -from pyrecest.backend import real -from pyrecest.backend import imag -from pyrecest.backend import all -from pyrecest.backend import zeros -from pyrecest.backend import isreal -from pyrecest.backend import complex128 - - +from pyrecest.backend import ( + all, + atleast_2d, + complex128, + full_like, + imag, + isreal, + real, + sqrt, + zeros, +) # pylint: disable=E0611 from scipy.special import sph_harm @@ -64,7 +64,7 @@ def to_spherical_harmonics_distribution_complex(self): raise NotImplementedError("Transformation currently not supported") real_coeff_mat = self.coeff_mat - complex_coeff_mat = full_like(real_coeff_mat, float('NaN'), dtype=complex128) + complex_coeff_mat = full_like(real_coeff_mat, float("NaN"), dtype=complex128) for n in range(real_coeff_mat.shape[0]): for m in range(-n, n + 1): @@ -83,4 +83,4 @@ def to_spherical_harmonics_distribution_complex(self): return SphericalHarmonicsDistributionComplex( complex_coeff_mat, self.transformation - ) \ No newline at end of file + ) diff --git a/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py b/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py index dfca8050..1cb4ea84 100644 --- a/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py @@ -1,24 +1,23 @@ -import pyrecest.backend -from pyrecest.backend import linalg from math import pi from typing import Union -from pyrecest.backend import sinh -from pyrecest.backend import sin -from pyrecest.backend import ndim -from pyrecest.backend import isnan -from pyrecest.backend import exp -from pyrecest.backend import cos -from pyrecest.backend import arccos -from pyrecest.backend import all -from pyrecest.backend import abs -from pyrecest.backend import int64 -from pyrecest.backend import int32 -from pyrecest.backend import zeros -from pyrecest.backend import array -import numbers - - -from beartype import beartype + +import pyrecest.backend +from pyrecest.backend import ( + abs, + all, + arccos, + array, + cos, + exp, + int32, + int64, + isnan, + linalg, + ndim, + sin, + sinh, + zeros, +) from scipy.special import iv from .abstract_hyperspherical_distribution import AbstractHypersphericalDistribution @@ -62,7 +61,9 @@ def sample(self, n): array: n von Mises-Fisher distributed random vectors. # Requires scipy 1.11 or later """ - assert pyrecest.backend.__name__ == "pyrecest.numpy", "Only supported on NumPy backend" + assert ( + pyrecest.backend.__name__ == "pyrecest.numpy" + ), "Only supported on NumPy backend" from scipy.stats import vonmises_fisher # Create a von Mises-Fisher distribution object @@ -189,4 +190,4 @@ def a_d_inverse(d: Union[int, int32, int64], x: float): if abs(kappa_ - kappa_old) < epsilon: break - return kappa_ \ No newline at end of file + return kappa_ diff --git a/pyrecest/distributions/hypersphere_subset/watson_distribution.py b/pyrecest/distributions/hypersphere_subset/watson_distribution.py index a0c517cb..4118004c 100644 --- a/pyrecest/distributions/hypersphere_subset/watson_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/watson_distribution.py @@ -1,22 +1,18 @@ -from pyrecest.backend import full -from pyrecest.backend import linalg -from pyrecest.backend import vstack -from pyrecest.backend import tile -from pyrecest.backend import hstack -from pyrecest.backend import eye -from pyrecest.backend import exp -from pyrecest.backend import dot -from pyrecest.backend import array -from pyrecest.backend import abs -from pyrecest.backend import float64 -from pyrecest.backend import zeros -import numbers -import numpy.testing as npt import mpmath - -from beartype import beartype -from scipy.linalg import qr +import numpy.testing as npt +from pyrecest.backend import ( + abs, + array, + exp, + eye, + full, + hstack, + linalg, + tile, + vstack, + zeros, +) from .abstract_hyperspherical_distribution import AbstractHypersphericalDistribution from .bingham_distribution import BinghamDistribution @@ -95,5 +91,9 @@ def set_mode(self, new_mode): return dist def shift(self, shift_by): - npt.assert_almost_equal(self.mu, vstack([zeros((self.dim, 1)), 1]), "There is no true shifting for the hypersphere. This is a function for compatibility and only works when mu is [0,0,...,1].") - return self.set_mode(shift_by) \ No newline at end of file + npt.assert_almost_equal( + self.mu, + vstack([zeros((self.dim, 1)), 1]), + "There is no true shifting for the hypersphere. This is a function for compatibility and only works when mu is [0,0,...,1].", + ) + return self.set_mode(shift_by) diff --git a/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py b/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py index fd525586..aadf6fab 100644 --- a/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py +++ b/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py @@ -1,32 +1,31 @@ +from collections.abc import Callable from math import pi -from pyrecest.backend import random from typing import Union -from pyrecest.backend import vstack -from pyrecest.backend import sqrt -from pyrecest.backend import sin -from pyrecest.backend import reshape -from pyrecest.backend import ones -from pyrecest.backend import mod -from pyrecest.backend import meshgrid -from pyrecest.backend import log -from pyrecest.backend import linspace -from pyrecest.backend import isnan -from pyrecest.backend import angle -from pyrecest.backend import cos -from pyrecest.backend import array -from pyrecest.backend import arange -from pyrecest.backend import abs -from pyrecest.backend import int64 -from pyrecest.backend import int32 -from pyrecest.backend import zeros -from pyrecest.backend import minimum -import pyrecest.backend -import numbers -from collections.abc import Callable import matplotlib.pyplot as plt - -from beartype import beartype +import pyrecest.backend +from pyrecest.backend import ( + abs, + angle, + arange, + array, + cos, + int32, + int64, + isnan, + linspace, + log, + meshgrid, + minimum, + mod, + ones, + random, + reshape, + sin, + sqrt, + vstack, + zeros, +) from scipy.integrate import nquad from ..abstract_manifold_specific_distribution import ( @@ -87,10 +86,10 @@ def integrate_fun_over_domain_part( return nquad(f, integration_boundaries)[0] - def integrate_numerically( - self, integration_boundaries=None - ): - assert pyrecest.backend.__name__ == 'pyrecest.numpy', "Only supported for numpy backend" + def integrate_numerically(self, integration_boundaries=None): + assert ( + pyrecest.backend.__name__ == "pyrecest.numpy" + ), "Only supported for numpy backend" if integration_boundaries is None: integration_boundaries = vstack( (zeros(self.dim), 2.0 * pi * ones(self.dim)) @@ -104,9 +103,7 @@ def integrate_numerically( lambda *args: self.pdf(array(args)), self.dim, integration_boundaries ) - def trigonometric_moment_numerical( - self, n: Union[int, int32, int64] - ): + def trigonometric_moment_numerical(self, n: Union[int, int32, int64]): """Calculates the complex trignometric moments. Since nquad does not support complex functions, the calculation is split up (as used in the alternative representation of trigonometric polonymials involving the two real numbers alpha and beta""" @@ -226,7 +223,7 @@ def mean(self): throughout manifolds. :return: The mean of the distribution. - :rtype: + :rtype: """ return self.mean_direction() @@ -294,4 +291,4 @@ def setup_axis_circular(axis_name: str = "x", ax=plt.gca()) -> None: ax.set_zticks(ticks) ax.set_zticklabels(tick_labels) else: - raise ValueError("invalid axis") \ No newline at end of file + raise ValueError("invalid axis") diff --git a/pyrecest/distributions/hypertorus/abstract_toroidal_distribution.py b/pyrecest/distributions/hypertorus/abstract_toroidal_distribution.py index 112b441f..b9f3db3d 100644 --- a/pyrecest/distributions/hypertorus/abstract_toroidal_distribution.py +++ b/pyrecest/distributions/hypertorus/abstract_toroidal_distribution.py @@ -1,13 +1,7 @@ from math import pi from typing import Union -from pyrecest.backend import sqrt -from pyrecest.backend import sin -from pyrecest.backend import cos -from pyrecest.backend import array -from pyrecest.backend import int64 -from pyrecest.backend import int32 -from pyrecest.backend import zeros +from pyrecest.backend import array, cos, int32, int64, sin, sqrt, zeros from scipy.integrate import dblquad from .abstract_hypertoroidal_distribution import AbstractHypertoroidalDistribution @@ -76,4 +70,4 @@ def mean_4D(self): """ m = self.trigonometric_moment(1) mu = array([m[0].real, m[0].imag, m[1].real, m[1].imag]).ravel() - return mu \ No newline at end of file + return mu diff --git a/pyrecest/distributions/hypertorus/custom_hypertoroidal_distribution.py b/pyrecest/distributions/hypertorus/custom_hypertoroidal_distribution.py index af6d61c1..69b9f3bf 100644 --- a/pyrecest/distributions/hypertorus/custom_hypertoroidal_distribution.py +++ b/pyrecest/distributions/hypertorus/custom_hypertoroidal_distribution.py @@ -1,10 +1,8 @@ from math import pi -from pyrecest.backend import mod -from pyrecest.backend import zeros +from pyrecest.backend import mod, zeros from ..abstract_custom_distribution import AbstractCustomDistribution - from .abstract_hypertoroidal_distribution import AbstractHypertoroidalDistribution @@ -29,9 +27,7 @@ def __init__(self, f, dim, shift_by=None): self.shift_by = shift_by def pdf(self, xs): - return AbstractCustomDistribution.pdf( - self, mod(xs + self.shift_by, 2 * pi) - ) + return AbstractCustomDistribution.pdf(self, mod(xs + self.shift_by, 2 * pi)) def to_custom_circular(self): # Convert to a custom circular distribution (only in 1D case) @@ -53,4 +49,4 @@ def to_custom_toroidal(self): assert self.dim == 2 ctd = CustomToroidalDistribution(self.f) - return ctd \ No newline at end of file + return ctd diff --git a/pyrecest/distributions/hypertorus/custom_toroidal_distribution.py b/pyrecest/distributions/hypertorus/custom_toroidal_distribution.py index f938a7c7..364e89c8 100644 --- a/pyrecest/distributions/hypertorus/custom_toroidal_distribution.py +++ b/pyrecest/distributions/hypertorus/custom_toroidal_distribution.py @@ -7,4 +7,4 @@ class CustomToroidalDistribution( ): def __init__(self, f): AbstractToroidalDistribution.__init__(self) - CustomHypertoroidalDistribution.__init__(self, f, 2) \ No newline at end of file + CustomHypertoroidalDistribution.__init__(self, f, 2) diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py b/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py index 5fbc92c8..142eb685 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py @@ -1,21 +1,21 @@ -from math import pi -from typing import Union -from pyrecest.backend import tile -from pyrecest.backend import sum -from pyrecest.backend import reshape -from pyrecest.backend import real -from pyrecest.backend import mod -from pyrecest.backend import imag -from pyrecest.backend import exp -from pyrecest.backend import arctan2 -from pyrecest.backend import int64 -from pyrecest.backend import atleast_1d -from pyrecest.backend import int32 import copy from collections.abc import Callable +from math import pi +from typing import Union - -from beartype import beartype +from pyrecest.backend import ( + arctan2, + atleast_1d, + exp, + imag, + int32, + int64, + mod, + real, + reshape, + sum, + tile, +) from ..abstract_dirac_distribution import AbstractDiracDistribution from .abstract_hypertoroidal_distribution import AbstractHypertoroidalDistribution @@ -24,9 +24,7 @@ class HypertoroidalDiracDistribution( AbstractDiracDistribution, AbstractHypertoroidalDistribution ): - def __init__( - self, d, w=None, dim: int | None = None - ): + def __init__(self, d, w=None, dim: int | None = None): """Can set dim manually to tell apart number of samples vs dimension for 1-D arrays.""" if dim is None: if d.ndim > 1: @@ -35,9 +33,7 @@ def __init__( raise ValueError("Cannot automatically determine dimension.") AbstractHypertoroidalDistribution.__init__(self, dim) - AbstractDiracDistribution.__init__( - self, atleast_1d(mod(d, 2.0 * pi)), w=w - ) + AbstractDiracDistribution.__init__(self, atleast_1d(mod(d, 2.0 * pi)), w=w) def plot(self, *args, **kwargs): raise NotImplementedError("Plotting is not implemented") @@ -61,11 +57,11 @@ def trigonometric_moment(self, n: Union[int, int32, int64]): :param n: Integer moment order :return: Trigonometric moment """ - return sum( - exp(1j * n * self.d.T) * tile(self.w, (self.dim, 1)), axis=1 - ) + return sum(exp(1j * n * self.d.T) * tile(self.w, (self.dim, 1)), axis=1) - def apply_function(self, f: Callable, f_supports_multiple: bool = True) -> "HypertoroidalDiracDistribution": + def apply_function( + self, f: Callable, f_supports_multiple: bool = True + ) -> "HypertoroidalDiracDistribution": dist = super().apply_function(f, f_supports_multiple) dist.d = mod(dist.d, 2.0 * pi) return dist @@ -103,4 +99,4 @@ def to_wd(self): assert self.dim == 1 from ..circle.circular_dirac_distribution import CircularDiracDistribution - return CircularDiracDistribution(self.d, self.w) \ No newline at end of file + return CircularDiracDistribution(self.d, self.w) diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_mixture.py b/pyrecest/distributions/hypertorus/hypertoroidal_mixture.py index a33bfc05..38c71760 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_mixture.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_mixture.py @@ -1,13 +1,8 @@ -from typing import Union -from pyrecest.backend import int64 -from pyrecest.backend import int32 -from pyrecest.backend import zeros -from pyrecest.backend import complex128 import collections import copy +from typing import Union - -from beartype import beartype +from pyrecest.backend import complex128, int32, int64, zeros from ..abstract_mixture import AbstractMixture from .abstract_hypertoroidal_distribution import AbstractHypertoroidalDistribution @@ -17,7 +12,7 @@ class HypertoroidalMixture(AbstractMixture, AbstractHypertoroidalDistribution): def __init__( self, dists: collections.abc.Sequence[AbstractHypertoroidalDistribution], - w = None, + w=None, ): """ Constructor @@ -81,4 +76,4 @@ def to_toroidal_mixture(self): @property def input_dim(self): - return AbstractHypertoroidalDistribution.input_dim.fget(self) \ No newline at end of file + return AbstractHypertoroidalDistribution.input_dim.fget(self) diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_uniform_distribution.py b/pyrecest/distributions/hypertorus/hypertoroidal_uniform_distribution.py index f9ac8c05..05b676bd 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_uniform_distribution.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_uniform_distribution.py @@ -1,14 +1,7 @@ from math import pi -from pyrecest.backend import random from typing import Union -from pyrecest.backend import prod -from pyrecest.backend import ones -from pyrecest.backend import ndim -from pyrecest.backend import log -from pyrecest.backend import int64 -from pyrecest.backend import int32 -from pyrecest.backend import zeros +from pyrecest.backend import int32, int64, log, ndim, ones, prod, random, zeros from ..abstract_uniform_distribution import AbstractUniformDistribution from .abstract_hypertoroidal_distribution import AbstractHypertoroidalDistribution @@ -25,16 +18,16 @@ def pdf(self, xs): :returns: PDF evaluated at xs """ if xs.ndim == 0: - assert self.dim==1 + assert self.dim == 1 n_inputs = 1 - elif xs.ndim == 1 and self.dim==1: + elif xs.ndim == 1 and self.dim == 1: n_inputs = xs.shape[0] elif xs.ndim == 1: - assert self.dim==xs.shape[0] + assert self.dim == xs.shape[0] n_inputs = 1 else: n_inputs = xs.shape[0] - + return 1.0 / self.get_manifold_size() * ones(n_inputs) def trigonometric_moment(self, n: Union[int, int32, int64]): @@ -88,9 +81,7 @@ def shift(self, shift_by) -> "HypertoroidalUniformDistribution": assert shift_by.shape == (self.dim,) return self - def integrate( - self, integration_boundaries=None - ) -> float: + def integrate(self, integration_boundaries=None) -> float: """ Returns the integral of the distribution over the specified boundaries @@ -107,4 +98,4 @@ def integrate( assert ndim(right) == 0 and self.dim == 1 or right.shape == (self.dim,) volume = prod(right - left) - return 1.0 / (2.0 * pi) ** self.dim * volume \ No newline at end of file + return 1.0 / (2.0 * pi) ** self.dim * volume diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py b/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py index a9d8b805..a1768566 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py @@ -1,22 +1,21 @@ -from pyrecest.backend import linalg +import copy from math import pi -from pyrecest.backend import random from typing import Union -from pyrecest.backend import reshape -from pyrecest.backend import mod -from pyrecest.backend import meshgrid -from pyrecest.backend import exp -from pyrecest.backend import array -from pyrecest.backend import arange -from pyrecest.backend import allclose -from pyrecest.backend import all -from pyrecest.backend import int64 -from pyrecest.backend import int32 -from pyrecest.backend import zeros -import copy - -from beartype import beartype +from pyrecest.backend import ( + allclose, + arange, + array, + exp, + int32, + int64, + linalg, + meshgrid, + mod, + random, + reshape, + zeros, +) from scipy.stats import multivariate_normal from .abstract_hypertoroidal_distribution import AbstractHypertoroidalDistribution @@ -32,14 +31,16 @@ def __init__(self, mu, C): :raises AssertionError: If C_ is not square, not symmetric, not positive definite, or its dimension does not match with mu_. """ numel_mu = 1 if mu.ndim == 0 else mu.shape[0] - assert C.ndim == 0 or C.ndim == 2 and C.shape[0] == C.shape[1], "C must be of shape (dim, dim)" + assert ( + C.ndim == 0 or C.ndim == 2 and C.shape[0] == C.shape[1] + ), "C must be of shape (dim, dim)" assert allclose(C, C.T, atol=1e-8), "C must be symmetric" - assert (C.ndim == 0 and C > 0.0 or - len(linalg.cholesky(C)) > 0 # fails if not positiv definite - ), "C must be positive definite" assert ( - numel_mu == 1 or mu.shape == (C.shape[1],) - ), "mu must be of shape (dim,)" + C.ndim == 0 + and C > 0.0 + or len(linalg.cholesky(C)) > 0 # fails if not positiv definite + ), "C must be positive definite" + assert numel_mu == 1 or mu.shape == (C.shape[1],), "mu must be of shape (dim,)" AbstractHypertoroidalDistribution.__init__(self, numel_mu) self.mu = mod(mu, 2.0 * pi) self.C = C @@ -134,4 +135,4 @@ def mode(self): # Returns: # m (vector) # the mode - return self.mu \ No newline at end of file + return self.mu diff --git a/pyrecest/distributions/hypertorus/toroidal_dirac_distribution.py b/pyrecest/distributions/hypertorus/toroidal_dirac_distribution.py index 4544e6f6..66ec4ff6 100644 --- a/pyrecest/distributions/hypertorus/toroidal_dirac_distribution.py +++ b/pyrecest/distributions/hypertorus/toroidal_dirac_distribution.py @@ -1,12 +1,4 @@ -from pyrecest.backend import diag -from pyrecest.backend import tile -from pyrecest.backend import sum -from pyrecest.backend import sqrt -from pyrecest.backend import sin -from pyrecest.backend import dot -from pyrecest.backend import cos -from pyrecest.backend import column_stack - +from pyrecest.backend import column_stack, cos, diag, dot, sin, sqrt, sum, tile from .abstract_toroidal_distribution import AbstractToroidalDistribution from .hypertoroidal_dirac_distribution import HypertoroidalDiracDistribution @@ -57,7 +49,5 @@ def covariance_4D(self): ) mu = dot(self.w, dbar) n = len(self.d) - C = (dbar - tile(mu, (n, 1))).T @ ( - diag(self.w) @ (dbar - tile(mu, (n, 1))) - ) - return C \ No newline at end of file + C = (dbar - tile(mu, (n, 1))).T @ (diag(self.w) @ (dbar - tile(mu, (n, 1)))) + return C diff --git a/pyrecest/distributions/hypertorus/toroidal_mixture.py b/pyrecest/distributions/hypertorus/toroidal_mixture.py index daa953c9..21900a5e 100644 --- a/pyrecest/distributions/hypertorus/toroidal_mixture.py +++ b/pyrecest/distributions/hypertorus/toroidal_mixture.py @@ -1,5 +1,3 @@ - - from .abstract_toroidal_distribution import AbstractToroidalDistribution from .hypertoroidal_mixture import HypertoroidalMixture @@ -17,4 +15,4 @@ def __init__(self, hds: list[AbstractToroidalDistribution], w): ), "hds must be a list of toroidal distributions" HypertoroidalMixture.__init__(self, hds, w) - AbstractToroidalDistribution.__init__(self) \ No newline at end of file + AbstractToroidalDistribution.__init__(self) diff --git a/pyrecest/distributions/hypertorus/toroidal_uniform_distribution.py b/pyrecest/distributions/hypertorus/toroidal_uniform_distribution.py index 9f237534..b2eedda5 100644 --- a/pyrecest/distributions/hypertorus/toroidal_uniform_distribution.py +++ b/pyrecest/distributions/hypertorus/toroidal_uniform_distribution.py @@ -6,4 +6,4 @@ class ToroidalUniformDistribution( HypertoroidalUniformDistribution, AbstractToroidalDistribution ): def get_manifold_size(self): - return AbstractToroidalDistribution.get_manifold_size(self) \ No newline at end of file + return AbstractToroidalDistribution.get_manifold_size(self) diff --git a/pyrecest/distributions/hypertorus/toroidal_von_mises_sine_distribution.py b/pyrecest/distributions/hypertorus/toroidal_von_mises_sine_distribution.py index 225db015..6a0c31f9 100644 --- a/pyrecest/distributions/hypertorus/toroidal_von_mises_sine_distribution.py +++ b/pyrecest/distributions/hypertorus/toroidal_von_mises_sine_distribution.py @@ -1,12 +1,6 @@ from math import pi -from pyrecest.backend import sum -from pyrecest.backend import sin -from pyrecest.backend import mod -from pyrecest.backend import exp -from pyrecest.backend import cos -from pyrecest.backend import all -from pyrecest.backend import array +from pyrecest.backend import all, array, cos, exp, mod, sin, sum from scipy.special import comb, iv from .abstract_toroidal_distribution import AbstractToroidalDistribution @@ -44,8 +38,6 @@ def pdf(self, xs): p = self.C * exp( self.kappa[0] * cos(xs[..., 0] - self.mu[0]) + self.kappa[1] * cos(xs[..., 1] - self.mu[1]) - + self.lambda_ - * sin(xs[..., 0] - self.mu[0]) - * sin(xs[..., 1] - self.mu[1]) + + self.lambda_ * sin(xs[..., 0] - self.mu[0]) * sin(xs[..., 1] - self.mu[1]) ) - return p \ No newline at end of file + return p diff --git a/pyrecest/distributions/hypertorus/toroidal_wrapped_normal_distribution.py b/pyrecest/distributions/hypertorus/toroidal_wrapped_normal_distribution.py index a8aaa235..d8b9f09f 100644 --- a/pyrecest/distributions/hypertorus/toroidal_wrapped_normal_distribution.py +++ b/pyrecest/distributions/hypertorus/toroidal_wrapped_normal_distribution.py @@ -1,6 +1,5 @@ -from pyrecest.backend import array - from numpy import cos, exp, sin +from pyrecest.backend import array from .abstract_toroidal_distribution import AbstractToroidalDistribution from .hypertoroidal_wrapped_normal_distribution import ( @@ -123,4 +122,4 @@ def covariance_4D(self): C[2, 1] = C[1, 2] C[3, 1] = C[1, 3] # jscpd:ignore-end - return C \ No newline at end of file + return C diff --git a/pyrecest/distributions/nonperiodic/abstract_hyperrectangular_distribution.py b/pyrecest/distributions/nonperiodic/abstract_hyperrectangular_distribution.py index d1d7181b..d8edd0a4 100644 --- a/pyrecest/distributions/nonperiodic/abstract_hyperrectangular_distribution.py +++ b/pyrecest/distributions/nonperiodic/abstract_hyperrectangular_distribution.py @@ -1,7 +1,4 @@ -from pyrecest.backend import reshape -from pyrecest.backend import prod -from pyrecest.backend import array -from pyrecest.backend import diff +from pyrecest.backend import array, diff, prod, reshape from scipy.integrate import nquad from ..abstract_bounded_nonperiodic_distribution import ( @@ -42,4 +39,4 @@ def integrate(self, integration_boundaries=None) -> float: left, right = integration_boundaries integration_boundaries = zip(left, right) - return nquad(lambda *args: self.pdf(array(args)), integration_boundaries)[0] \ No newline at end of file + return nquad(lambda *args: self.pdf(array(args)), integration_boundaries)[0] diff --git a/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py b/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py index 1303ff52..5725fd77 100644 --- a/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py +++ b/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py @@ -1,23 +1,25 @@ -from pyrecest.backend import full -from pyrecest.backend import atleast_1d -from pyrecest.backend import random -from typing import Union -from pyrecest.backend import squeeze -from pyrecest.backend import sqrt -from pyrecest.backend import reshape -from pyrecest.backend import ndim -from pyrecest.backend import meshgrid -from pyrecest.backend import linspace -from pyrecest.backend import array -from pyrecest.backend import int64 -from pyrecest.backend import int32 -from pyrecest.backend import column_stack -import pyrecest.backend -import numbers from collections.abc import Callable +from typing import Union import matplotlib.pyplot as plt - +import pyrecest.backend +from pyrecest.backend import ( + array, + atleast_1d, + column_stack, + empty, + full, + int32, + int64, + linspace, + meshgrid, + ndim, + ones, + random, + reshape, + sqrt, + squeeze, +) from pyrecest.utils.plotting import plot_ellipsoid from scipy.integrate import dblquad, nquad, quad from scipy.optimize import minimize @@ -26,7 +28,6 @@ from ..abstract_manifold_specific_distribution import ( AbstractManifoldSpecificDistribution, ) -from pyrecest.backend import empty, ones class AbstractLinearDistribution(AbstractManifoldSpecificDistribution): @@ -41,13 +42,15 @@ def covariance(self): return self.covariance_numerical() def get_manifold_size(self): - return float('inf') + return float("inf") def mode(self, starting_point=None): return self.mode_numerical(starting_point) def mode_numerical(self, starting_point=None): - assert pyrecest.backend.__name__ == 'pyrecest.numpy', "Only supported for numpy backend" + assert ( + pyrecest.backend.__name__ == "pyrecest.numpy" + ), "Only supported for numpy backend" if starting_point is None: # Ensure 1-D for minimize starting_point = self.sample(1).squeeze() @@ -69,7 +72,7 @@ def sample_metropolis_hastings( burn_in: Union[int, int32, int64] = 10, skipping: Union[int, int32, int64] = 5, proposal: Callable | None = None, - start_point = None, + start_point=None, ): if proposal is None: @@ -94,23 +97,26 @@ def proposal(x): def mean_numerical(self): mu = empty(self.dim) if self.dim == 1: - mu = quad(lambda x: x * self.pdf(x), array(-float('inf')), array(float('inf')))[0] + mu = quad( + lambda x: x * self.pdf(x), array(-float("inf")), array(float("inf")) + )[0] elif self.dim == 2: mu[0] = dblquad( lambda x, y: x * self.pdf(array([x, y])), - -float('inf'), - float('inf'), - lambda _: -float('inf'), - lambda _: float('inf'), + -float("inf"), + float("inf"), + lambda _: -float("inf"), + lambda _: float("inf"), )[0] mu[1] = dblquad( lambda x, y: y * self.pdf(array([x, y])), - -float('inf'), - float('inf'), - lambda _: -float('inf'), - lambda _: float('inf'), + -float("inf"), + float("inf"), + lambda _: -float("inf"), + lambda _: float("inf"), )[0] elif self.dim == 3: + def integrand1(x, y, z): return x * self.pdf(array([x, y, z])) @@ -121,13 +127,28 @@ def integrand3(x, y, z): return z * self.pdf(array([x, y, z])) mu[0] = nquad( - integrand1, [[-float('inf'), float('inf')], [-float('inf'), float('inf')], [-float('inf'), float('inf')]] + integrand1, + [ + [-float("inf"), float("inf")], + [-float("inf"), float("inf")], + [-float("inf"), float("inf")], + ], )[0] mu[1] = nquad( - integrand2, [[-float('inf'), float('inf')], [-float('inf'), float('inf')], [-float('inf'), float('inf')]] + integrand2, + [ + [-float("inf"), float("inf")], + [-float("inf"), float("inf")], + [-float("inf"), float("inf")], + ], )[0] mu[2] = nquad( - integrand3, [[-float('inf'), float('inf')], [-float('inf'), float('inf')], [-float('inf'), float('inf')]] + integrand3, + [ + [-float("inf"), float("inf")], + [-float("inf"), float("inf")], + [-float("inf"), float("inf")], + ], )[0] else: raise ValueError( @@ -138,7 +159,9 @@ def integrand3(x, y, z): def covariance_numerical(self): mu = self.mean() if self.dim == 1: - C = quad(lambda x: (x - mu) ** 2 * self.pdf(x), -float('inf'), float('inf'))[0] + C = quad( + lambda x: (x - mu) ** 2 * self.pdf(x), -float("inf"), float("inf") + )[0] elif self.dim == 2: C = empty((2, 2)) @@ -151,10 +174,19 @@ def integrand2(x, y): def integrand3(x, y): return (y - mu[1]) ** 2 * self.pdf(array([x, y])) - C[0, 0] = nquad(integrand1, [[-float('inf'), float('inf')], [-float('inf'), float('inf')]])[0] - C[0, 1] = nquad(integrand2, [[-float('inf'), float('inf')], [-float('inf'), float('inf')]])[0] + C[0, 0] = nquad( + integrand1, + [[-float("inf"), float("inf")], [-float("inf"), float("inf")]], + )[0] + C[0, 1] = nquad( + integrand2, + [[-float("inf"), float("inf")], [-float("inf"), float("inf")]], + )[0] C[1, 0] = C[0, 1] - C[1, 1] = nquad(integrand3, [[-float('inf'), float('inf')], [-float('inf'), float('inf')]])[0] + C[1, 1] = nquad( + integrand3, + [[-float("inf"), float("inf")], [-float("inf"), float("inf")]], + )[0] else: raise NotImplementedError( "Covariance numerical not supported for this dimension." @@ -163,9 +195,9 @@ def integrand3(x, y): def integrate(self, left=None, right=None): if left is None: - left = -float('inf') * ones(self.dim) + left = -float("inf") * ones(self.dim) if right is None: - right = float('inf') * ones(self.dim) + right = float("inf") * ones(self.dim) result = self.integrate_numerically(left, right) return result @@ -173,10 +205,10 @@ def integrate(self, left=None, right=None): def integrate_numerically(self, left=None, right=None): if left is None: left = empty(self.dim) - left[:] = -float('inf') + left[:] = -float("inf") if right is None: right = empty(self.dim) - right[:] = float('inf') + right[:] = float("inf") return AbstractLinearDistribution.integrate_fun_over_domain( self.pdf, self.dim, left, right ) @@ -217,8 +249,8 @@ def get_suggested_integration_limits(self, scaling_factor=10): """ C = self.covariance() m = self.mode() - left = full((self.dim,), float('NaN')) - right = full((self.dim,), float('NaN')) + left = full((self.dim,), float("NaN")) + right = full((self.dim,), float("NaN")) for i in range(self.dim): # Change for linear dimensions left[i] = m[i] - scaling_factor * sqrt(C[i, i]) @@ -269,4 +301,4 @@ def plot_state(self, scaling_factor=1, color=(0, 0.4470, 0.7410)): mean = self.mean() plot_ellipsoid(mean, covariance, scaling_factor, color) - raise ValueError("Dimension currently not supported for plotting the state.") \ No newline at end of file + raise ValueError("Dimension currently not supported for plotting the state.") diff --git a/pyrecest/distributions/nonperiodic/custom_linear_distribution.py b/pyrecest/distributions/nonperiodic/custom_linear_distribution.py index 1966ec16..625c4619 100644 --- a/pyrecest/distributions/nonperiodic/custom_linear_distribution.py +++ b/pyrecest/distributions/nonperiodic/custom_linear_distribution.py @@ -1,15 +1,12 @@ -from pyrecest.backend import reshape -from pyrecest.backend import ndim import copy - +from pyrecest.backend import ndim, reshape, zeros from ..abstract_custom_nonperiodic_distribution import ( AbstractCustomNonPeriodicDistribution, ) from .abstract_linear_distribution import AbstractLinearDistribution -from pyrecest.backend import zeros class CustomLinearDistribution( AbstractLinearDistribution, AbstractCustomNonPeriodicDistribution @@ -50,7 +47,8 @@ def pdf(self, xs): assert xs.shape[-1] == self.dim p = self.scale_by * self.f( # To ensure 2-d for broadcasting - reshape(xs, (-1, self.dim)) - reshape(self.shift_by, (1, -1)) + reshape(xs, (-1, self.dim)) + - reshape(self.shift_by, (1, -1)) ) assert ndim(p) <= 1 return p @@ -72,4 +70,4 @@ def from_distribution(distribution): return chd def integrate(self, left=None, right=None): - return AbstractLinearDistribution.integrate(self, left, right) \ No newline at end of file + return AbstractLinearDistribution.integrate(self, left, right) diff --git a/pyrecest/distributions/nonperiodic/gaussian_distribution.py b/pyrecest/distributions/nonperiodic/gaussian_distribution.py index 7360ed6b..741c3038 100644 --- a/pyrecest/distributions/nonperiodic/gaussian_distribution.py +++ b/pyrecest/distributions/nonperiodic/gaussian_distribution.py @@ -1,11 +1,6 @@ -from pyrecest.backend import linalg -from pyrecest.backend import random -from pyrecest.backend import ndim -from pyrecest.backend import dot import copy - -from beartype import beartype +from pyrecest.backend import dot, linalg, ndim, random from scipy.linalg import cholesky from scipy.stats import multivariate_normal as mvn @@ -84,7 +79,9 @@ def marginalize_out(self, dimensions): assert all(dim <= self.dim for dim in dimensions) remaining_dims = [i for i in range(self.dim) if i not in dimensions] new_mu = self.mu[remaining_dims] - new_C = self.C[remaining_dims][:, remaining_dims] # Instead of np.ix_ for interface compatibiliy + new_C = self.C[remaining_dims][ + :, remaining_dims + ] # Instead of np.ix_ for interface compatibiliy return GaussianDistribution(new_mu, new_C, check_validity=False) def sample(self, n): @@ -100,4 +97,4 @@ def from_distribution(distribution): ) # Assuming to_gaussian method is defined in GaussianMixtureDistribution else: gaussian = GaussianDistribution(distribution.mean, distribution.covariance) - return gaussian \ No newline at end of file + return gaussian diff --git a/pyrecest/distributions/nonperiodic/gaussian_mixture.py b/pyrecest/distributions/nonperiodic/gaussian_mixture.py index 60445173..35285796 100644 --- a/pyrecest/distributions/nonperiodic/gaussian_mixture.py +++ b/pyrecest/distributions/nonperiodic/gaussian_mixture.py @@ -1,12 +1,5 @@ -from pyrecest.backend import sum -from pyrecest.backend import stack -from pyrecest.backend import ones -from pyrecest.backend import dot -from pyrecest.backend import array -import numbers - -from beartype import beartype +from pyrecest.backend import array, dot, ones, stack, sum from .abstract_linear_distribution import AbstractLinearDistribution from .gaussian_distribution import GaussianDistribution @@ -59,4 +52,4 @@ def mixture_parameters_to_gaussian_parameters( ) C = C_from_cov + C_from_means - return mu, C \ No newline at end of file + return mu, C diff --git a/pyrecest/distributions/nonperiodic/hyperrectangular_uniform_distribution.py b/pyrecest/distributions/nonperiodic/hyperrectangular_uniform_distribution.py index e4284596..03fc9609 100644 --- a/pyrecest/distributions/nonperiodic/hyperrectangular_uniform_distribution.py +++ b/pyrecest/distributions/nonperiodic/hyperrectangular_uniform_distribution.py @@ -10,4 +10,4 @@ def __init__(self, bounds): AbstractHyperrectangularDistribution.__init__(self, bounds) def get_manifold_size(self): - return AbstractHyperrectangularDistribution.get_manifold_size(self) \ No newline at end of file + return AbstractHyperrectangularDistribution.get_manifold_size(self) diff --git a/pyrecest/distributions/nonperiodic/linear_dirac_distribution.py b/pyrecest/distributions/nonperiodic/linear_dirac_distribution.py index a0c83dfc..d647645d 100644 --- a/pyrecest/distributions/nonperiodic/linear_dirac_distribution.py +++ b/pyrecest/distributions/nonperiodic/linear_dirac_distribution.py @@ -1,8 +1,5 @@ -from pyrecest.backend import reshape -from pyrecest.backend import ones -from pyrecest.backend import cov import matplotlib.pyplot as plt - +from pyrecest.backend import cov, ones, reshape from ..abstract_dirac_distribution import AbstractDiracDistribution from .abstract_linear_distribution import AbstractLinearDistribution @@ -56,4 +53,4 @@ def weighted_samples_to_mean_and_cov(samples, weights=None): deviation = samples - mean covariance = cov(deviation.T, aweights=weights, bias=True) - return mean, covariance \ No newline at end of file + return mean, covariance diff --git a/pyrecest/distributions/nonperiodic/linear_mixture.py b/pyrecest/distributions/nonperiodic/linear_mixture.py index acc27974..68898780 100644 --- a/pyrecest/distributions/nonperiodic/linear_mixture.py +++ b/pyrecest/distributions/nonperiodic/linear_mixture.py @@ -1,8 +1,6 @@ import warnings -from beartype import beartype - from ..abstract_mixture import AbstractMixture from .abstract_linear_distribution import AbstractLinearDistribution from .gaussian_distribution import GaussianDistribution @@ -27,4 +25,4 @@ def __init__(self, dists: list[AbstractLinearDistribution], w): @property def input_dim(self): - return AbstractLinearDistribution.input_dim.fget(self) \ No newline at end of file + return AbstractLinearDistribution.input_dim.fget(self) diff --git a/pyrecest/distributions/se3_cart_prod_stacked_distribution.py b/pyrecest/distributions/se3_cart_prod_stacked_distribution.py index 88951093..dff11812 100644 --- a/pyrecest/distributions/se3_cart_prod_stacked_distribution.py +++ b/pyrecest/distributions/se3_cart_prod_stacked_distribution.py @@ -1,5 +1,3 @@ - - from .abstract_se3_distribution import AbstractSE3Distribution from .cart_prod.cart_prod_stacked_distribution import CartProdStackedDistribution @@ -18,7 +16,7 @@ def marginalize_periodic(self): return self.dists[1] def get_manifold_size(self): - return float('inf') + return float("inf") def pdf(self, xs): - return CartProdStackedDistribution.pdf(self, xs) \ No newline at end of file + return CartProdStackedDistribution.pdf(self, xs) diff --git a/pyrecest/distributions/se3_dirac_distribution.py b/pyrecest/distributions/se3_dirac_distribution.py index 6beeecec..7c9530eb 100644 --- a/pyrecest/distributions/se3_dirac_distribution.py +++ b/pyrecest/distributions/se3_dirac_distribution.py @@ -1,6 +1,5 @@ from pyrecest.backend import ones - from .abstract_se3_distribution import AbstractSE3Distribution from .cart_prod.lin_hypersphere_cart_prod_dirac_distribution import ( LinHypersphereCartProdDiracDistribution, @@ -27,7 +26,7 @@ def mean(self): throughout manifolds. :return: The mean of the distribution. - :rtype: + :rtype: """ m = self.hybrid_mean() return m @@ -45,4 +44,4 @@ def from_distribution(distribution, n_particles): distribution.sample(n_particles), 1 / n_particles * ones(n_particles), ) - return ddist \ No newline at end of file + return ddist diff --git a/pyrecest/evaluation/__init__.py b/pyrecest/evaluation/__init__.py index b1206122..7f61bdf5 100644 --- a/pyrecest/evaluation/__init__.py +++ b/pyrecest/evaluation/__init__.py @@ -34,4 +34,4 @@ "evaluate_for_file", "evaluate_for_simulation_config", "evaluate_for_variables", -] \ No newline at end of file +] diff --git a/pyrecest/evaluation/check_and_fix_config.py b/pyrecest/evaluation/check_and_fix_config.py index 6a4dac8e..b0589656 100644 --- a/pyrecest/evaluation/check_and_fix_config.py +++ b/pyrecest/evaluation/check_and_fix_config.py @@ -90,4 +90,4 @@ def check_and_fix_config(simulation_param): simulation_param["initial_prior"], AbstractManifoldSpecificDistribution ) - return simulation_param \ No newline at end of file + return simulation_param diff --git a/pyrecest/evaluation/configure_for_filter.py b/pyrecest/evaluation/configure_for_filter.py index 6219ebcc..1d3558a0 100644 --- a/pyrecest/evaluation/configure_for_filter.py +++ b/pyrecest/evaluation/configure_for_filter.py @@ -149,4 +149,4 @@ def prediction_routine(curr_input): # type: ignore[misc] prediction_routine, likelihood_for_filter, meas_noise_for_filter, - ) \ No newline at end of file + ) diff --git a/pyrecest/evaluation/determine_all_deviations.py b/pyrecest/evaluation/determine_all_deviations.py index 84f59c34..8cc90242 100644 --- a/pyrecest/evaluation/determine_all_deviations.py +++ b/pyrecest/evaluation/determine_all_deviations.py @@ -1,13 +1,8 @@ -from pyrecest.backend import sum -from pyrecest.backend import ndim -from pyrecest.backend import any -from pyrecest.backend import empty import warnings from typing import Callable -import numpy as np -from pyrecest.backend import isinf -from beartype import beartype +import numpy as np +from pyrecest.backend import any, empty, isinf, ndim, sum def determine_all_deviations( @@ -49,7 +44,7 @@ def determine_all_deviations( ) else: warnings.warn("No estimate for this filter, setting error to inf.") - all_deviations_last_mat[config_no][run] = float('inf') + all_deviations_last_mat[config_no][run] = float("inf") if any(isinf(all_deviations_last_mat[config_no])): print( @@ -58,4 +53,4 @@ def determine_all_deviations( "times. Check if this is plausible." ) - return all_deviations_last_mat \ No newline at end of file + return all_deviations_last_mat diff --git a/pyrecest/evaluation/eot_shape_database.py b/pyrecest/evaluation/eot_shape_database.py index 4934caa6..7c47c402 100644 --- a/pyrecest/evaluation/eot_shape_database.py +++ b/pyrecest/evaluation/eot_shape_database.py @@ -1,11 +1,6 @@ from math import pi -from pyrecest.backend import random -from pyrecest.backend import sin -from pyrecest.backend import linspace -from pyrecest.backend import cos -from pyrecest.backend import array -from pyrecest.backend import empty +from pyrecest.backend import array, cos, empty, linspace, random, sin from shapely.geometry import LineString, MultiLineString, Point, Polygon from shapely.ops import unary_union @@ -223,4 +218,4 @@ def __new__(cls, scaling_factor=1): polygon = super().__new__(cls, shell=zip(x, y), holes=None) # nosec polygon.__class__ = cls - return polygon \ No newline at end of file + return polygon diff --git a/pyrecest/evaluation/evaluate_for_file.py b/pyrecest/evaluation/evaluate_for_file.py index 67f85f89..c86af532 100644 --- a/pyrecest/evaluation/evaluate_for_file.py +++ b/pyrecest/evaluation/evaluate_for_file.py @@ -1,11 +1,8 @@ -from numpy import ones -from numpy import concatenate -from numpy import zeros -import numpy as np import os from typing import Any - +import numpy as np +from numpy import concatenate, ones, zeros from .evaluate_for_variables import evaluate_for_variables @@ -23,7 +20,7 @@ def evaluate_for_file( tolerate_failure: bool = False, auto_warning_on_off: bool = False, # jscpd:ignore-end - ): +): data = np.load(input_file_name, allow_pickle=True).item() if "name" not in scenario_config: @@ -48,9 +45,7 @@ def evaluate_for_file( ) scenario_config.setdefault( "apply_sys_noise_times", - concatenate( - [ones(scenario_config["n_timesteps"] - 1, dtype=bool), [False]] - ), + concatenate([ones(scenario_config["n_timesteps"] - 1, dtype=bool), [False]]), ) return evaluate_for_variables( @@ -64,4 +59,4 @@ def evaluate_for_file( extract_all_point_estimates=extract_all_point_estimates, tolerate_failure=tolerate_failure, auto_warning_on_off=auto_warning_on_off, - ) \ No newline at end of file + ) diff --git a/pyrecest/evaluation/evaluate_for_simulation_config.py b/pyrecest/evaluation/evaluate_for_simulation_config.py index 6b9972c7..54128a8f 100644 --- a/pyrecest/evaluation/evaluate_for_simulation_config.py +++ b/pyrecest/evaluation/evaluate_for_simulation_config.py @@ -2,8 +2,6 @@ from typing import Any, Optional -from beartype import beartype - from .evaluate_for_variables import evaluate_for_variables from .generate_simulated_scenarios import generate_simulated_scenarios from .simulation_database import simulation_database @@ -79,4 +77,4 @@ def get_all_seeds(n_runs: int, seed_input=None, consecutive_seed: bool = True): "The number of seeds provided must be either 1 or equal to the number of runs." ) - return all_seeds \ No newline at end of file + return all_seeds diff --git a/pyrecest/evaluation/evaluate_for_variables.py b/pyrecest/evaluation/evaluate_for_variables.py index ce21762e..2c821f03 100644 --- a/pyrecest/evaluation/evaluate_for_variables.py +++ b/pyrecest/evaluation/evaluate_for_variables.py @@ -2,8 +2,6 @@ import os from typing import Any - - from .iterate_configs_and_runs import iterate_configs_and_runs @@ -78,4 +76,4 @@ def evaluate_for_variables( scenario_config, # pylint: disable=R0801 filter_configs, # pylint: disable=R0801 evaluation_config, # pylint: disable=R0801 - ) \ No newline at end of file + ) diff --git a/pyrecest/evaluation/generate_groundtruth.py b/pyrecest/evaluation/generate_groundtruth.py index 4da7193b..0e327a7f 100644 --- a/pyrecest/evaluation/generate_groundtruth.py +++ b/pyrecest/evaluation/generate_groundtruth.py @@ -1,9 +1,5 @@ -from numpy import squeeze -from numpy import ndim -from numpy import empty -from numpy import empty_like -from numpy import atleast_2d import numpy as np +from numpy import atleast_2d, empty, empty_like, ndim, squeeze # pylint: disable=too-many-branches @@ -93,4 +89,4 @@ def generate_groundtruth(simulation_param, x0=None): for t in range(simulation_param["n_timesteps"]): groundtruth[t] = squeeze(groundtruth[t]) - return groundtruth \ No newline at end of file + return groundtruth diff --git a/pyrecest/evaluation/generate_measurements.py b/pyrecest/evaluation/generate_measurements.py index 440734b8..aab5c926 100644 --- a/pyrecest/evaluation/generate_measurements.py +++ b/pyrecest/evaluation/generate_measurements.py @@ -1,16 +1,7 @@ from math import pi -from numpy import random -from numpy import tile -from numpy import sum -from numpy import squeeze -from numpy import shape -from numpy import mod -from numpy import dot -from numpy import empty -from numpy import zeros -import numpy as np -from beartype import beartype +import numpy as np +from numpy import dot, empty, mod, random, shape, squeeze, sum, tile, zeros from pyrecest.distributions import ( AbstractHypertoroidalDistribution, GaussianDistribution, @@ -72,7 +63,9 @@ def generate_measurements(groundtruth, simulation_config): elif groundtruth[0].shape[-1] == 3: curr_shape = rotate( translate( - target_shape, groundtruth[0][..., 1], yoff=groundtruth[0][..., 2] + target_shape, + groundtruth[0][..., 1], + yoff=groundtruth[0][..., 2], ), angle=groundtruth[0][..., 0], origin="centroid", @@ -127,7 +120,7 @@ def generate_measurements(groundtruth, simulation_config): for t in range(simulation_config["n_timesteps"]): n_meas_at_t = sum(n_observations[t, :]) - measurements[t] = float('NaN') * zeros( + measurements[t] = float("NaN") * zeros( (simulation_config["meas_matrix_for_each_target"].shape[0], n_meas_at_t) ) @@ -198,4 +191,4 @@ def generate_n_measurements_PPP(area: float, intensity_lambda: float) -> int: # Compute the expected number of points expected_num_points = intensity_lambda * area # Get the actual number of points to generate as a realization from a Poisson distribution - return poisson.rvs(expected_num_points) \ No newline at end of file + return poisson.rvs(expected_num_points) diff --git a/pyrecest/evaluation/generate_simulated_scenarios.py b/pyrecest/evaluation/generate_simulated_scenarios.py index c372cd11..30d58e9e 100644 --- a/pyrecest/evaluation/generate_simulated_scenarios.py +++ b/pyrecest/evaluation/generate_simulated_scenarios.py @@ -1,6 +1,5 @@ -from numpy import random, empty import numpy as np - +from numpy import empty, random from .check_and_fix_config import check_and_fix_config from .generate_groundtruth import generate_groundtruth @@ -39,4 +38,4 @@ def generate_simulated_scenarios( groundtruths[run, :], simulation_params ) - return groundtruths, measurements \ No newline at end of file + return groundtruths, measurements diff --git a/pyrecest/evaluation/get_axis_label.py b/pyrecest/evaluation/get_axis_label.py index dfa94054..6eebac08 100644 --- a/pyrecest/evaluation/get_axis_label.py +++ b/pyrecest/evaluation/get_axis_label.py @@ -36,4 +36,4 @@ def get_axis_label(manifold_name): else: raise ValueError("Mode not recognized") - return error_label \ No newline at end of file + return error_label diff --git a/pyrecest/evaluation/get_distance_function.py b/pyrecest/evaluation/get_distance_function.py index 2b0ba634..5cd9b0b8 100644 --- a/pyrecest/evaluation/get_distance_function.py +++ b/pyrecest/evaluation/get_distance_function.py @@ -1,7 +1,5 @@ -from pyrecest.backend import dot -from pyrecest.backend import arccos - from numpy.linalg import norm +from pyrecest.backend import arccos, dot from pyrecest.distributions import AbstractHypertoroidalDistribution @@ -46,9 +44,7 @@ def distance_function(x1, x2): elif "se3bounded" in manifold_name: def distance_function(x1, x2): - return min( - arccos(dot(x1[:4], x2[:4])), arccos(dot(x1[:4], -x2[:4])) - ) + return min(arccos(dot(x1[:4], x2[:4])), arccos(dot(x1[:4], -x2[:4]))) elif ( "euclidean" in manifold_name or "Euclidean" in manifold_name @@ -68,4 +64,4 @@ def distance_function(x1, x2): else: raise ValueError("Mode not recognized") - return distance_function \ No newline at end of file + return distance_function diff --git a/pyrecest/evaluation/get_extract_mean.py b/pyrecest/evaluation/get_extract_mean.py index 64539bf3..17b7b178 100644 --- a/pyrecest/evaluation/get_extract_mean.py +++ b/pyrecest/evaluation/get_extract_mean.py @@ -48,4 +48,4 @@ def extract_mean(_): else: raise ValueError("Mode not recognized") - return extract_mean \ No newline at end of file + return extract_mean diff --git a/pyrecest/evaluation/group_results_by_filter.py b/pyrecest/evaluation/group_results_by_filter.py index 35781f7f..f9e852a4 100644 --- a/pyrecest/evaluation/group_results_by_filter.py +++ b/pyrecest/evaluation/group_results_by_filter.py @@ -20,4 +20,4 @@ def group_results_by_filter(data): # Initialize the entry in the output_dict with lists for each value output_dict[name] = {k: [v] for k, v in entry_values.items()} - return output_dict \ No newline at end of file + return output_dict diff --git a/pyrecest/evaluation/iterate_configs_and_runs.py b/pyrecest/evaluation/iterate_configs_and_runs.py index 94aa0ad1..450cb68e 100644 --- a/pyrecest/evaluation/iterate_configs_and_runs.py +++ b/pyrecest/evaluation/iterate_configs_and_runs.py @@ -22,7 +22,7 @@ def iterate_configs_and_runs( ) raise NotImplementedError("This is not implemented yet.") - n_configs = sum(np.size(f["parameter"]) for f in filter_configs) + n_configs = sum((f["parameter"]).shape[0] for f in filter_configs) n_runs = groundtruths.shape[0] run_times = empty((n_configs, n_runs)) run_failed = zeros((n_configs, n_runs), dtype=bool) diff --git a/pyrecest/evaluation/perform_predict_update_cycles.py b/pyrecest/evaluation/perform_predict_update_cycles.py index ef255d5b..d2e48576 100644 --- a/pyrecest/evaluation/perform_predict_update_cycles.py +++ b/pyrecest/evaluation/perform_predict_update_cycles.py @@ -1,11 +1,7 @@ -from pyrecest.backend import atleast_2d -from pyrecest.backend import squeeze -from pyrecest.backend import array -from pyrecest.backend import empty import time import warnings - +from pyrecest.backend import array, atleast_2d, squeeze from .configure_for_filter import configure_for_filter @@ -92,4 +88,4 @@ def perform_predict_update_cycles( else: last_estimate = filter_obj.get_point_estimate() - return last_filter_state, time_elapsed, last_estimate, all_estimates \ No newline at end of file + return last_filter_state, time_elapsed, last_estimate, all_estimates diff --git a/pyrecest/evaluation/plot_results.py b/pyrecest/evaluation/plot_results.py index a60901dc..4e8bc0ac 100644 --- a/pyrecest/evaluation/plot_results.py +++ b/pyrecest/evaluation/plot_results.py @@ -1,13 +1,7 @@ -from pyrecest.backend import shape -from pyrecest.backend import ones -from pyrecest.backend import isnan -from pyrecest.backend import array -from pyrecest.backend import any import warnings import matplotlib.pyplot as plt - -from beartype import beartype +from pyrecest.backend import any, array, isnan, ones, shape from .get_axis_label import get_axis_label from .group_results_by_filter import group_results_by_filter @@ -79,11 +73,7 @@ def plot_results( # Plot errors plt.figure(0) - if ( - params[0] is not None - and not any(isnan(params)) - and params.shape[0] > 1 - ): + if params[0] is not None and not any(isnan(params)) and params.shape[0] > 1: if plot_stds: plt.plot( params, @@ -118,11 +108,7 @@ def plot_results( # Plot times plt.figure(1) - if ( - params[0] is not None - and not any(isnan(params)) - and params.shape[0] > 1 - ): + if params[0] is not None and not any(isnan(params)) and params.shape[0] > 1: plt.plot( params, times_factor * times_mean, @@ -148,11 +134,7 @@ def plot_results( # Plot errors over time plt.figure(2) - if ( - params[0] is not None - and not any(isnan(params)) - and params.shape[0] > 1 - ): + if params[0] is not None and not any(isnan(params)) and params.shape[0] > 1: plt.plot( times_factor * times_mean, errors_mean, @@ -292,4 +274,4 @@ def apply_log_scale_to_axes(axes_list, log_array): ax.set_xscale("log") if log_array[1, plot_idx]: # Check if y-axis should be log scale - ax.set_yscale("log") \ No newline at end of file + ax.set_yscale("log") diff --git a/pyrecest/evaluation/simulation_database.py b/pyrecest/evaluation/simulation_database.py index cad29c8b..b682a592 100644 --- a/pyrecest/evaluation/simulation_database.py +++ b/pyrecest/evaluation/simulation_database.py @@ -1,9 +1,7 @@ -from pyrecest.backend import eye, zeros import warnings from typing import Optional - -from beartype import beartype +from pyrecest.backend import eye, zeros from pyrecest.distributions import GaussianDistribution @@ -27,17 +25,11 @@ def simulation_database( elif scenario_name == "R2randomWalk": simulation_param["manifold"] = "Euclidean" simulation_param["n_timesteps"] = 10 - simulation_param["initial_prior"] = GaussianDistribution( - zeros(2), 0.5 * eye(2) - ) - simulation_param["meas_noise"] = GaussianDistribution( - zeros(2), 0.5 * eye(2) - ) - simulation_param["sys_noise"] = GaussianDistribution( - zeros(2), 0.5 * eye(2) - ) + simulation_param["initial_prior"] = GaussianDistribution(zeros(2), 0.5 * eye(2)) + simulation_param["meas_noise"] = GaussianDistribution(zeros(2), 0.5 * eye(2)) + simulation_param["sys_noise"] = GaussianDistribution(zeros(2), 0.5 * eye(2)) simulation_param["gen_next_state_without_noise_is_vectorized"] = True else: raise ValueError("Scenario not recognized.") - return simulation_param \ No newline at end of file + return simulation_param diff --git a/pyrecest/evaluation/summarize_filter_results.py b/pyrecest/evaluation/summarize_filter_results.py index 5b400ec1..77af38b2 100644 --- a/pyrecest/evaluation/summarize_filter_results.py +++ b/pyrecest/evaluation/summarize_filter_results.py @@ -1,9 +1,6 @@ -from pyrecest.backend import sum -from pyrecest.backend import std -from pyrecest.backend import mean import warnings - +from pyrecest.backend import mean, std, sum from .determine_all_deviations import determine_all_deviations from .get_distance_function import get_distance_function @@ -57,4 +54,4 @@ def summarize_filter_results( d["time_mean"] = curr_time d["failure_rate"] = curr_fail_rate - return results_summarized \ No newline at end of file + return results_summarized diff --git a/pyrecest/filters/__init__.py b/pyrecest/filters/__init__.py index 04a15427..479c6b9b 100644 --- a/pyrecest/filters/__init__.py +++ b/pyrecest/filters/__init__.py @@ -18,4 +18,4 @@ "HypertoroidalParticleFilter", "KalmanFilter", "EuclideanParticleFilter", -] \ No newline at end of file +] diff --git a/pyrecest/filters/abstract_circular_filter.py b/pyrecest/filters/abstract_circular_filter.py index 51871795..5007a63c 100644 --- a/pyrecest/filters/abstract_circular_filter.py +++ b/pyrecest/filters/abstract_circular_filter.py @@ -5,4 +5,4 @@ class AbstractCircularFilter(AbstractHypertoroidalFilter): """ This class represents an abstract circular filter. While it currently does not add any functionality to its superclass, it serves as a basis for creating more specific types of circular filters. - """ \ No newline at end of file + """ diff --git a/pyrecest/filters/abstract_euclidean_filter.py b/pyrecest/filters/abstract_euclidean_filter.py index 63900947..9701fe41 100644 --- a/pyrecest/filters/abstract_euclidean_filter.py +++ b/pyrecest/filters/abstract_euclidean_filter.py @@ -7,4 +7,4 @@ class AbstractEuclideanFilter(AbstractManifoldSpecificFilter): def get_point_estimate(self): est = self.filter_state.mean() - return est \ No newline at end of file + return est diff --git a/pyrecest/filters/abstract_extended_object_tracker.py b/pyrecest/filters/abstract_extended_object_tracker.py index 464bbf03..407e5904 100644 --- a/pyrecest/filters/abstract_extended_object_tracker.py +++ b/pyrecest/filters/abstract_extended_object_tracker.py @@ -76,4 +76,4 @@ def get_point_estimate_extent(self, flatten_matrix=False): Returns: - A matrix or vector representing the estimated extent. - """ \ No newline at end of file + """ diff --git a/pyrecest/filters/abstract_filter.py b/pyrecest/filters/abstract_filter.py index a7ba4e08..8c0c9af6 100644 --- a/pyrecest/filters/abstract_filter.py +++ b/pyrecest/filters/abstract_filter.py @@ -33,4 +33,4 @@ def dim(self) -> int: def plot_filter_state(self): """Plot the filter state.""" - self.filter_state.plot() \ No newline at end of file + self.filter_state.plot() diff --git a/pyrecest/filters/abstract_filter_type.py b/pyrecest/filters/abstract_filter_type.py index 3b991428..f47c7556 100644 --- a/pyrecest/filters/abstract_filter_type.py +++ b/pyrecest/filters/abstract_filter_type.py @@ -2,4 +2,4 @@ class AbstractFilterType(AbstractFilter): - pass \ No newline at end of file + pass diff --git a/pyrecest/filters/abstract_hypercylindrical_filter.py b/pyrecest/filters/abstract_hypercylindrical_filter.py index 7beb0067..8b791857 100644 --- a/pyrecest/filters/abstract_hypercylindrical_filter.py +++ b/pyrecest/filters/abstract_hypercylindrical_filter.py @@ -3,4 +3,4 @@ class AbstractHypercylindricalFilter(AbstractLinPeriodicFilter): def get_point_estimate(self): - return self.filter_state.hybrid_mean() \ No newline at end of file + return self.filter_state.hybrid_mean() diff --git a/pyrecest/filters/abstract_hyperhemispherical_filter.py b/pyrecest/filters/abstract_hyperhemispherical_filter.py index 675b4b86..5d66ec82 100644 --- a/pyrecest/filters/abstract_hyperhemispherical_filter.py +++ b/pyrecest/filters/abstract_hyperhemispherical_filter.py @@ -4,4 +4,4 @@ class AbstractHyperhemisphericalFilter(AbstractManifoldSpecificFilter): """ Abstract class representing a hyperhemispherical filter. - """ \ No newline at end of file + """ diff --git a/pyrecest/filters/abstract_hypersphere_subset_filter.py b/pyrecest/filters/abstract_hypersphere_subset_filter.py index e5623099..9ce61002 100644 --- a/pyrecest/filters/abstract_hypersphere_subset_filter.py +++ b/pyrecest/filters/abstract_hypersphere_subset_filter.py @@ -2,4 +2,4 @@ class AbstractHypersphereSubsetFilter(AbstractManifoldSpecificFilter): - pass \ No newline at end of file + pass diff --git a/pyrecest/filters/abstract_hyperspherical_filter.py b/pyrecest/filters/abstract_hyperspherical_filter.py index c842ea3f..d8c96a3b 100644 --- a/pyrecest/filters/abstract_hyperspherical_filter.py +++ b/pyrecest/filters/abstract_hyperspherical_filter.py @@ -2,4 +2,4 @@ class AbstractHypersphericalFilter(AbstractManifoldSpecificFilter): - pass \ No newline at end of file + pass diff --git a/pyrecest/filters/abstract_hypertoroidal_filter.py b/pyrecest/filters/abstract_hypertoroidal_filter.py index f0815bc7..c2c19cdc 100644 --- a/pyrecest/filters/abstract_hypertoroidal_filter.py +++ b/pyrecest/filters/abstract_hypertoroidal_filter.py @@ -1,7 +1,5 @@ import copy - - from .abstract_manifold_specific_filter import AbstractManifoldSpecificFilter @@ -24,4 +22,4 @@ def get_point_estimate(self): :return: The mean direction of the filter state. """ - return self.filter_state.mean_direction() \ No newline at end of file + return self.filter_state.mean_direction() diff --git a/pyrecest/filters/abstract_lin_bounded_filter.py b/pyrecest/filters/abstract_lin_bounded_filter.py index 60d148e2..515fe37a 100644 --- a/pyrecest/filters/abstract_lin_bounded_filter.py +++ b/pyrecest/filters/abstract_lin_bounded_filter.py @@ -2,4 +2,4 @@ class AbstractLinBoundedFilter(AbstractManifoldSpecificFilter): - pass \ No newline at end of file + pass diff --git a/pyrecest/filters/abstract_lin_periodic_filter.py b/pyrecest/filters/abstract_lin_periodic_filter.py index 2e465906..fc6aebee 100644 --- a/pyrecest/filters/abstract_lin_periodic_filter.py +++ b/pyrecest/filters/abstract_lin_periodic_filter.py @@ -2,4 +2,4 @@ class AbstractLinPeriodicFilter(AbstractLinBoundedFilter): - pass \ No newline at end of file + pass diff --git a/pyrecest/filters/abstract_manifold_specific_filter.py b/pyrecest/filters/abstract_manifold_specific_filter.py index cb5bc243..c9a1f853 100644 --- a/pyrecest/filters/abstract_manifold_specific_filter.py +++ b/pyrecest/filters/abstract_manifold_specific_filter.py @@ -2,4 +2,4 @@ class AbstractManifoldSpecificFilter(AbstractFilter): - pass \ No newline at end of file + pass diff --git a/pyrecest/filters/abstract_multitarget_tracker.py b/pyrecest/filters/abstract_multitarget_tracker.py index 3a8343f9..0d158964 100644 --- a/pyrecest/filters/abstract_multitarget_tracker.py +++ b/pyrecest/filters/abstract_multitarget_tracker.py @@ -30,4 +30,4 @@ def get_point_estimate(self, flatten_vector=False): @abstractmethod def get_number_of_targets(self): - pass \ No newline at end of file + pass diff --git a/pyrecest/filters/abstract_nearest_neighbor_tracker.py b/pyrecest/filters/abstract_nearest_neighbor_tracker.py index 788e6a87..f0141c11 100644 --- a/pyrecest/filters/abstract_nearest_neighbor_tracker.py +++ b/pyrecest/filters/abstract_nearest_neighbor_tracker.py @@ -1,10 +1,8 @@ -from pyrecest.backend import ndim -from pyrecest.backend import empty import copy import warnings from abc import abstractmethod - +from pyrecest.backend import empty, ndim from pyrecest.distributions import GaussianDistribution from .abstract_euclidean_filter import AbstractEuclideanFilter @@ -143,9 +141,9 @@ def get_point_estimate(self, flatten_vector=False): point_ests = None else: point_ests = empty((self.dim, num_targets)) - point_ests[:] = float('NaN') + point_ests[:] = float("NaN") for i in range(num_targets): point_ests[:, i] = self.filter_bank[i].get_point_estimate() if flatten_vector: point_ests = point_ests.flatten() - return point_ests \ No newline at end of file + return point_ests diff --git a/pyrecest/filters/abstract_particle_filter.py b/pyrecest/filters/abstract_particle_filter.py index bfd6d2e6..e1f0d2b6 100644 --- a/pyrecest/filters/abstract_particle_filter.py +++ b/pyrecest/filters/abstract_particle_filter.py @@ -1,13 +1,6 @@ -from pyrecest.backend import random -from pyrecest.backend import sum -from pyrecest.backend import ones_like -from pyrecest.backend import ones -from pyrecest.backend import ndim from collections.abc import Callable -from pyrecest.backend import zeros - -from beartype import beartype +from pyrecest.backend import ndim, ones_like, random, sum, zeros from pyrecest.distributions.abstract_manifold_specific_distribution import ( AbstractManifoldSpecificDistribution, ) @@ -65,12 +58,13 @@ def predict_nonlinear_nonadditive(self, f, samples, weights): def update_identity( self, meas_noise, measurement, shift_instead_of_add: bool = True ): - assert measurement is None or measurement.shape == (meas_noise.dim,) or meas_noise.dim == 1 and measurement.shape == () assert ( - ndim(measurement) == 1 - or ndim(measurement) == 0 - and meas_noise.dim == 1 + measurement is None + or measurement.shape == (meas_noise.dim,) + or meas_noise.dim == 1 + and measurement.shape == () ) + assert ndim(measurement) == 1 or ndim(measurement) == 0 and meas_noise.dim == 1 if not shift_instead_of_add: raise NotImplementedError() @@ -94,7 +88,5 @@ def update_nonlinear_using_likelihood(self, likelihood, measurement=None): ) def association_likelihood(self, likelihood: AbstractManifoldSpecificDistribution): - likelihood_val = sum( - likelihood.pdf(self.filter_state.d) * self.filter_state.w - ) - return likelihood_val \ No newline at end of file + likelihood_val = sum(likelihood.pdf(self.filter_state.d) * self.filter_state.w) + return likelihood_val diff --git a/pyrecest/filters/abstract_se2_filter.py b/pyrecest/filters/abstract_se2_filter.py index eacf6294..113083c1 100644 --- a/pyrecest/filters/abstract_se2_filter.py +++ b/pyrecest/filters/abstract_se2_filter.py @@ -2,4 +2,4 @@ class AbstractSE2Filter(AbstractManifoldSpecificFilter): - """This class represents an abstract filter for the SE(2) manifold.""" \ No newline at end of file + """This class represents an abstract filter for the SE(2) manifold.""" diff --git a/pyrecest/filters/abstract_toroidal_filter.py b/pyrecest/filters/abstract_toroidal_filter.py index 72a028b0..8407b6eb 100644 --- a/pyrecest/filters/abstract_toroidal_filter.py +++ b/pyrecest/filters/abstract_toroidal_filter.py @@ -2,4 +2,4 @@ class AbstractToroidalFilter(AbstractHypertoroidalFilter): - pass \ No newline at end of file + pass diff --git a/pyrecest/filters/abstract_tracker_with_logging.py b/pyrecest/filters/abstract_tracker_with_logging.py index 1ee868d0..360c4b95 100644 --- a/pyrecest/filters/abstract_tracker_with_logging.py +++ b/pyrecest/filters/abstract_tracker_with_logging.py @@ -1,9 +1,6 @@ -from pyrecest.backend import full -from pyrecest.backend import hstack -from pyrecest.backend import array from abc import ABC - +from pyrecest.backend import array, full, hstack class AbstractTrackerWithLogging(ABC): @@ -25,13 +22,16 @@ def _store_estimates(self, curr_ests, estimates_over_time): if n <= m: curr_ests = np.pad( - curr_ests, ((0, m - n), (0, 0)), mode="constant", constant_values=float('NaN') + curr_ests, + ((0, m - n), (0, 0)), + mode="constant", + constant_values=float("NaN"), ) estimates_over_time = hstack((estimates_over_time, curr_ests)) else: - estimates_over_time_new = full((n, t + 1), float('NaN')) + estimates_over_time_new = full((n, t + 1), float("NaN")) estimates_over_time_new[:m, :t] = estimates_over_time estimates_over_time_new[:, -1] = curr_ests.flatten() estimates_over_time = estimates_over_time_new - return estimates_over_time \ No newline at end of file + return estimates_over_time diff --git a/pyrecest/filters/circular_particle_filter.py b/pyrecest/filters/circular_particle_filter.py index eac07c2e..fdef6efe 100644 --- a/pyrecest/filters/circular_particle_filter.py +++ b/pyrecest/filters/circular_particle_filter.py @@ -1,9 +1,6 @@ from typing import Union -from pyrecest.backend import sum -from pyrecest.backend import float64 -from pyrecest.backend import int64 -from pyrecest.backend import int32 +from pyrecest.backend import float64, int32, int64, sum from .hypertoroidal_particle_filter import HypertoroidalParticleFilter @@ -25,7 +22,5 @@ def compute_association_likelihood(self, likelihood) -> float64: :param likelihood: likelihood object with a PDF method :return: association likelihood value """ - likelihood_val = sum( - likelihood.pdf(self.filter_state.d) * self.filter_state.w - ) - return likelihood_val \ No newline at end of file + likelihood_val = sum(likelihood.pdf(self.filter_state.d) * self.filter_state.w) + return likelihood_val diff --git a/pyrecest/filters/euclidean_particle_filter.py b/pyrecest/filters/euclidean_particle_filter.py index 8cf955e8..aa795515 100644 --- a/pyrecest/filters/euclidean_particle_filter.py +++ b/pyrecest/filters/euclidean_particle_filter.py @@ -1,12 +1,8 @@ -from typing import Union -from pyrecest.backend import int64 -from pyrecest.backend import int32 -from pyrecest.backend import zeros import copy from collections.abc import Callable +from typing import Union - -from beartype import beartype +from pyrecest.backend import int32, int64, zeros from ..distributions.nonperiodic.abstract_linear_distribution import ( AbstractLinearDistribution, @@ -69,4 +65,4 @@ def predict_nonlinear( """Predict for nonlinear system model.""" AbstractParticleFilter.predict_nonlinear( self, f, noise_distribution, function_is_vectorized, shift_instead_of_add - ) \ No newline at end of file + ) diff --git a/pyrecest/filters/global_nearest_neighbor.py b/pyrecest/filters/global_nearest_neighbor.py index c3c256f9..5da0a40b 100644 --- a/pyrecest/filters/global_nearest_neighbor.py +++ b/pyrecest/filters/global_nearest_neighbor.py @@ -1,11 +1,4 @@ -from pyrecest.backend import full -from pyrecest.backend import stack -from pyrecest.backend import squeeze -from pyrecest.backend import repeat -from pyrecest.backend import any -from pyrecest.backend import all -from pyrecest.backend import empty - +from pyrecest.backend import all, any, empty, full, repeat, squeeze, stack from scipy.optimize import linear_sum_assignment from scipy.spatial.distance import cdist from scipy.stats import chi2 @@ -50,9 +43,7 @@ def find_association( assert cov_mats_meas.ndim == 2 or cov_mats_meas.shape[2] == n_meas all_gaussians = [filter.filter_state for filter in self.filter_bank] all_means_prior = stack([gaussian.mu for gaussian in all_gaussians], axis=1) - all_cov_mats_prior = stack( - [gaussian.C for gaussian in all_gaussians], axis=2 - ) + all_cov_mats_prior = stack([gaussian.C for gaussian in all_gaussians], axis=2) if self.association_param["distance_metric_pos"].lower() == "euclidean": dists = cdist( @@ -124,9 +115,7 @@ def find_association( ) dists[i, j] = squeeze( cdist( - (measurement_matrix @ all_means_prior[:, i]).T[ - None - ], + (measurement_matrix @ all_means_prior[:, i]).T[None], measurements[:, j].T[None], "mahalanobis", VI=curr_cov_mahalanobis, @@ -152,4 +141,4 @@ def find_association( "GNN: No measurement was within gating threshold for at least one target." ) - return association \ No newline at end of file + return association diff --git a/pyrecest/filters/hypertoroidal_particle_filter.py b/pyrecest/filters/hypertoroidal_particle_filter.py index ec9a36f5..fff92044 100644 --- a/pyrecest/filters/hypertoroidal_particle_filter.py +++ b/pyrecest/filters/hypertoroidal_particle_filter.py @@ -1,21 +1,19 @@ -from math import pi -from pyrecest.backend import random -from typing import Union -from pyrecest.backend import tile -from pyrecest.backend import sum -from pyrecest.backend import squeeze -from pyrecest.backend import mod -from pyrecest.backend import linspace -from pyrecest.backend import arange -from pyrecest.backend import int64 -from pyrecest.backend import int32 -from pyrecest.backend import zeros_like -from pyrecest.backend import arange import copy from collections.abc import Callable +from math import pi +from typing import Union - -from beartype import beartype +from pyrecest.backend import ( + arange, + int32, + int64, + linspace, + mod, + random, + sum, + tile, + zeros_like, +) from pyrecest.distributions import ( AbstractHypertoroidalDistribution, HypertoroidalDiracDistribution, @@ -34,14 +32,15 @@ def __init__( n_particles: Union[int, int32, int64], dim: Union[int, int32, int64], ): - if dim == 1: # Prevents ambiguities if a vector is of size (dim,) or (n,) (for dim=1) - filter_state = CircularDiracDistribution(linspace(0.0, 2.0 * pi, num = n_particles, endpoint=False)) + filter_state = CircularDiracDistribution( + linspace(0.0, 2.0 * pi, num=n_particles, endpoint=False) + ) else: filter_state = HypertoroidalDiracDistribution( tile( - arange(0.0, 2.0*pi, 2.0*pi/n_particles), (dim, 1) + arange(0.0, 2.0 * pi, 2.0 * pi / n_particles), (dim, 1) ).T.squeeze(), dim=dim, ) @@ -73,11 +72,8 @@ def predict_nonlinear( self.filter_state.d += noise.squeeze() self.filter_state.d = mod(self.filter_state.d, 2.0 * pi) - def predict_nonlinear_nonadditive( - self, f: Callable, samples, weights): - assert ( - samples.shape == weights.size - ), "samples and weights must match in size" + def predict_nonlinear_nonadditive(self, f: Callable, samples, weights): + assert samples.shape == weights.size, "samples and weights must match in size" weights /= sum(weights) n = self.filter_state.shape[0] @@ -85,4 +81,4 @@ def predict_nonlinear_nonadditive( d = zeros_like(self.filter_state) for i in range(n): d[i, :] = f(self.filter_state[i, :], samples[noise_ids[i, :]]) - self.filter_state = d \ No newline at end of file + self.filter_state = d diff --git a/pyrecest/filters/kalman_filter.py b/pyrecest/filters/kalman_filter.py index 5aa6f346..19ee8261 100644 --- a/pyrecest/filters/kalman_filter.py +++ b/pyrecest/filters/kalman_filter.py @@ -1,12 +1,11 @@ -from pyrecest.backend import eye - -from beartype import beartype +import pyrecest.backend from filterpy.kalman import KalmanFilter as FilterPyKalmanFilter +from pyrecest.backend import eye from pyrecest.distributions import GaussianDistribution from .abstract_euclidean_filter import AbstractEuclideanFilter -import pyrecest.backend + class KalmanFilter(AbstractEuclideanFilter): def __init__(self, initial_state): """ @@ -65,7 +64,7 @@ def predict_linear( self, system_matrix, sys_noise_cov, - sys_input = None, + sys_input=None, ): """ Predicts the next state assuming a linear system model. @@ -74,7 +73,9 @@ def predict_linear( :param sys_noise_cov: System noise covariance. :param sys_input: System input. """ - assert pyrecest.backend.__name__ == "pyrecest.numpy", "Only supported on NumPy backend" + assert ( + pyrecest.backend.__name__ == "pyrecest.numpy" + ), "Only supported on NumPy backend" if sys_input is not None and system_matrix.shape[0] != sys_input.shape[0]: raise ValueError( "The number of rows in system_matrix should match the number of elements in sys_input" @@ -109,10 +110,12 @@ def update_linear( :param measurement_matrix: Measurement matrix. :param meas_noise: Covariance matrix for measurement. """ - assert pyrecest.backend.__name__ == "pyrecest.numpy", "Only supported on NumPy backend" + assert ( + pyrecest.backend.__name__ == "pyrecest.numpy" + ), "Only supported on NumPy backend" self._filter_state.dim_z = measurement_matrix.shape[0] self._filter_state.update(z=measurement, R=meas_noise, H=measurement_matrix) def get_point_estimate(self): """Returns the mean of the current filter state.""" - return self._filter_state.x \ No newline at end of file + return self._filter_state.x diff --git a/pyrecest/filters/lin_bounded_particle_filter.py b/pyrecest/filters/lin_bounded_particle_filter.py index d9cd11b3..3b7aca72 100644 --- a/pyrecest/filters/lin_bounded_particle_filter.py +++ b/pyrecest/filters/lin_bounded_particle_filter.py @@ -3,4 +3,4 @@ class LinBoundedParticleFilter(AbstractParticleFilter, AbstractLinBoundedFilter): - pass \ No newline at end of file + pass diff --git a/pyrecest/filters/lin_periodic_particle_filter.py b/pyrecest/filters/lin_periodic_particle_filter.py index f0746417..07613769 100644 --- a/pyrecest/filters/lin_periodic_particle_filter.py +++ b/pyrecest/filters/lin_periodic_particle_filter.py @@ -2,4 +2,4 @@ class LinPeriodicParticleFilter(LinBoundedParticleFilter): - pass \ No newline at end of file + pass diff --git a/pyrecest/filters/random_matrix_tracker.py b/pyrecest/filters/random_matrix_tracker.py index c44e17ee..318ac6fc 100644 --- a/pyrecest/filters/random_matrix_tracker.py +++ b/pyrecest/filters/random_matrix_tracker.py @@ -1,9 +1,4 @@ -from pyrecest.backend import linalg -from pyrecest.backend import mean -from pyrecest.backend import eye -from pyrecest.backend import exp -from pyrecest.backend import concatenate - +from pyrecest.backend import concatenate, exp, eye, linalg, mean from pyrecest.utils.plotting import plot_ellipsoid from .abstract_extended_object_tracker import AbstractExtendedObjectTracker @@ -103,4 +98,4 @@ def plot_point_estimate(self, scaling_factor=1, color=(0, 0.4470, 0.7410)): before plotting.""" ) position_estimate = self.kinematic_state_to_pos_matrix @ self.kinematic_state - plot_ellipsoid(position_estimate, self.extent, scaling_factor, color) \ No newline at end of file + plot_ellipsoid(position_estimate, self.extent, scaling_factor, color) diff --git a/pyrecest/filters/toroidal_particle_filter.py b/pyrecest/filters/toroidal_particle_filter.py index 8e96646d..a21e8e1e 100644 --- a/pyrecest/filters/toroidal_particle_filter.py +++ b/pyrecest/filters/toroidal_particle_filter.py @@ -1,12 +1,10 @@ from typing import Union -from pyrecest.backend import int64 -from pyrecest.backend import int32 -from beartype import beartype +from pyrecest.backend import int32, int64 from .hypertoroidal_particle_filter import HypertoroidalParticleFilter class ToroidalParticleFilter(HypertoroidalParticleFilter): def __init__(self, n_particles: Union[int, int32, int64]): - HypertoroidalParticleFilter.__init__(self, n_particles, 2) \ No newline at end of file + HypertoroidalParticleFilter.__init__(self, n_particles, 2) diff --git a/pyrecest/filters/toroidal_wrapped_normal_filter.py b/pyrecest/filters/toroidal_wrapped_normal_filter.py index f58b40b3..f9f7fd05 100644 --- a/pyrecest/filters/toroidal_wrapped_normal_filter.py +++ b/pyrecest/filters/toroidal_wrapped_normal_filter.py @@ -1,6 +1,4 @@ -from pyrecest.backend import eye -from pyrecest.backend import array - +from pyrecest.backend import array, eye from pyrecest.distributions.hypertorus.toroidal_wrapped_normal_distribution import ( ToroidalWrappedNormalDistribution, ) @@ -16,4 +14,4 @@ def __init__(self): def predict_identity(self, twn_sys): assert isinstance(twn_sys, ToroidalWrappedNormalDistribution) - self.filter_state = self.filter_state.convolve(twn_sys) \ No newline at end of file + self.filter_state = self.filter_state.convolve(twn_sys) diff --git a/pyrecest/filters/von_mises_filter.py b/pyrecest/filters/von_mises_filter.py index f136724a..e8e9461a 100644 --- a/pyrecest/filters/von_mises_filter.py +++ b/pyrecest/filters/von_mises_filter.py @@ -1,10 +1,8 @@ -from math import pi -from pyrecest.backend import mod import copy import warnings +from math import pi - -from beartype import beartype +from pyrecest.backend import mod from pyrecest.distributions import VonMisesDistribution from .abstract_circular_filter import AbstractCircularFilter @@ -71,4 +69,4 @@ def update_identity(self, vmMeas: VonMisesDistribution, z=0.0): muWnew = mod(z - vmMeas.mu, 2.0 * pi) vmMeasShifted = VonMisesDistribution(muWnew, vmMeas.kappa) - self.filter_state = self.filter_state.multiply(vmMeasShifted) \ No newline at end of file + self.filter_state = self.filter_state.multiply(vmMeasShifted) diff --git a/pyrecest/filters/von_mises_fisher_filter.py b/pyrecest/filters/von_mises_fisher_filter.py index 56291a0a..d0ace6b9 100644 --- a/pyrecest/filters/von_mises_fisher_filter.py +++ b/pyrecest/filters/von_mises_fisher_filter.py @@ -1,6 +1,4 @@ -from pyrecest.backend import ndim -from pyrecest.backend import array - +from pyrecest.backend import array, ndim from pyrecest.distributions import VonMisesFisherDistribution from .abstract_hyperspherical_filter import AbstractHypersphericalFilter @@ -49,4 +47,4 @@ def update_identity(self, meas_noise, z): ), "Dimension mismatch between measurement and state." assert ndim(z) == 1, "z should be a vector." meas_noise.mu = z - self.filter_state = self.filter_state.multiply(meas_noise) \ No newline at end of file + self.filter_state = self.filter_state.multiply(meas_noise) diff --git a/pyrecest/filters/wrapped_normal_filter.py b/pyrecest/filters/wrapped_normal_filter.py index 60d38e5b..2369be84 100644 --- a/pyrecest/filters/wrapped_normal_filter.py +++ b/pyrecest/filters/wrapped_normal_filter.py @@ -1,13 +1,8 @@ -from math import pi -from pyrecest.backend import mod -from pyrecest.backend import log -from pyrecest.backend import array from collections.abc import Callable from functools import partial -from pyrecest.backend import amax -from pyrecest.backend import amin - +from math import pi +from pyrecest.backend import amax, amin, array, log, mod from pyrecest.distributions import CircularDiracDistribution, WrappedNormalDistribution from pyrecest.filters.abstract_circular_filter import AbstractCircularFilter @@ -48,7 +43,7 @@ def update_nonlinear_progressive( while lambda_ > 0: wd = self.filter_state.to_dirac5() likelihood_vals = array([likelihood(z, x) for x in wd.d]) - likelihood_vals_min= amin(likelihood_vals) + likelihood_vals_min = amin(likelihood_vals) likelihood_vals_max = amax(likelihood_vals) if likelihood_vals_max == 0: @@ -75,4 +70,4 @@ def update_nonlinear_progressive( wd_new = wd.reweigh(lambda x: likelihood(z, x) ** current_lambda) self.filter_state = wd_new.to_wn() lambda_ = lambda_ - current_lambda - steps += 1 \ No newline at end of file + steps += 1 diff --git a/pyrecest/sampling/__init__.py b/pyrecest/sampling/__init__.py index fd4498fa..9249ae3b 100644 --- a/pyrecest/sampling/__init__.py +++ b/pyrecest/sampling/__init__.py @@ -2,4 +2,4 @@ __all__ = [ "AbstractSampler", -] \ No newline at end of file +] diff --git a/pyrecest/sampling/abstract_sampler.py b/pyrecest/sampling/abstract_sampler.py index ee00a570..36be20d1 100644 --- a/pyrecest/sampling/abstract_sampler.py +++ b/pyrecest/sampling/abstract_sampler.py @@ -1,9 +1,7 @@ from abc import ABC, abstractmethod - - class AbstractSampler(ABC): @abstractmethod def sample_stochastic(self, n_samples: int, dim: int): - raise NotImplementedError("Abstract method not implemented!") \ No newline at end of file + raise NotImplementedError("Abstract method not implemented!") diff --git a/pyrecest/sampling/euclidean_sampler.py b/pyrecest/sampling/euclidean_sampler.py index 77138d31..43daaa05 100644 --- a/pyrecest/sampling/euclidean_sampler.py +++ b/pyrecest/sampling/euclidean_sampler.py @@ -1,6 +1,4 @@ -from pyrecest.backend import eye -from pyrecest.backend import zeros - +from pyrecest.backend import eye, zeros from pyrecest.distributions import GaussianDistribution from .abstract_sampler import AbstractSampler @@ -12,4 +10,4 @@ class AbstractEuclideanSampler(AbstractSampler): class GaussianSampler(AbstractEuclideanSampler): def sample_stochastic(self, n_samples: int, dim: int): - return GaussianDistribution(zeros(dim), eye(dim)).sample(n_samples) \ No newline at end of file + return GaussianDistribution(zeros(dim), eye(dim)).sample(n_samples) diff --git a/pyrecest/sampling/hyperspherical_sampler.py b/pyrecest/sampling/hyperspherical_sampler.py index 20a5f06c..1958da44 100644 --- a/pyrecest/sampling/hyperspherical_sampler.py +++ b/pyrecest/sampling/hyperspherical_sampler.py @@ -70,11 +70,12 @@ def sample_stochastic( class AbstractSphericalCoordinatesBasedSampler(AbstractSphericalUniformSampler): @abstractmethod def get_grid_spherical_coordinates( - self, grid_density_parameter: int + self, grid_density_parameter: int, ): raise NotImplementedError() - def get_grid(self, grid_density_parameter: int): + def get_grid(self, grid_density_parameter: int, dim: int = 2): + assert dim == 2, "AbstractSphericalCoordinatesBasedSampler is supposed to be used for the circle (which is one-dimensional) only." phi, theta, grid_specific_description = self.get_grid_spherical_coordinates( grid_density_parameter ) diff --git a/pyrecest/sampling/hypertoroidal_sampler.py b/pyrecest/sampling/hypertoroidal_sampler.py index 4fc17cd6..78cd269b 100644 --- a/pyrecest/sampling/hypertoroidal_sampler.py +++ b/pyrecest/sampling/hypertoroidal_sampler.py @@ -16,7 +16,8 @@ class AbstractCircularSampler(AbstractHypertoroidalSampler): class CircularUniformSampler(AbstractCircularSampler): - def sample_stochastic(self, n_samples: int): + def sample_stochastic(self, n_samples: int, dim: int): + assert dim == 1, "CircularUniformSampler is supposed to be used for the circle (which is one-dimensional) only." return CircularUniformDistribution().sample(n_samples) def get_grid(self, grid_density_parameter: int): diff --git a/pyrecest/tests/distributions/test_abstract_circular_distribution.py b/pyrecest/tests/distributions/test_abstract_circular_distribution.py index aa96af10..04b3c4ca 100644 --- a/pyrecest/tests/distributions/test_abstract_circular_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_circular_distribution.py @@ -1,12 +1,8 @@ -from math import pi -from pyrecest.backend import arange -from pyrecest.backend import allclose -from pyrecest.backend import all -from pyrecest.backend import array -import pyrecest.backend import unittest +from math import pi - +import pyrecest.backend +from pyrecest.backend import allclose, arange, array from pyrecest.distributions import VonMisesDistribution, WrappedNormalDistribution @@ -17,7 +13,10 @@ def setUp(self): VonMisesDistribution(array(6.0), array(1.2)), ] - @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") + @unittest.skipIf( + pyrecest.backend.__name__ == "pyrecest.pytorch", + reason="Not supported on PyTorch backend", + ) def test_cdf_numerical(self): """Tests if the numerical computation of cdf matches the actual cdf.""" x = arange(0, 7) @@ -50,8 +49,11 @@ def test_angular_moment_numerical(self): rtol=1e-10, ) ) - - @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") + + @unittest.skipIf( + pyrecest.backend.__name__ == "pyrecest.pytorch", + reason="Not supported on PyTorch backend", + ) def test_integral_numerical(self): """Tests if the numerical computation of integral matches the actual integral.""" intervals = [ @@ -79,4 +81,4 @@ def test_integral_numerical(self): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py b/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py index 6c0760b9..177b6631 100644 --- a/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py @@ -1,17 +1,17 @@ -from pyrecest.backend import column_stack -from pyrecest.backend import diff -from math import pi -from pyrecest.backend import ones -from pyrecest.backend import array -from pyrecest.backend import arange -from pyrecest.backend import allclose -from pyrecest.backend import all -from pyrecest.backend import zeros import unittest -import pyrecest.backend -import numpy.testing as npt - +from math import pi +import numpy.testing as npt +import pyrecest.backend +from pyrecest.backend import ( + allclose, + arange, + array, + column_stack, + diff, + ones, + zeros, +) from pyrecest.distributions.cart_prod.partially_wrapped_normal_distribution import ( PartiallyWrappedNormalDistribution, ) @@ -30,7 +30,10 @@ def test_linear_mean_numerical(self): ) npt.assert_allclose(hwn.linear_mean_numerical(), hwn.mu[-1]) - @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") + @unittest.skipIf( + pyrecest.backend.__name__ == "pyrecest.pytorch", + reason="Not supported on PyTorch backend", + ) def test_condition_on_periodic(self): hwn = PartiallyWrappedNormalDistribution( array([1.0, 2.0]), array([[2.0, 0.3], [0.3, 1.0]]), 1 @@ -55,7 +58,10 @@ def test_condition_on_periodic(self): atol=1e-10, ) - @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") + @unittest.skipIf( + pyrecest.backend.__name__ == "pyrecest.pytorch", + reason="Not supported on PyTorch backend", + ) def test_condition_on_linear(self): hwn = PartiallyWrappedNormalDistribution( array([1.0, 2.0]), array([[2.0, 0.3], [0.3, 1.0]]), 1 @@ -84,4 +90,4 @@ def test_condition_on_linear(self): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/distributions/test_abstract_hyperhemispherical_distribution.py b/pyrecest/tests/distributions/test_abstract_hyperhemispherical_distribution.py index c87c4bb3..aebc17ee 100644 --- a/pyrecest/tests/distributions/test_abstract_hyperhemispherical_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hyperhemispherical_distribution.py @@ -1,12 +1,8 @@ -from pyrecest.backend import linalg -from math import pi -from pyrecest.backend import sum -from pyrecest.backend import ones -from pyrecest.backend import array import unittest -import numpy.testing as npt - +from math import pi +import numpy.testing as npt +from pyrecest.backend import array, linalg, ones, sum from pyrecest.distributions import ( HyperhemisphericalWatsonDistribution, VonMisesFisherDistribution, @@ -49,10 +45,8 @@ def test_sample_metropolis_hastings_basics_only(self): for s in samples: with self.subTest(sample=s): self.assertEqual(s.shape, (n, chd.input_dim)) - npt.assert_allclose( - sum(s**2, axis=1), ones(n), rtol=1e-10 - ) + npt.assert_allclose(sum(s**2, axis=1), ones(n), rtol=1e-10) if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/distributions/test_abstract_hypersphere_subset_distribution.py b/pyrecest/tests/distributions/test_abstract_hypersphere_subset_distribution.py index d925bd9c..3a8dd488 100644 --- a/pyrecest/tests/distributions/test_abstract_hypersphere_subset_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hypersphere_subset_distribution.py @@ -1,10 +1,7 @@ -from pyrecest.backend import linalg -from pyrecest.backend import sin -from pyrecest.backend import cos -from pyrecest.backend import array import unittest -import numpy.testing as npt +import numpy.testing as npt +from pyrecest.backend import array, cos, linalg, sin from pyrecest.distributions import VonMisesFisherDistribution @@ -82,4 +79,4 @@ def fangles_3d(phi1, phi2, phi3): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/distributions/test_abstract_hyperspherical_distribution.py b/pyrecest/tests/distributions/test_abstract_hyperspherical_distribution.py index 6245c68d..fb83bb2a 100644 --- a/pyrecest/tests/distributions/test_abstract_hyperspherical_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hyperspherical_distribution.py @@ -1,11 +1,8 @@ -from pyrecest.backend import linalg -from math import pi -from pyrecest.backend import sqrt -from pyrecest.backend import array import unittest +from math import pi import matplotlib - +from pyrecest.backend import array, linalg, sqrt from pyrecest.distributions import ( AbstractHypersphericalDistribution, VonMisesFisherDistribution, @@ -67,4 +64,4 @@ def test_plotting_error_free_2d(self): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/distributions/test_abstract_hypertoroidal_distribution.py b/pyrecest/tests/distributions/test_abstract_hypertoroidal_distribution.py index a10cafce..acbad876 100644 --- a/pyrecest/tests/distributions/test_abstract_hypertoroidal_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hypertoroidal_distribution.py @@ -1,9 +1,10 @@ -from math import pi import unittest -from pyrecest.backend import array +from math import pi -from pyrecest.distributions import AbstractHypertoroidalDistribution import numpy.testing as npt +from pyrecest.backend import array +from pyrecest.distributions import AbstractHypertoroidalDistribution + class TestAbstractHypertoroidalDistribution(unittest.TestCase): def test_angular_error(self): @@ -14,6 +15,8 @@ def test_angular_error(self): AbstractHypertoroidalDistribution.angular_error(array(0), array(2 * pi)), 0 ) npt.assert_allclose( - AbstractHypertoroidalDistribution.angular_error(array(pi / 4), array(7 * pi / 4)), + AbstractHypertoroidalDistribution.angular_error( + array(pi / 4), array(7 * pi / 4) + ), pi / 2, - ) \ No newline at end of file + ) diff --git a/pyrecest/tests/distributions/test_abstract_linear_distribution.py b/pyrecest/tests/distributions/test_abstract_linear_distribution.py index a6dc685a..f3d3aa2b 100644 --- a/pyrecest/tests/distributions/test_abstract_linear_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_linear_distribution.py @@ -1,13 +1,9 @@ -from pyrecest.backend import diag -from pyrecest.backend import squeeze -from pyrecest.backend import isclose -from pyrecest.backend import array -import pyrecest.backend import unittest -import numpy.testing as npt import matplotlib - +import numpy.testing as npt +import pyrecest.backend +from pyrecest.backend import array, diag, isclose from pyrecest.distributions import ( AbstractLinearDistribution, CustomLinearDistribution, @@ -40,8 +36,8 @@ def f(x): return 0.3 * dist.pdf(x) dim = 2 - left = [-float('inf'), -float('inf')] - right = [float('inf'), float('inf')] + left = [-float("inf"), -float("inf")] + right = [float("inf"), float("inf")] integration_result = AbstractLinearDistribution.integrate_fun_over_domain( f, dim, left, right @@ -50,11 +46,15 @@ def f(x): integration_result, 0.3, rtol=1e-5 ), f"Expected 0.3, but got {integration_result}" - @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") + @unittest.skipIf( + pyrecest.backend.__name__ == "pyrecest.pytorch", + reason="Not supported on PyTorch backend", + ) def test_mode_numerical_custom_1D(self): cd = CustomLinearDistribution( lambda x: array( - ((x > -1.0) & (x <= 0.0)) * (1.0 + x) + ((x > 0.0) & (x <= 1.0)) * (1.0 - x) + ((x > -1.0) & (x <= 0.0)) * (1.0 + x) + + ((x > 0.0) & (x <= 1.0)) * (1.0 - x) ).squeeze(), 1, ) @@ -64,21 +64,25 @@ def test_mode_numerical_custom_1D(self): def test_mean_numerical_gaussian_2D(self): npt.assert_allclose(self.g_2D.mean_numerical(), self.mu_2D, atol=1e-6) - @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") + @unittest.skipIf( + pyrecest.backend.__name__ == "pyrecest.pytorch", + reason="Not supported on PyTorch backend", + ) def test_mode_numerical_gaussian_2D_mean_far_away(self): mu = array([5.0, 10.0]) C = array([[2.0, 1.0], [1.0, 1.0]]) g = GaussianDistribution(mu, C) npt.assert_allclose(g.mode_numerical(), mu, atol=2e-4) - @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") + @unittest.skipIf( + pyrecest.backend.__name__ == "pyrecest.pytorch", + reason="Not supported on PyTorch backend", + ) def test_mode_numerical_gaussian_3D(self): npt.assert_allclose(self.g_3D.mode_numerical(), self.mu_3D, atol=5e-4) def test_covariance_numerical_gaussian_2D(self): - npt.assert_allclose( - self.g_2D.covariance_numerical(), self.C_2D, atol=1e-6 - ) + npt.assert_allclose(self.g_2D.covariance_numerical(), self.C_2D, atol=1e-6) def test_plot_state_r2(self): gd = GaussianDistribution(array([1.0, 2.0]), array([[1.0, 0.5], [0.5, 1.0]])) @@ -86,4 +90,4 @@ def test_plot_state_r2(self): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/distributions/test_abstract_mixture.py b/pyrecest/tests/distributions/test_abstract_mixture.py index 5fcebf27..483ef305 100644 --- a/pyrecest/tests/distributions/test_abstract_mixture.py +++ b/pyrecest/tests/distributions/test_abstract_mixture.py @@ -1,13 +1,7 @@ -from pyrecest.backend import linalg -from pyrecest.backend import ones -from pyrecest.backend import eye -from pyrecest.backend import array -from pyrecest.backend import allclose -from pyrecest.backend import all -import pyrecest.backend import unittest - +import pyrecest.backend +from pyrecest.backend import allclose, array, eye, linalg, ones from pyrecest.distributions import VonMisesFisherDistribution from pyrecest.distributions.hypersphere_subset.custom_hyperhemispherical_distribution import ( CustomHyperhemisphericalDistribution, @@ -35,7 +29,10 @@ def test_sample_metropolis_hastings_basics_only_t2(self): ) self._test_sample(mix, 10) - @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") + @unittest.skipIf( + pyrecest.backend.__name__ == "pyrecest.pytorch", + reason="Not supported on PyTorch backend", + ) def test_sample_metropolis_hastings_basics_only_s2(self): vmf1 = VonMisesFisherDistribution(array([1.0, 0.0, 0.0]), array(2.0)) vmf2 = VonMisesFisherDistribution(array([0.0, 1.0, 0.0]), array(2.0)) @@ -53,4 +50,4 @@ def test_sample_metropolis_hastings_basics_only_h2(self): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/distributions/test_bingham_distribution.py b/pyrecest/tests/distributions/test_bingham_distribution.py index 4e613f07..3caf9728 100644 --- a/pyrecest/tests/distributions/test_bingham_distribution.py +++ b/pyrecest/tests/distributions/test_bingham_distribution.py @@ -1,11 +1,11 @@ -from pyrecest.backend import array import unittest - +import numpy.testing as npt +from pyrecest.backend import array from pyrecest.distributions import BinghamDistribution from .test_von_mises_fisher_distribution import vectors_to_test_2d -import numpy.testing as npt + class TestBinghamDistribution(unittest.TestCase): def setUp(self): @@ -37,4 +37,4 @@ def test_pdf(self): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/distributions/test_circular_fourier_distribution.py b/pyrecest/tests/distributions/test_circular_fourier_distribution.py index 8464e92d..4d897097 100644 --- a/pyrecest/tests/distributions/test_circular_fourier_distribution.py +++ b/pyrecest/tests/distributions/test_circular_fourier_distribution.py @@ -1,18 +1,11 @@ -from math import pi -from pyrecest.backend import sqrt -from pyrecest.backend import linspace -from pyrecest.backend import ceil -from pyrecest.backend import array -from pyrecest.backend import arange -from pyrecest.backend import allclose -from pyrecest.backend import all -import pyrecest.backend import copy import unittest -import numpy.testing as npt +from math import pi import numpy.testing as npt +import pyrecest.backend from parameterized import parameterized +from pyrecest.backend import arange, array, ceil, linspace, sqrt from pyrecest.distributions import ( CircularFourierDistribution, VonMisesDistribution, @@ -97,7 +90,10 @@ def test_vm_to_fourier(self, mult_by_n, transformation): (False, "sqrt"), ] ) - @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") + @unittest.skipIf( + pyrecest.backend.__name__ == "pyrecest.pytorch", + reason="Not supported on PyTorch backend", + ) def test_integrate_numerically(self, mult_by_n, transformation): scale_by = 2.0 / 5.0 dist = VonMisesDistribution(2.9, 1.3) @@ -116,9 +112,7 @@ def test_integrate_numerically(self, mult_by_n, transformation): expected_val = scale_by else: expected_val = (scale_by) ** 2 - npt.assert_array_almost_equal( - fd_unnorm.integrate_numerically(), expected_val - ) + npt.assert_array_almost_equal(fd_unnorm.integrate_numerically(), expected_val) fd_unnorm_real = fd_unnorm.to_real_fd() npt.assert_array_almost_equal( fd_unnorm_real.integrate_numerically(), expected_val @@ -149,7 +143,7 @@ def test_integrate(self, mult_by_n, transformation): if transformation == "identity": expected_val = scale_by else: - expected_val = scale_by ** 2 + expected_val = scale_by**2 npt.assert_array_almost_equal(fd_unnorm.integrate(), expected_val) fd_unnorm_real = fd_unnorm.to_real_fd() npt.assert_array_almost_equal(fd_unnorm_real.integrate(), expected_val) @@ -188,10 +182,7 @@ def test_distance(self, mult_by_n): store_values_multiplied_by_n=mult_by_n, ) hel_like_distance, _ = integrate.quad( - lambda x: ( - sqrt(dist1.pdf(array(x))) - sqrt(dist2.pdf(array(x))) - ) - ** 2, + lambda x: (sqrt(dist1.pdf(array(x))) - sqrt(dist2.pdf(array(x)))) ** 2, 0.0, 2.0 * pi, ) @@ -200,4 +191,4 @@ def test_distance(self, mult_by_n): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/distributions/test_circular_uniform_distribution.py b/pyrecest/tests/distributions/test_circular_uniform_distribution.py index 48a207eb..bef2e597 100644 --- a/pyrecest/tests/distributions/test_circular_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_circular_uniform_distribution.py @@ -1,10 +1,9 @@ -from math import pi -from pyrecest.backend import ones -from pyrecest.backend import array import unittest -import pyrecest.backend +from math import pi import numpy.testing as npt +import pyrecest.backend +from pyrecest.backend import array, ones from pyrecest.distributions.circle.circular_uniform_distribution import ( CircularUniformDistribution, ) @@ -24,13 +23,19 @@ def test_shift(self): x = array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]) npt.assert_allclose(cu2.pdf(x), 1.0 / (2.0 * pi) * ones(x.shape)) - @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") + @unittest.skipIf( + pyrecest.backend.__name__ == "pyrecest.pytorch", + reason="Not supported on PyTorch backend", + ) def test_cdf(self): cu = CircularUniformDistribution() x = array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]) npt.assert_allclose(cu.cdf(x), cu.cdf_numerical(x)) - @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") + @unittest.skipIf( + pyrecest.backend.__name__ == "pyrecest.pytorch", + reason="Not supported on PyTorch backend", + ) def test_cdf_with_shift(self): cu = CircularUniformDistribution() x = array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]) @@ -51,23 +56,31 @@ def test_trigonometric_moment_with_shift(self): ) npt.assert_allclose(cu.trigonometric_moment(1), 0.0, atol=1e-10) - @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") + @unittest.skipIf( + pyrecest.backend.__name__ == "pyrecest.pytorch", + reason="Not supported on PyTorch backend", + ) def test_integral(self): cu = CircularUniformDistribution() npt.assert_allclose(cu.integrate(), cu.integrate_numerically()) npt.assert_allclose(cu.integrate(), 1) - @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") + @unittest.skipIf( + pyrecest.backend.__name__ == "pyrecest.pytorch", + reason="Not supported on PyTorch backend", + ) def test_integral_with_range(self): cu = CircularUniformDistribution() npt.assert_allclose( cu.integrate(array([1.0, 4.0])), cu.integrate_numerically(array([1.0, 4.0])) ) npt.assert_allclose( - cu.integrate(array([-4.0, 11.0])), cu.integrate_numerically(array([-4.0, 11.0])) + cu.integrate(array([-4.0, 11.0])), + cu.integrate_numerically(array([-4.0, 11.0])), ) npt.assert_allclose( - cu.integrate(array([2.0 * pi, -1.0])), cu.integrate_numerically(array([2.0 * pi, -1.0])) + cu.integrate(array([2.0 * pi, -1.0])), + cu.integrate_numerically(array([2.0 * pi, -1.0])), ) def test_mean(self): @@ -83,4 +96,4 @@ def test_sampling(self): cu = CircularUniformDistribution() n = 10 s = cu.sample(n) - npt.assert_allclose(s.shape[0], n) \ No newline at end of file + npt.assert_allclose(s.shape[0], n) diff --git a/pyrecest/tests/distributions/test_custom_hemispherical_distribution.py b/pyrecest/tests/distributions/test_custom_hemispherical_distribution.py index a6983e9d..32709d96 100644 --- a/pyrecest/tests/distributions/test_custom_hemispherical_distribution.py +++ b/pyrecest/tests/distributions/test_custom_hemispherical_distribution.py @@ -1,14 +1,7 @@ -from pyrecest.backend import linalg -from pyrecest.backend import random -from pyrecest.backend import eye -from pyrecest.backend import array -from pyrecest.backend import allclose -from pyrecest.backend import all -from pyrecest.backend import ndim import unittest import warnings - +from pyrecest.backend import allclose, array, eye, linalg, ndim, random from pyrecest.distributions import ( BinghamDistribution, CustomHemisphericalDistribution, @@ -74,4 +67,4 @@ def test_warning_asymmetric(self): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py b/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py index 8699dfa7..99ce619e 100644 --- a/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py +++ b/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py @@ -1,14 +1,9 @@ -from math import pi -from pyrecest.backend import random -from pyrecest.backend import linspace -from pyrecest.backend import eye -from pyrecest.backend import array -from pyrecest.backend import arange -from pyrecest.backend import meshgrid -import pyrecest.backend import unittest -import numpy.testing as npt +from math import pi +import numpy.testing as npt +import pyrecest.backend +from pyrecest.backend import arange, array, eye, linspace, meshgrid, random from pyrecest.distributions import ( GaussianDistribution, PartiallyWrappedNormalDistribution, @@ -26,7 +21,14 @@ def setUp(self) -> None: self.pwn = PartiallyWrappedNormalDistribution( array([2.0, 3.0, 4.0, 5.0, 6.0, 7.0]), mat, 3 ) - grid = meshgrid(arange(-3, 4), arange(-3, 4), arange(-2, 3), arange(-2, 3), arange(-2, 3), arange(-2, 3)) + grid = meshgrid( + arange(-3, 4), + arange(-3, 4), + arange(-2, 3), + arange(-2, 3), + arange(-2, 3), + arange(-2, 3), + ) self.grid_flat = array(grid).reshape(6, -1).T self.vm = VonMisesDistribution(array(0.0), array(1.0)) @@ -39,24 +41,26 @@ def fun(x): def test_constructor(self): chd = CustomHypercylindricalDistribution(self.pwn.pdf, 3, 3) - npt.assert_allclose( - self.pwn.pdf(self.grid_flat), chd.pdf(self.grid_flat) - ) + npt.assert_allclose(self.pwn.pdf(self.grid_flat), chd.pdf(self.grid_flat)) def test_from_distribution(self): chd = CustomHypercylindricalDistribution.from_distribution(self.pwn) - npt.assert_allclose( - self.pwn.pdf(self.grid_flat), chd.pdf(self.grid_flat) - ) + npt.assert_allclose(self.pwn.pdf(self.grid_flat), chd.pdf(self.grid_flat)) - @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") + @unittest.skipIf( + pyrecest.backend.__name__ == "pyrecest.pytorch", + reason="Not supported on PyTorch backend", + ) def test_condition_on_linear(self): dist = self.chcd_vm_gauss_stacked.condition_on_linear(array([2.0, 1.0])) x = linspace(0.0, 2.0 * pi, 100) npt.assert_allclose(dist.pdf(x), self.vm.pdf(x)) - @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") + @unittest.skipIf( + pyrecest.backend.__name__ == "pyrecest.pytorch", + reason="Not supported on PyTorch backend", + ) def test_condition_on_periodic(self): dist = self.chcd_vm_gauss_stacked.condition_on_periodic(array(1.0)) @@ -66,4 +70,4 @@ def test_condition_on_periodic(self): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/distributions/test_custom_hyperrectangular_distribution.py b/pyrecest/tests/distributions/test_custom_hyperrectangular_distribution.py index 92fe34dc..95001bd0 100644 --- a/pyrecest/tests/distributions/test_custom_hyperrectangular_distribution.py +++ b/pyrecest/tests/distributions/test_custom_hyperrectangular_distribution.py @@ -1,13 +1,13 @@ -from pyrecest.backend import column_stack -from pyrecest.backend import ones -from pyrecest.backend import meshgrid -from pyrecest.backend import linspace -from pyrecest.backend import array -from pyrecest.backend import allclose -from pyrecest.backend import all import unittest - +from pyrecest.backend import ( + allclose, + array, + column_stack, + linspace, + meshgrid, + ones, +) from pyrecest.distributions.custom_hyperrectangular_distribution import ( CustomHyperrectangularDistribution, ) @@ -42,4 +42,4 @@ def test_pdf_method(self): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/distributions/test_custom_hyperspherical_distribution.py b/pyrecest/tests/distributions/test_custom_hyperspherical_distribution.py index 3e4cef3d..c2b9f16f 100644 --- a/pyrecest/tests/distributions/test_custom_hyperspherical_distribution.py +++ b/pyrecest/tests/distributions/test_custom_hyperspherical_distribution.py @@ -1,11 +1,6 @@ -from pyrecest.backend import linalg -from pyrecest.backend import random -from pyrecest.backend import array -from pyrecest.backend import allclose -from pyrecest.backend import all import unittest - +from pyrecest.backend import allclose, array, linalg, random from pyrecest.distributions import VonMisesFisherDistribution from pyrecest.distributions.hypersphere_subset.custom_hyperspherical_distribution import ( CustomHypersphericalDistribution, @@ -58,4 +53,4 @@ def test_from_distribution(self): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/distributions/test_custom_linear_distribution.py b/pyrecest/tests/distributions/test_custom_linear_distribution.py index 3dd94a06..c39aa1ee 100644 --- a/pyrecest/tests/distributions/test_custom_linear_distribution.py +++ b/pyrecest/tests/distributions/test_custom_linear_distribution.py @@ -1,12 +1,8 @@ -from math import pi -from pyrecest.backend import meshgrid -from pyrecest.backend import linspace -from pyrecest.backend import eye -from pyrecest.backend import array -from pyrecest.backend import concatenate import unittest -import numpy.testing as npt +from math import pi +import numpy.testing as npt +from pyrecest.backend import array, concatenate, eye, linspace, meshgrid from pyrecest.distributions import CustomLinearDistribution, GaussianDistribution from pyrecest.distributions.nonperiodic.gaussian_mixture import GaussianMixture @@ -41,4 +37,4 @@ def verify_pdf_equal(dist1, dist2, tol): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/distributions/test_disk_uniform_distribution.py b/pyrecest/tests/distributions/test_disk_uniform_distribution.py index e3cecd15..9232884a 100644 --- a/pyrecest/tests/distributions/test_disk_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_disk_uniform_distribution.py @@ -1,13 +1,11 @@ from math import pi -from pyrecest.backend import sqrt -from pyrecest.backend import ones -from pyrecest.backend import concatenate -from pyrecest.backend import array -from pyrecest.backend import zeros + +from pyrecest.backend import array, concatenate, ones, sqrt, zeros + """ Test cases for DiskUniformDistribution""" import unittest -import numpy.testing as npt +import numpy.testing as npt from pyrecest.distributions import DiskUniformDistribution @@ -40,4 +38,4 @@ def test_pdf(self): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/distributions/test_ellipsoidal_ball_uniform_distribution.py b/pyrecest/tests/distributions/test_ellipsoidal_ball_uniform_distribution.py index ae70778e..fe0f596c 100644 --- a/pyrecest/tests/distributions/test_ellipsoidal_ball_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_ellipsoidal_ball_uniform_distribution.py @@ -1,8 +1,7 @@ -from pyrecest.backend import diag -from pyrecest.backend import array import unittest -import numpy.testing as npt +import numpy.testing as npt +from pyrecest.backend import array, diag from pyrecest.distributions import EllipsoidalBallUniformDistribution @@ -25,4 +24,4 @@ def test_sampling(self): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/distributions/test_gaussian_distribution.py b/pyrecest/tests/distributions/test_gaussian_distribution.py index d6363df3..5eeb5518 100644 --- a/pyrecest/tests/distributions/test_gaussian_distribution.py +++ b/pyrecest/tests/distributions/test_gaussian_distribution.py @@ -1,11 +1,7 @@ -from pyrecest.backend import linspace -from pyrecest.backend import array -from pyrecest.backend import allclose -from pyrecest.backend import all import unittest - import scipy +from pyrecest.backend import allclose, array, linspace from pyrecest.distributions import GaussianDistribution from scipy.stats import multivariate_normal @@ -69,7 +65,7 @@ def integrand(y, x): result = [] for x_curr in xs: integral_value, _ = scipy.integrate.quad( - integrand, -float('inf'), float('inf'), args=x_curr + integrand, -float("inf"), float("inf"), args=x_curr ) result.append(integral_value) return array(result) @@ -84,4 +80,4 @@ def integrand(y, x): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/distributions/test_hemispherical_uniform_distribution.py b/pyrecest/tests/distributions/test_hemispherical_uniform_distribution.py index 5e302ab2..6cbb0758 100644 --- a/pyrecest/tests/distributions/test_hemispherical_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_hemispherical_uniform_distribution.py @@ -1,10 +1,7 @@ -from math import pi -from pyrecest.backend import ones -from pyrecest.backend import allclose -from pyrecest.backend import all import unittest +from math import pi - +from pyrecest.backend import allclose, ones from pyrecest.distributions.hypersphere_subset.hemispherical_uniform_distribution import ( HemisphericalUniformDistribution, ) @@ -23,8 +20,6 @@ def test_pdf_2d(self): # jscpd:ignore-start self.assertTrue( - allclose( - hhud.pdf(points), ones(points.shape[0]) / (2 * pi), atol=1e-6 - ) + allclose(hhud.pdf(points), ones(points.shape[0]) / (2 * pi), atol=1e-6) ) - # jscpd:ignore-end \ No newline at end of file + # jscpd:ignore-end diff --git a/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py b/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py index a75c6a4a..7aa6bad9 100644 --- a/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py @@ -1,17 +1,18 @@ -from math import pi -from pyrecest.backend import random -from pyrecest.backend import sum -from pyrecest.backend import ones_like -from pyrecest.backend import ones -from pyrecest.backend import isclose -from pyrecest.backend import eye -from pyrecest.backend import exp -from pyrecest.backend import array -from pyrecest.backend import zeros_like -from pyrecest.backend import zeros import unittest -import numpy.testing as npt +from math import pi +import numpy.testing as npt +from pyrecest.backend import ( + array, + exp, + eye, + isclose, + ones, + ones_like, + random, + sum, + zeros_like, +) from pyrecest.distributions.cart_prod.hypercylindrical_dirac_distribution import ( HypercylindricalDiracDistribution, ) @@ -24,7 +25,11 @@ class TestHypercylindricalDiracDistribution(unittest.TestCase): def setUp(self): self.d = array( - [[1.0, 2.0, 3.0, 4.0, 5.0, 6.0], [2.0, 4.0, 0.0, 0.5, 1.0, 1.0], [0.0, 10.0, 20.0, 30.0, 40.0, 50.0]] + [ + [1.0, 2.0, 3.0, 4.0, 5.0, 6.0], + [2.0, 4.0, 0.0, 0.5, 1.0, 1.0], + [0.0, 10.0, 20.0, 30.0, 40.0, 50.0], + ] ).T self.w = array([1.0, 2.0, 3.0, 1.0, 2.0, 3.0]) self.w = self.w / sum(self.w) @@ -102,6 +107,7 @@ def test_sampling(self): def test_from_distribution(self): import numpy as _np + random_gen = _np.random.default_rng(0) # Could fail randomly otherwise df = 4 scale = eye(4) @@ -109,4 +115,4 @@ def test_from_distribution(self): C = array(wishart.rvs(df, scale, random_state=random_gen)) hwn = PartiallyWrappedNormalDistribution(array([1.0, 2.0, 3.0, 4.0]), C, 2) hddist = HypercylindricalDiracDistribution.from_distribution(hwn, 100000) - npt.assert_allclose(hddist.hybrid_mean(), hwn.hybrid_mean(), atol=0.2) \ No newline at end of file + npt.assert_allclose(hddist.hybrid_mean(), hwn.hybrid_mean(), atol=0.2) diff --git a/pyrecest/tests/distributions/test_hyperhemispherical_uniform_distribution.py b/pyrecest/tests/distributions/test_hyperhemispherical_uniform_distribution.py index bd1f571e..f2a32a09 100644 --- a/pyrecest/tests/distributions/test_hyperhemispherical_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_hyperhemispherical_uniform_distribution.py @@ -1,20 +1,16 @@ -from pyrecest.backend import linalg from math import pi -from pyrecest.backend import random -from pyrecest.backend import reshape -from pyrecest.backend import ones -from pyrecest.backend import allclose -from pyrecest.backend import all + +from pyrecest.backend import allclose, linalg, ones, random, reshape + """ Test for uniform distribution for hyperhemispheres """ import unittest - from pyrecest.distributions import HyperhemisphericalUniformDistribution def get_random_points(n, d): random.seed(10) - points = random.normal(0.0, 1.0, (n, d+1)) + points = random.normal(0.0, 1.0, (n, d + 1)) points = points[points[:, -1] >= 0, :] points /= reshape(linalg.norm(points, axis=1), (-1, 1)) return points @@ -29,9 +25,7 @@ def test_pdf_2d(self): points = get_random_points(100, 2) self.assertTrue( - allclose( - hhud.pdf(points), ones(points.shape[0]) / (2 * pi), atol=1e-6 - ) + allclose(hhud.pdf(points), ones(points.shape[0]) / (2 * pi), atol=1e-6) ) def test_pdf_3d(self): @@ -40,9 +34,7 @@ def test_pdf_3d(self): points = get_random_points(100, 3) # jscpd:ignore-start self.assertTrue( - allclose( - hhud.pdf(points), ones(points.shape[0]) / (pi**2), atol=1e-6 - ) + allclose(hhud.pdf(points), ones(points.shape[0]) / (pi**2), atol=1e-6) ) # jscpd:ignore-end @@ -56,4 +48,4 @@ def test_integrate_S3(self): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py b/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py index 367a102d..d41eab2e 100644 --- a/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py @@ -1,15 +1,9 @@ -from pyrecest.backend import linalg -from math import pi -from pyrecest.backend import random -from pyrecest.backend import sum -from pyrecest.backend import sqrt -from pyrecest.backend import ones -from pyrecest.backend import mod -from pyrecest.backend import array -import pyrecest.backend import unittest -import numpy.testing as npt +from math import pi +import numpy.testing as npt +import pyrecest.backend +from pyrecest.backend import array, linalg, mod, ones, random, sqrt, sum from pyrecest.distributions import VonMisesFisherDistribution from pyrecest.distributions.hypersphere_subset.hyperspherical_dirac_distribution import ( HypersphericalDiracDistribution, @@ -19,7 +13,11 @@ class HypersphericalDiracDistributionTest(unittest.TestCase): def setUp(self): self.d = array( - [[0.5, 3.0, 4.0, 6.0, 6.0], [2.0, 2.0, 5.0, 3.0, 0.0], [0.5, 0.2, 5.8, 4.3, 1.2]] + [ + [0.5, 3.0, 4.0, 6.0, 6.0], + [2.0, 2.0, 5.0, 3.0, 0.0], + [0.5, 0.2, 5.8, 4.3, 1.2], + ] ).T self.d = self.d / linalg.norm(self.d, axis=1)[:, None] self.w = array([0.1, 0.1, 0.1, 0.1, 0.6]) @@ -33,9 +31,7 @@ def test_sampling(self): s = self.hdd.sample(nSamples) self.assertEqual(s.shape, (nSamples, self.d.shape[-1])) npt.assert_array_almost_equal(s, mod(s, 2 * pi)) - npt.assert_array_almost_equal( - linalg.norm(s, axis=-1), ones(nSamples) - ) + npt.assert_array_almost_equal(linalg.norm(s, axis=-1), ones(nSamples)) def test_apply_function(self): same = self.hdd.apply_function(lambda x: x) @@ -66,7 +62,10 @@ def f(x): wNew = self.hdd.d[:, 1] * self.hdd.w npt.assert_array_almost_equal(twdNew.w, wNew / sum(wNew)) - @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") + @unittest.skipIf( + pyrecest.backend.__name__ == "pyrecest.pytorch", + reason="Not supported on PyTorch backend", + ) def test_from_distribution(self): random.seed(0) vmf = VonMisesFisherDistribution(array([1.0, 1.0, 1.0]) / sqrt(3), array(1.0)) @@ -77,4 +76,4 @@ def test_from_distribution(self): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/distributions/test_hyperspherical_mixture.py b/pyrecest/tests/distributions/test_hyperspherical_mixture.py index ea64d227..a1743c23 100644 --- a/pyrecest/tests/distributions/test_hyperspherical_mixture.py +++ b/pyrecest/tests/distributions/test_hyperspherical_mixture.py @@ -1,15 +1,8 @@ -from math import pi -from pyrecest.backend import sum -from pyrecest.backend import stack -from pyrecest.backend import sqrt -from pyrecest.backend import meshgrid -from pyrecest.backend import arange -from pyrecest.backend import linspace -from pyrecest.backend import array import unittest - +from math import pi from numpy.testing import assert_allclose +from pyrecest.backend import arange, array, linspace, meshgrid, sqrt, stack, sum from pyrecest.distributions import ( AbstractHypersphereSubsetDistribution, HypersphericalMixture, @@ -44,7 +37,9 @@ def test_pdf_4d(self): w = array([0.3, 0.7]) smix = HypersphericalMixture([wad, vmf], w) - a, b, c, d = meshgrid(arange(-1, 4), arange(-1, 4), arange(-1, 4), arange(-1, 4)) + a, b, c, d = meshgrid( + arange(-1, 4), arange(-1, 4), arange(-1, 4), arange(-1, 4) + ) points = array([a.ravel(), b.ravel(), c.ravel(), d.ravel()]).T points = points / sqrt(sum(points**2, axis=1, keepdims=True)) @@ -56,4 +51,4 @@ def test_pdf_4d(self): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/distributions/test_hyperspherical_uniform_distribution.py b/pyrecest/tests/distributions/test_hyperspherical_uniform_distribution.py index 65d6b560..6cff5157 100644 --- a/pyrecest/tests/distributions/test_hyperspherical_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_hyperspherical_uniform_distribution.py @@ -1,12 +1,8 @@ -from pyrecest.backend import linalg -from pyrecest.backend import random -from pyrecest.backend import ones -from pyrecest.backend import allclose -from pyrecest.backend import all +from pyrecest.backend import allclose, linalg, ones, random + """ Test for uniform distribution on the hypersphere """ import unittest - from pyrecest.distributions import ( AbstractHypersphericalDistribution, HypersphericalUniformDistribution, @@ -43,10 +39,8 @@ def test_sample(self): n = 10 samples = hud.sample(n) self.assertEqual(samples.shape, (n, hud.dim + 1)) - self.assertTrue( - allclose(linalg.norm(samples, axis=1), ones(n), rtol=1e-10) - ) + self.assertTrue(allclose(linalg.norm(samples, axis=1), ones(n), rtol=1e-10)) if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py b/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py index 97fc561f..5c5f36fb 100644 --- a/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py @@ -1,17 +1,17 @@ -from math import pi -from pyrecest.backend import random -from pyrecest.backend import sum -from pyrecest.backend import squeeze -from pyrecest.backend import outer -from pyrecest.backend import ones_like -from pyrecest.backend import ones -from pyrecest.backend import mod -from pyrecest.backend import exp -from pyrecest.backend import array import copy import unittest -import numpy.testing as npt +from math import pi +import numpy.testing as npt +from pyrecest.backend import ( + array, + exp, + mod, + ones_like, + outer, + random, + sum, +) from pyrecest.distributions import ( HypertoroidalDiracDistribution, ToroidalDiracDistribution, @@ -37,12 +37,8 @@ def test_trigonometric_moment(self): m2 = self.twd.marginalize_to_1D(1).trigonometric_moment(1) npt.assert_almost_equal(m[0], m1, decimal=10) npt.assert_almost_equal(m[1], m2, decimal=10) - npt.assert_almost_equal( - m[0], sum(self.w * exp(1j * self.d[:, 0])), decimal=10 - ) - npt.assert_almost_equal( - m[1], sum(self.w * exp(1j * self.d[:, 1])), decimal=10 - ) + npt.assert_almost_equal(m[0], sum(self.w * exp(1j * self.d[:, 0])), decimal=10) + npt.assert_almost_equal(m[1], sum(self.w * exp(1j * self.d[:, 1])), decimal=10) def test_sample(self): n_samples = 5 @@ -124,4 +120,4 @@ def test_marginalization(self): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/distributions/test_hypertoroidal_wrapped_normal_distribution.py b/pyrecest/tests/distributions/test_hypertoroidal_wrapped_normal_distribution.py index 61452543..15f67a06 100644 --- a/pyrecest/tests/distributions/test_hypertoroidal_wrapped_normal_distribution.py +++ b/pyrecest/tests/distributions/test_hypertoroidal_wrapped_normal_distribution.py @@ -1,7 +1,7 @@ -from pyrecest.backend import array import unittest -import numpy.testing as npt +import numpy.testing as npt +from pyrecest.backend import array from pyrecest.distributions import HypertoroidalWNDistribution @@ -22,4 +22,4 @@ def test_pdf(self): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/distributions/test_linear_dirac_distribution.py b/pyrecest/tests/distributions/test_linear_dirac_distribution.py index a6fee6a2..dc1e5028 100644 --- a/pyrecest/tests/distributions/test_linear_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_linear_dirac_distribution.py @@ -1,12 +1,7 @@ -from pyrecest.backend import random -from pyrecest.backend import eye -from pyrecest.backend import array -from pyrecest.backend import allclose -from pyrecest.backend import all import unittest import numpy.testing as npt - +from pyrecest.backend import allclose, array, eye, random from pyrecest.distributions import GaussianDistribution from pyrecest.distributions.nonperiodic.linear_dirac_distribution import ( LinearDiracDistribution, @@ -32,4 +27,4 @@ def test_mean_and_cov(self): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/distributions/test_linear_mixture.py b/pyrecest/tests/distributions/test_linear_mixture.py index 8da82e33..74801287 100644 --- a/pyrecest/tests/distributions/test_linear_mixture.py +++ b/pyrecest/tests/distributions/test_linear_mixture.py @@ -1,12 +1,8 @@ -from pyrecest.backend import column_stack -from pyrecest.backend import diag -from pyrecest.backend import meshgrid -from pyrecest.backend import linspace -from pyrecest.backend import array import unittest from warnings import catch_warnings, simplefilter -import numpy.testing as npt +import numpy.testing as npt +from pyrecest.backend import array, column_stack, diag, linspace, meshgrid from pyrecest.distributions import GaussianDistribution from pyrecest.distributions.nonperiodic.linear_mixture import LinearMixture @@ -46,4 +42,4 @@ def test_pdf(self): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/distributions/test_partially_wrapped_normal_distribution.py b/pyrecest/tests/distributions/test_partially_wrapped_normal_distribution.py index 36acea8b..40e2ebcf 100644 --- a/pyrecest/tests/distributions/test_partially_wrapped_normal_distribution.py +++ b/pyrecest/tests/distributions/test_partially_wrapped_normal_distribution.py @@ -1,9 +1,8 @@ -from pyrecest.backend import ones -from pyrecest.backend import array import unittest -import numpy.testing as npt +import numpy.testing as npt import scipy.linalg +from pyrecest.backend import array, ones from pyrecest.distributions.cart_prod.partially_wrapped_normal_distribution import ( PartiallyWrappedNormalDistribution, ) @@ -23,7 +22,9 @@ def test_hybrid_mean_2d(self): def test_hybrid_mean_4d(self): mu = array([5.0, 1.0, 3.0, 4.0]) - C = array(scipy.linalg.block_diag([[2.0, 1.0], [1.0, 1.0]], [[2.0, 1.0], [1.0, 1.0]])) + C = array( + scipy.linalg.block_diag([[2.0, 1.0], [1.0, 1.0]], [[2.0, 1.0], [1.0, 1.0]]) + ) dist = PartiallyWrappedNormalDistribution(mu, C, 2) npt.assert_allclose(dist.hybrid_mean(), mu) @@ -35,4 +36,4 @@ def test_hybrid_moment_2d(self): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/distributions/test_se3_dirac_distribution.py b/pyrecest/tests/distributions/test_se3_dirac_distribution.py index 70975073..7c67cf21 100644 --- a/pyrecest/tests/distributions/test_se3_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_se3_dirac_distribution.py @@ -1,12 +1,6 @@ -from pyrecest.backend import diag -from pyrecest.backend import linalg -from pyrecest.backend import tile -from pyrecest.backend import sum -from pyrecest.backend import concatenate -from pyrecest.backend import array import unittest - +from pyrecest.backend import array, concatenate, diag, linalg, sum, tile from pyrecest.distributions import ( GaussianDistribution, HyperhemisphericalUniformDistribution, @@ -37,11 +31,13 @@ def test_from_distribution(self): cpsd = SE3CartProdStackedDistribution( [ HyperhemisphericalUniformDistribution(3), - GaussianDistribution(array([1.0, 2.0, 3.0]).T, diag(array([3.0, 2.0, 1.0]))), + GaussianDistribution( + array([1.0, 2.0, 3.0]).T, diag(array([3.0, 2.0, 1.0])) + ), ] ) SE3DiracDistribution.from_distribution(cpsd, 100) if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/distributions/test_sphere_subset_distribution.py b/pyrecest/tests/distributions/test_sphere_subset_distribution.py index 08aceb40..81169e07 100644 --- a/pyrecest/tests/distributions/test_sphere_subset_distribution.py +++ b/pyrecest/tests/distributions/test_sphere_subset_distribution.py @@ -1,9 +1,9 @@ -from math import pi -from pyrecest.backend import array import unittest -import numpy.testing as npt +from math import pi +import numpy.testing as npt from parameterized import parameterized +from pyrecest.backend import array from pyrecest.distributions.hypersphere_subset.abstract_sphere_subset_distribution import ( AbstractSphereSubsetDistribution, ) @@ -58,4 +58,4 @@ def test_sph_to_cart_to_sph(self, mode): # The new spherical coordinates should be close to the original ones npt.assert_allclose(azimuth_new, azimuth, atol=1e-15) - npt.assert_allclose(theta_new, theta, atol=1e-15) \ No newline at end of file + npt.assert_allclose(theta_new, theta, atol=1e-15) diff --git a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py index 93d87a1f..f606b320 100644 --- a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py +++ b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py @@ -1,25 +1,25 @@ -from pyrecest.backend import column_stack -from pyrecest.backend import diff -from math import pi -from pyrecest.backend import random -from pyrecest.backend import sqrt -from pyrecest.backend import sin -from pyrecest.backend import ones_like -from pyrecest.backend import ones -from pyrecest.backend import meshgrid -from pyrecest.backend import linspace -from pyrecest.backend import isnan -from pyrecest.backend import exp -from pyrecest.backend import cos -from pyrecest.backend import array -from pyrecest.backend import allclose -from pyrecest.backend import all -from pyrecest.backend import zeros import unittest -import numpy.testing as npt - +from math import pi +import numpy.testing as npt from parameterized import parameterized +from pyrecest.backend import ( + all, + allclose, + array, + column_stack, + cos, + diff, + exp, + isnan, + linspace, + meshgrid, + ones_like, + random, + sin, + sqrt, + zeros, +) from pyrecest.distributions import VonMisesFisherDistribution from pyrecest.distributions.hypersphere_subset.abstract_spherical_distribution import ( AbstractSphericalDistribution, @@ -38,13 +38,13 @@ def setUp(self): coeff_rand = random.rand(9) self.unnormalized_coeffs = array( [ - [coeff_rand[0], float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [coeff_rand[0], float("NaN"), float("NaN"), float("NaN"), float("NaN")], [ coeff_rand[1] + 1j * coeff_rand[2], coeff_rand[3], -coeff_rand[1] + 1j * coeff_rand[2], - float('NaN'), - float('NaN'), + float("NaN"), + float("NaN"), ], [ coeff_rand[4] + 1j * coeff_rand[5], @@ -70,9 +70,7 @@ def test_normalization(self): random.rand(1, 10) * 2.0 * pi, random.rand(1, 10) * pi - pi / 2.0, ) - x, y, z = array( - [cos(theta) * cos(phi), cos(theta) * sin(phi), sin(theta)] - ) + x, y, z = array([cos(theta) * cos(phi), cos(theta) * sin(phi), sin(theta)]) vals_normalized = shd.pdf(column_stack([x, y, z])) shd.coeff_mat = self.unnormalized_coeffs vals_unnormalized = shd.pdf(column_stack([x, y, z])) @@ -91,13 +89,19 @@ def test_integral_analytical(self, transformation): coeff_rand = random.rand(1, 9) unnormalized_coeffs = array( [ - [coeff_rand[0, 0], float('NaN'), float('NaN'), float('NaN'), float('NaN')], + [ + coeff_rand[0, 0], + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + ], [ coeff_rand[0, 1] + 1j * coeff_rand[0, 2], coeff_rand[0, 3], -coeff_rand[0, 1] + 1j * coeff_rand[0, 2], - float('NaN'), - float('NaN'), + float("NaN"), + float("NaN"), ], [ coeff_rand[0, 4] + 1j * coeff_rand[0, 5], @@ -110,7 +114,7 @@ def test_integral_analytical(self, transformation): ) # First initialize and overwrite afterward to prevent normalization shd = SphericalHarmonicsDistributionComplex( - array([[1.0, float('NaN'), float('NaN')], [0.0, 0.0, 0.0]]) + array([[1.0, float("NaN"), float("NaN")], [0.0, 0.0, 0.0]]) ) shd.coeff_mat = unnormalized_coeffs shd.transformation = transformation @@ -124,9 +128,7 @@ def test_truncation(self): with self.assertWarns(UserWarning): shd2 = shd.truncate(4) self.assertEqual(shd2.coeff_mat.shape, (5, 9)) - self.assertTrue( - all(isnan(shd2.coeff_mat[4, :]) | (shd2.coeff_mat[4, :] == 0)) - ) + self.assertTrue(all(isnan(shd2.coeff_mat[4, :]) | (shd2.coeff_mat[4, :] == 0))) shd3 = shd.truncate(5) self.assertEqual(shd3.coeff_mat.shape, (6, 11)) self.assertTrue( @@ -178,8 +180,8 @@ def test_truncation(self): "testl0m0", array( [ - [1.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [1.0, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [0.0, 0.0, 0.0, float("NaN"), float("NaN")], [0.0, 0.0, 0.0, 0.0, 0.0], ] ), @@ -189,8 +191,8 @@ def test_truncation(self): "testl1m0", array( [ - [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 1.0, 0.0, float('NaN'), float('NaN')], + [0.0, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [0.0, 1.0, 0.0, float("NaN"), float("NaN")], [0.0, 0.0, 0.0, 0.0, 0.0], ] ), @@ -200,8 +202,8 @@ def test_truncation(self): "testl2m0", array( [ - [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [0.0, 0.0, 0.0, float("NaN"), float("NaN")], [0.0, 0.0, 1.0, 0.0, 0.0], ] ), @@ -214,9 +216,25 @@ def test_truncation(self): "testl3m0", array( [ - [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [ + 0.0, + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + ], + [ + 0.0, + 0.0, + 0.0, + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + ], + [0.0, 0.0, 0.0, 0.0, 0.0, float("NaN"), float("NaN")], [0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0], ] ), @@ -232,8 +250,14 @@ def test_truncation(self): "test_l1mneg1real", array( [ - [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [1j * sqrt(1 / 2), 0.0, 1j * sqrt(1 / 2), float('NaN'), float('NaN')], + [0.0, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [ + 1j * sqrt(1 / 2), + 0.0, + 1j * sqrt(1 / 2), + float("NaN"), + float("NaN"), + ], [0.0, 0.0, 0.0, 0.0, 0], ] ), @@ -243,8 +267,8 @@ def test_truncation(self): "test_l1m1real", array( [ - [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [sqrt(1 / 2), 0.0, -sqrt(1 / 2), float('NaN'), float('NaN')], + [0.0, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [sqrt(1 / 2), 0.0, -sqrt(1 / 2), float("NaN"), float("NaN")], [0.0, 0.0, 0.0, 0.0, 0], ] ), @@ -254,8 +278,8 @@ def test_truncation(self): "test_l2mneg2real", array( [ - [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [0.0, 0.0, 0.0, float("NaN"), float("NaN")], [1j * sqrt(1 / 2), 0.0, 0.0, 0.0, -1j * sqrt(1 / 2)], ] ), @@ -265,8 +289,8 @@ def test_truncation(self): "test_l2mneg1real", array( [ - [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [0.0, 0.0, 0.0, float("NaN"), float("NaN")], [0.0, 1j * sqrt(1 / 2), 0.0, 1j * sqrt(1 / 2), 0], ] ), @@ -276,8 +300,8 @@ def test_truncation(self): "test_l2m1real", array( [ - [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [0.0, 0.0, 0.0, float("NaN"), float("NaN")], [0.0, sqrt(1 / 2), 0.0, -sqrt(1 / 2), 0], ] ), @@ -287,8 +311,8 @@ def test_truncation(self): "test_l2m2real", array( [ - [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [0.0, 0.0, 0.0, float("NaN"), float("NaN")], [sqrt(1 / 2), 0.0, 0.0, 0.0, sqrt(1 / 2)], ] ), @@ -298,9 +322,25 @@ def test_truncation(self): "test_l3mneg3real", array( [ - [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [ + 0.0, + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + ], + [ + 0.0, + 0.0, + 0.0, + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + ], + [0.0, 0.0, 0.0, 0.0, 0.0, float("NaN"), float("NaN")], [1j / sqrt(2), 0.0, 0.0, 0.0, 0.0, 0.0, 1j / sqrt(2)], ] ), @@ -314,9 +354,25 @@ def test_truncation(self): "test_l3mneg2real", array( [ - [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [ + 0.0, + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + ], + [ + 0.0, + 0.0, + 0.0, + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + ], + [0.0, 0.0, 0.0, 0.0, 0.0, float("NaN"), float("NaN")], [0.0, 1j / sqrt(2), 0.0, 0.0, 0.0, -1j / sqrt(2), 0], ] ), @@ -326,9 +382,25 @@ def test_truncation(self): "test_l3mneg1real", array( [ - [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [ + 0.0, + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + ], + [ + 0.0, + 0.0, + 0.0, + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + ], + [0.0, 0.0, 0.0, 0.0, 0.0, float("NaN"), float("NaN")], [0.0, 0.0, 1j / sqrt(2), 0.0, 1j / sqrt(2), 0.0, 0], ] ), @@ -342,9 +414,25 @@ def test_truncation(self): "test_l3m1real", array( [ - [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [ + 0.0, + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + ], + [ + 0.0, + 0.0, + 0.0, + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + ], + [0.0, 0.0, 0.0, 0.0, 0.0, float("NaN"), float("NaN")], [0.0, 0.0, 1 / sqrt(2), 0.0, -1 / sqrt(2), 0.0, 0], ] ), @@ -358,9 +446,25 @@ def test_truncation(self): "test_l3m2real", array( [ - [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [ + 0.0, + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + ], + [ + 0.0, + 0.0, + 0.0, + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + ], + [0.0, 0.0, 0.0, 0.0, 0.0, float("NaN"), float("NaN")], [0.0, 1 / sqrt(2), 0.0, 0.0, 0.0, 1 / sqrt(2), 0], ] ), @@ -370,26 +474,36 @@ def test_truncation(self): "test_l3m3real", array( [ - [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [ + 0.0, + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + ], + [ + 0.0, + 0.0, + 0.0, + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + ], + [0.0, 0.0, 0.0, 0.0, 0.0, float("NaN"), float("NaN")], [1 / sqrt(2), 0.0, 0.0, 0.0, 0.0, 0.0, -1 / sqrt(2)], ] ), - lambda x, y, z: 1 - / 4 - * sqrt(35 / (2 * pi)) - * x - * (x**2 - 3 * y**2), + lambda x, y, z: 1 / 4 * sqrt(35 / (2 * pi)) * x * (x**2 - 3 * y**2), ), ] ) def test_basis_function(self, _, coeff_mat, expected_func): shd = SphericalHarmonicsDistributionComplex(1.0 / sqrt(4.0 * pi)) shd.coeff_mat = coeff_mat - phi, theta = meshgrid( - linspace(0.0, 2.0 * pi, 10), linspace(0.0, pi, 10) - ) + phi, theta = meshgrid(linspace(0.0, 2.0 * pi, 10), linspace(0.0, pi, 10)) x, y, z = AbstractSphericalDistribution.sph_to_cart(phi.ravel(), theta.ravel()) npt.assert_allclose( shd.pdf(column_stack([x, y, z])), expected_func(x, y, z), atol=1e-6 @@ -402,8 +516,8 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl1mneg1_cart", array( [ - [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [1, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [1, 0.0, 0.0, float("NaN"), float("NaN")], [0.0, 0.0, 0.0, 0.0, 0], ] ), @@ -413,8 +527,8 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl1m1_cart", array( [ - [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 1, float('NaN'), float('NaN')], + [0.0, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [0.0, 0.0, 1, float("NaN"), float("NaN")], [0.0, 0.0, 0.0, 0.0, 0], ] ), @@ -424,8 +538,8 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl2mneg2_cart", array( [ - [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [0.0, 0.0, 0.0, float("NaN"), float("NaN")], [1, 0.0, 0.0, 0.0, 0], ] ), @@ -435,8 +549,8 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl2mneg1_cart", array( [ - [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [0.0, 0.0, 0.0, float("NaN"), float("NaN")], [0.0, 1, 0.0, 0.0, 0], ] ), @@ -446,8 +560,8 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl2m1_cart", array( [ - [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [0.0, 0.0, 0.0, float("NaN"), float("NaN")], [0.0, 0.0, 0.0, 1, 0], ] ), @@ -457,8 +571,8 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl2m2_cart", array( [ - [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [0.0, 0.0, 0.0, float("NaN"), float("NaN")], [0.0, 0.0, 0.0, 0.0, 1], ] ), @@ -469,8 +583,8 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl1mneg1_sph", array( [ - [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [1, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [1, 0.0, 0.0, float("NaN"), float("NaN")], [0.0, 0.0, 0.0, 0.0, 0], ] ), @@ -483,8 +597,8 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl1m1_sph", array( [ - [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 1, float('NaN'), float('NaN')], + [0.0, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [0.0, 0.0, 1, float("NaN"), float("NaN")], [0.0, 0.0, 0.0, 0.0, 0], ] ), @@ -497,8 +611,8 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl2mneg2_sph", array( [ - [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [0.0, 0.0, 0.0, float("NaN"), float("NaN")], [1, 0.0, 0.0, 0.0, 0], ] ), @@ -511,8 +625,8 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl2mneg1_sph", array( [ - [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [0.0, 0.0, 0.0, float("NaN"), float("NaN")], [0.0, 1, 0.0, 0.0, 0], ] ), @@ -526,8 +640,8 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl2m1_sph", array( [ - [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [0.0, 0.0, 0.0, float("NaN"), float("NaN")], [0.0, 0.0, 0.0, 1, 0], ] ), @@ -541,8 +655,8 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl2m2_sph", array( [ - [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [0.0, 0.0, 0.0, float("NaN"), float("NaN")], [0.0, 0.0, 0.0, 0.0, 1], ] ), @@ -555,8 +669,8 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl1mneg1_sphconv_colatitude", array( [ - [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [1, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [1, 0.0, 0.0, float("NaN"), float("NaN")], [0.0, 0.0, 0.0, 0.0, 0], ] ), @@ -569,8 +683,8 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl1m1_sphconv_colatitude", array( [ - [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 1, float('NaN'), float('NaN')], + [0.0, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [0.0, 0.0, 1, float("NaN"), float("NaN")], [0.0, 0.0, 0.0, 0.0, 0], ] ), @@ -583,8 +697,8 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl2mneg2_sphconv_colatitude", array( [ - [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [0.0, 0.0, 0.0, float("NaN"), float("NaN")], [1, 0.0, 0.0, 0.0, 0], ] ), @@ -597,8 +711,8 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl2mneg1_sphconv_colatitude", array( [ - [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [0.0, 0.0, 0.0, float("NaN"), float("NaN")], [0.0, 1, 0.0, 0.0, 0], ] ), @@ -612,8 +726,8 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl2m1_sphconv_colatitude", array( [ - [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [0.0, 0.0, 0.0, float("NaN"), float("NaN")], [0.0, 0.0, 0.0, 1, 0], ] ), @@ -627,8 +741,8 @@ def test_basis_function(self, _, coeff_mat, expected_func): "testl2m2_sphconv_colatitude", array( [ - [0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [0.0, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [0.0, 0.0, 0.0, float("NaN"), float("NaN")], [0.0, 0.0, 0.0, 0.0, 1], ] ), @@ -640,13 +754,9 @@ def test_basis_function(self, _, coeff_mat, expected_func): ] ) def test_basis_function_complex(self, name, coeff_mat, expected_func): - shd = SphericalHarmonicsDistributionComplex( - 1 / sqrt(4 * pi), assert_real=False - ) + shd = SphericalHarmonicsDistributionComplex(1 / sqrt(4 * pi), assert_real=False) shd.coeff_mat = coeff_mat - phi, theta = meshgrid( - linspace(0.0, 2 * pi, 10), linspace(-pi / 2, pi / 2, 10) - ) + phi, theta = meshgrid(linspace(0.0, 2 * pi, 10), linspace(-pi / 2, pi / 2, 10)) x, y, z = AbstractSphericalDistribution.sph_to_cart(phi.ravel(), theta.ravel()) vals_to_test = shd.pdf(column_stack([x, y, z])) @@ -668,8 +778,8 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): "l0m0", array( [ - [1, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [1, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [0.0, 0.0, 0.0, float("NaN"), float("NaN")], [0.0, 0.0, 0.0, 0.0, 0], ] ), @@ -678,8 +788,14 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): "l1mneg1", array( [ - [1, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [1j * sqrt(1 / 2), 0.0, 1j * sqrt(1 / 2), float('NaN'), float('NaN')], + [1, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [ + 1j * sqrt(1 / 2), + 0.0, + 1j * sqrt(1 / 2), + float("NaN"), + float("NaN"), + ], [0.0, 0.0, 0.0, 0.0, 0], ] ), @@ -688,8 +804,8 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): "l1m0", array( [ - [1, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 1, 0.0, float('NaN'), float('NaN')], + [1, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [0.0, 1, 0.0, float("NaN"), float("NaN")], [0.0, 0.0, 0.0, 0.0, 0], ] ), @@ -698,8 +814,8 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): "l1m1", array( [ - [1, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [sqrt(1 / 2), 0.0, -sqrt(1 / 2), float('NaN'), float('NaN')], + [1, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [sqrt(1 / 2), 0.0, -sqrt(1 / 2), float("NaN"), float("NaN")], [0.0, 0.0, 0.0, 0.0, 0], ] ), @@ -708,8 +824,8 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): "l2mneg2", array( [ - [1, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [1, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [0.0, 0.0, 0.0, float("NaN"), float("NaN")], [1j * sqrt(1 / 2), 0.0, 0.0, 0.0, -1j * sqrt(1 / 2)], ] ), @@ -718,8 +834,8 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): "l2mneg1", array( [ - [1, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [1, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [0.0, 0.0, 0.0, float("NaN"), float("NaN")], [0.0, 1j * sqrt(1 / 2), 0.0, 1j * sqrt(1 / 2), 0], ] ), @@ -728,8 +844,8 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): "l2m0", array( [ - [1, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [1, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [0.0, 0.0, 0.0, float("NaN"), float("NaN")], [0.0, 0.0, 1, 0.0, 0], ] ), @@ -738,8 +854,8 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): "l2m1", array( [ - [1, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [1, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [0.0, 0.0, 0.0, float("NaN"), float("NaN")], [0.0, sqrt(1 / 2), 0.0, -sqrt(1 / 2), 0], ] ), @@ -748,8 +864,8 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): "l2m2", array( [ - [1, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [1, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [0.0, 0.0, 0.0, float("NaN"), float("NaN")], [sqrt(1 / 2), 0.0, 0.0, 0.0, sqrt(1 / 2)], ] ), @@ -758,9 +874,25 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): "l3mneg3", array( [ - [1, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [ + 1, + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + ], + [ + 0.0, + 0.0, + 0.0, + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + ], + [0.0, 0.0, 0.0, 0.0, 0.0, float("NaN"), float("NaN")], [1j / sqrt(2), 0.0, 0.0, 0.0, 0.0, 0.0, 1j / sqrt(2)], ] ), @@ -769,9 +901,25 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): "l3mneg2", array( [ - [1, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [ + 1, + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + ], + [ + 0.0, + 0.0, + 0.0, + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + ], + [0.0, 0.0, 0.0, 0.0, 0.0, float("NaN"), float("NaN")], [0.0, 1j / sqrt(2), 0.0, 0.0, 0.0, -1j / sqrt(2), 0], ] ), @@ -780,9 +928,25 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): "l3mneg1", array( [ - [1, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [ + 1, + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + ], + [ + 0.0, + 0.0, + 0.0, + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + ], + [0.0, 0.0, 0.0, 0.0, 0.0, float("NaN"), float("NaN")], [0.0, 0.0, 1j / sqrt(2), 0.0, 1j / sqrt(2), 0.0, 0], ] ), @@ -791,9 +955,25 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): "l3m0", array( [ - [1, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [ + 1, + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + ], + [ + 0.0, + 0.0, + 0.0, + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + ], + [0.0, 0.0, 0.0, 0.0, 0.0, float("NaN"), float("NaN")], [0.0, 0.0, 0.0, 1, 0.0, 0.0, 0], ] ), @@ -802,9 +982,25 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): "l3m1", array( [ - [1, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [ + 1, + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + ], + [ + 0.0, + 0.0, + 0.0, + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + ], + [0.0, 0.0, 0.0, 0.0, 0.0, float("NaN"), float("NaN")], [0.0, 0.0, 1 / sqrt(2), 0.0, -1 / sqrt(2), 0.0, 0], ] ), @@ -813,9 +1009,25 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): "l3m2", array( [ - [1, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [ + 1, + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + ], + [ + 0.0, + 0.0, + 0.0, + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + ], + [0.0, 0.0, 0.0, 0.0, 0.0, float("NaN"), float("NaN")], [0.0, 1 / sqrt(2), 0.0, 0.0, 0.0, 1 / sqrt(2), 0], ] ), @@ -824,9 +1036,25 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): "l3m3", array( [ - [1, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0.0, 0.0, 0.0, 0.0, 0.0, float('NaN'), float('NaN')], + [ + 1, + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + ], + [ + 0.0, + 0.0, + 0.0, + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + ], + [0.0, 0.0, 0.0, 0.0, 0.0, float("NaN"), float("NaN")], [1 / sqrt(2), 0.0, 0.0, 0.0, 0.0, 0.0, -1 / sqrt(2)], ] ), @@ -836,9 +1064,7 @@ def test_basis_function_complex(self, name, coeff_mat, expected_func): def test_conversion(self, _, coeff_mat): shd = SphericalHarmonicsDistributionComplex(coeff_mat) rshd = shd.to_spherical_harmonics_distribution_real() - phi, theta = meshgrid( - linspace(0.0, 2 * pi, 10), linspace(-pi / 2, pi / 2, 10) - ) + phi, theta = meshgrid(linspace(0.0, 2 * pi, 10), linspace(-pi / 2, pi / 2, 10)) x, y, z = AbstractSphericalDistribution.sph_to_cart(phi.ravel(), theta.ravel()) npt.assert_allclose( rshd.pdf(column_stack((x, y, z))), @@ -850,21 +1076,26 @@ def test_conversion(self, _, coeff_mat): [ ( "shd_x", - array([[1, float('NaN'), float('NaN')], [sqrt(1 / 2), 0.0, -sqrt(1 / 2)]]), + array( + [[1, float("NaN"), float("NaN")], [sqrt(1 / 2), 0.0, -sqrt(1 / 2)]] + ), array([1, 0.0, 0]), SphericalHarmonicsDistributionComplex.mean_direction, ), ( "shd_y", array( - [[1, float('NaN'), float('NaN')], [1j * sqrt(1 / 2), 0.0, 1j * sqrt(1 / 2)]] + [ + [1, float("NaN"), float("NaN")], + [1j * sqrt(1 / 2), 0.0, 1j * sqrt(1 / 2)], + ] ), array([0.0, 1, 0]), SphericalHarmonicsDistributionComplex.mean_direction, ), ( "shd_z", - array([[1, float('NaN'), float('NaN')], [0.0, 1, 0]]), + array([[1, float("NaN"), float("NaN")], [0.0, 1, 0]]), array([0.0, 0.0, 1]), SphericalHarmonicsDistributionComplex.mean_direction, ), @@ -872,7 +1103,7 @@ def test_conversion(self, _, coeff_mat): "shd_xy", array( [ - [1, float('NaN'), float('NaN')], + [1, float("NaN"), float("NaN")], [ sqrt(1.0 / 2.0) + 1j * sqrt(1.0 / 2.0), 0.0, @@ -885,33 +1116,44 @@ def test_conversion(self, _, coeff_mat): ), ( "shd_xz", - array([[1.0, float('NaN'), float('NaN')], [sqrt(1 / 2), 1, -sqrt(1.0 / 2.0)]]), - array([1., 0.0, 1.0]) / sqrt(2.0), + array( + [ + [1.0, float("NaN"), float("NaN")], + [sqrt(1 / 2), 1, -sqrt(1.0 / 2.0)], + ] + ), + array([1.0, 0.0, 1.0]) / sqrt(2.0), SphericalHarmonicsDistributionComplex.mean_direction, ), ( "shd_yz", array( - [[1, float('NaN'), float('NaN')], [1j * sqrt(1 / 2), 1, 1j * sqrt(1 / 2)]] + [ + [1, float("NaN"), float("NaN")], + [1j * sqrt(1 / 2), 1, 1j * sqrt(1 / 2)], + ] ), array([0.0, 1.0, 1.0]) / sqrt(2.0), SphericalHarmonicsDistributionComplex.mean_direction, ), ( "numerical_shd_x", - [[1, float('NaN'), float('NaN')], [sqrt(1 / 2), 0.0, -sqrt(1 / 2)]], + [[1, float("NaN"), float("NaN")], [sqrt(1 / 2), 0.0, -sqrt(1 / 2)]], [1, 0.0, 0.0], SphericalHarmonicsDistributionComplex.mean_direction_numerical, ), ( "numerical_shd_y", - [[1.0, float('NaN'), float('NaN')], [1j * sqrt(1 / 2), 0.0, 1j * sqrt(1.0 / 2.0)]], + [ + [1.0, float("NaN"), float("NaN")], + [1j * sqrt(1 / 2), 0.0, 1j * sqrt(1.0 / 2.0)], + ], [0.0, 1.0, 0.0], SphericalHarmonicsDistributionComplex.mean_direction_numerical, ), ( "numerical_shd_z", - [[1.0, float('NaN'), float('NaN')], [0.0, 1.0, 0]], + [[1.0, float("NaN"), float("NaN")], [0.0, 1.0, 0]], [0.0, 0.0, 1.0], SphericalHarmonicsDistributionComplex.mean_direction_numerical, ), @@ -923,7 +1165,9 @@ def test_mean_direction(self, _, input_array, expected_output, fun_to_test): def test_from_distribution_via_integral_vmf(self): # Test approximating a VMF - dist = VonMisesFisherDistribution(array([-1.0, -1.0, 0.0]) / sqrt(2.0), array(1.0)) + dist = VonMisesFisherDistribution( + array([-1.0, -1.0, 0.0]) / sqrt(2.0), array(1.0) + ) shd = SphericalHarmonicsDistributionComplex.from_distribution_via_integral( dist, 3 ) @@ -931,9 +1175,7 @@ def test_from_distribution_via_integral_vmf(self): linspace(0.0, 2.0 * pi, 10), linspace(-pi / 2.0, pi / 2.0, 10) ) x, y, z = AbstractSphericalDistribution.sph_to_cart(phi.ravel(), theta.ravel()) - npt.assert_allclose( - shd.mean_direction(), dist.mean_direction(), atol=1e-10 - ) + npt.assert_allclose(shd.mean_direction(), dist.mean_direction(), atol=1e-10) npt.assert_allclose( shd.mean_direction_numerical(), dist.mean_direction(), atol=1e-10 ) @@ -955,7 +1197,7 @@ def test_from_distribution_via_integral_uniform(self): def test_transformation_via_integral_shd(self): # Test approximating a spherical harmonic distribution dist = SphericalHarmonicsDistributionComplex( - array([[1, float('NaN'), float('NaN')], [0.0, 1, 0]]) + array([[1, float("NaN"), float("NaN")], [0.0, 1, 0]]) ) shd = SphericalHarmonicsDistributionComplex.from_function_via_integral_cart( @@ -979,16 +1221,20 @@ def test_convergence(self): @parameterized.expand( [ - ("zplus", [[1 / sqrt(4 * pi), float('NaN'), float('NaN')], [0.0, 1, 0]], [0.0, 0.0, 1]), + ( + "zplus", + [[1 / sqrt(4 * pi), float("NaN"), float("NaN")], [0.0, 1, 0]], + [0.0, 0.0, 1], + ), ( "zminus", - [[1 / sqrt(4 * pi), float('NaN'), float('NaN')], [0.0, -1, 0]], + [[1 / sqrt(4 * pi), float("NaN"), float("NaN")], [0.0, -1, 0]], [0.0, 0.0, -1], ), ( "yplus", [ - [1 / sqrt(4 * pi), float('NaN'), float('NaN')], + [1 / sqrt(4 * pi), float("NaN"), float("NaN")], [1j * sqrt(1 / 2), 0.0, 1j * sqrt(1 / 2)], ], [0.0, 1, 0], @@ -996,7 +1242,7 @@ def test_convergence(self): ( "yminus", [ - [1 / sqrt(4 * pi), float('NaN'), float('NaN')], + [1 / sqrt(4 * pi), float("NaN"), float("NaN")], [-1j * sqrt(1 / 2), 0.0, -1j * sqrt(1 / 2)], ], [0.0, -1, 0], @@ -1004,7 +1250,7 @@ def test_convergence(self): ( "xplus", [ - [1 / sqrt(4 * pi), float('NaN'), float('NaN')], + [1 / sqrt(4 * pi), float("NaN"), float("NaN")], [sqrt(1 / 2), 0.0, -sqrt(1 / 2)], ], [1, 0.0, 0], @@ -1012,7 +1258,7 @@ def test_convergence(self): ( "xminus", [ - [1 / sqrt(4 * pi), float('NaN'), float('NaN')], + [1 / sqrt(4 * pi), float("NaN"), float("NaN")], [-sqrt(1 / 2), 0.0, sqrt(1 / 2)], ], [-1, 0.0, 0], @@ -1020,7 +1266,7 @@ def test_convergence(self): ( "xyplus", [ - [1 / sqrt(4 * pi), float('NaN'), float('NaN')], + [1 / sqrt(4 * pi), float("NaN"), float("NaN")], [ 1j * sqrt(1 / 2) + sqrt(1 / 2), 1, @@ -1032,7 +1278,7 @@ def test_convergence(self): ( "xyminus", [ - [1.0 / sqrt(4 * pi), float('NaN'), float('NaN')], + [1.0 / sqrt(4 * pi), float("NaN"), float("NaN")], [ -1j * sqrt(1 / 2) - sqrt(1.0 / 2.0), 0.0, @@ -1049,4 +1295,4 @@ def test_mean(self, _, coeff_mat, expected_output): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py index ab59b8d7..6dab9881 100644 --- a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py +++ b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py @@ -1,19 +1,19 @@ -from pyrecest.backend import diff -from math import pi -from pyrecest.backend import random -from pyrecest.backend import sqrt -from pyrecest.backend import ones_like -from pyrecest.backend import ones -from pyrecest.backend import array -from pyrecest.backend import allclose -from pyrecest.backend import all -from pyrecest.backend import zeros -from pyrecest.backend import column_stack import unittest import warnings -import numpy.testing as npt +from math import pi +import numpy.testing as npt from parameterized import parameterized +from pyrecest.backend import ( + allclose, + array, + column_stack, + diff, + ones_like, + random, + sqrt, + zeros, +) from pyrecest.distributions.hypersphere_subset.abstract_spherical_distribution import ( AbstractSphericalDistribution, ) @@ -54,8 +54,8 @@ def testNormalization(self): ( "l0m0", [ - [1, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN')], + [1, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [0, 0, 0, float("NaN"), float("NaN")], [0, 0, 0, 0, 0], ], lambda x, _, __: ones_like(x) * sqrt(1 / (4 * pi)), @@ -63,8 +63,8 @@ def testNormalization(self): ( "l1mneg1", [ - [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [1, 0, 0, float('NaN'), float('NaN')], + [0, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [1, 0, 0, float("NaN"), float("NaN")], [0, 0, 0, 0, 0], ], lambda _, y, __: sqrt(3 / (4 * pi)) * y, @@ -72,8 +72,8 @@ def testNormalization(self): ( "l1_m0", [ - [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 1, 0, float('NaN'), float('NaN')], + [0, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [0, 1, 0, float("NaN"), float("NaN")], [0, 0, 0, 0, 0], ], lambda _, __, z: sqrt(3 / (4 * pi)) * z, @@ -81,8 +81,8 @@ def testNormalization(self): ( "l1_m1", [ - [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 1, float('NaN'), float('NaN')], + [0, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [0, 0, 1, float("NaN"), float("NaN")], [0, 0, 0, 0, 0], ], lambda x, _, __: sqrt(3 / (4 * pi)) * x, @@ -90,8 +90,8 @@ def testNormalization(self): ( "l2_mneg2", [ - [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN')], + [0, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [0, 0, 0, float("NaN"), float("NaN")], [1, 0, 0, 0, 0], ], lambda x, y, __: 1 / 2 * sqrt(15 / pi) * x * y, @@ -99,8 +99,8 @@ def testNormalization(self): ( "l2_mneg1", [ - [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN')], + [0, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [0, 0, 0, float("NaN"), float("NaN")], [0, 1, 0, 0, 0], ], lambda _, y, z: 1 / 2 * sqrt(15 / pi) * y * z, @@ -108,20 +108,17 @@ def testNormalization(self): ( "l2_m0", [ - [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN')], + [0, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [0, 0, 0, float("NaN"), float("NaN")], [0, 0, 1, 0, 0], ], - lambda x, y, z: 1 - / 4 - * sqrt(5 / pi) - * (2 * z**2 - x**2 - y**2), + lambda x, y, z: 1 / 4 * sqrt(5 / pi) * (2 * z**2 - x**2 - y**2), ), ( "l2_m1", [ - [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN')], + [0, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [0, 0, 0, float("NaN"), float("NaN")], [0, 0, 0, 1, 0], ], lambda x, _, z: 1 / 2 * sqrt(15 / pi) * x * z, @@ -129,8 +126,8 @@ def testNormalization(self): ( "l2_m2", [ - [0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN')], + [0, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [0, 0, 0, float("NaN"), float("NaN")], [0, 0, 0, 0, 1], ], lambda x, y, _: 1 / 4 * sqrt(15 / pi) * (x**2 - y**2), @@ -161,8 +158,8 @@ def _gen_naive_grid(n_per_dim): "l0_m0", array( [ - [1, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN')], + [1, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [0, 0, 0, float("NaN"), float("NaN")], [0, 0, 0, 0, 0], ] ), @@ -171,8 +168,8 @@ def _gen_naive_grid(n_per_dim): "l1_mneg1", array( [ - [1, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [1, 0, 0, float('NaN'), float('NaN')], + [1, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [1, 0, 0, float("NaN"), float("NaN")], [0, 0, 0, 0, 0], ] ), @@ -181,8 +178,8 @@ def _gen_naive_grid(n_per_dim): "l1_m0", array( [ - [1, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 1, 0, float('NaN'), float('NaN')], + [1, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [0, 1, 0, float("NaN"), float("NaN")], [0, 0, 0, 0, 0], ] ), @@ -191,8 +188,8 @@ def _gen_naive_grid(n_per_dim): "l1_m1", array( [ - [1, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 1, float('NaN'), float('NaN')], + [1, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [0, 0, 1, float("NaN"), float("NaN")], [0, 0, 0, 0, 0], ] ), @@ -201,8 +198,8 @@ def _gen_naive_grid(n_per_dim): "l2_mneg2", array( [ - [1, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN')], + [1, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [0, 0, 0, float("NaN"), float("NaN")], [1, 0, 0, 0, 0], ] ), @@ -211,8 +208,8 @@ def _gen_naive_grid(n_per_dim): "l2_mneg1", array( [ - [1, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN')], + [1, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [0, 0, 0, float("NaN"), float("NaN")], [0, 1, 0, 0, 0], ] ), @@ -221,8 +218,8 @@ def _gen_naive_grid(n_per_dim): "l2_m0", array( [ - [1, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN')], + [1, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [0, 0, 0, float("NaN"), float("NaN")], [0, 0, 1, 0, 0], ] ), @@ -231,8 +228,8 @@ def _gen_naive_grid(n_per_dim): "l2_m1", array( [ - [1, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN')], + [1, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [0, 0, 0, float("NaN"), float("NaN")], [0, 0, 0, 1, 0], ] ), @@ -241,8 +238,8 @@ def _gen_naive_grid(n_per_dim): "l2_m2", array( [ - [1, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN')], + [1, float("NaN"), float("NaN"), float("NaN"), float("NaN")], + [0, 0, 0, float("NaN"), float("NaN")], [0, 0, 0, 0, 1], ] ), @@ -251,9 +248,25 @@ def _gen_naive_grid(n_per_dim): "l3_mneg3", array( [ - [1, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, 0, 0, float('NaN'), float('NaN')], + [ + 1, + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + ], + [ + 0, + 0, + 0, + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + ], + [0, 0, 0, 0, 0, float("NaN"), float("NaN")], [1, 0, 0, 0, 0, 0, 0], ] ), @@ -262,9 +275,25 @@ def _gen_naive_grid(n_per_dim): "l3_mneg2", array( [ - [1, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, 0, 0, float('NaN'), float('NaN')], + [ + 1, + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + ], + [ + 0, + 0, + 0, + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + ], + [0, 0, 0, 0, 0, float("NaN"), float("NaN")], [0, 1, 0, 0, 0, 0, 0], ] ), @@ -273,9 +302,25 @@ def _gen_naive_grid(n_per_dim): "l3_mneg1", array( [ - [1, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, 0, 0, float('NaN'), float('NaN')], + [ + 1, + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + ], + [ + 0, + 0, + 0, + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + ], + [0, 0, 0, 0, 0, float("NaN"), float("NaN")], [0, 0, 1, 0, 0, 0, 0], ] ), @@ -284,9 +329,25 @@ def _gen_naive_grid(n_per_dim): "l3_m0", array( [ - [1, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, 0, 0, float('NaN'), float('NaN')], + [ + 1, + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + ], + [ + 0, + 0, + 0, + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + ], + [0, 0, 0, 0, 0, float("NaN"), float("NaN")], [0, 0, 0, 1, 0, 0, 0], ] ), @@ -295,9 +356,25 @@ def _gen_naive_grid(n_per_dim): "l3_m1", array( [ - [1, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, 0, 0, float('NaN'), float('NaN')], + [ + 1, + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + ], + [ + 0, + 0, + 0, + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + ], + [0, 0, 0, 0, 0, float("NaN"), float("NaN")], [0, 0, 0, 0, 1, 0, 0], ] ), @@ -306,9 +383,25 @@ def _gen_naive_grid(n_per_dim): "l3_m2", array( [ - [1, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, 0, 0, float('NaN'), float('NaN')], + [ + 1, + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + ], + [ + 0, + 0, + 0, + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + ], + [0, 0, 0, 0, 0, float("NaN"), float("NaN")], [0, 0, 0, 0, 0, 1, 0], ] ), @@ -317,9 +410,25 @@ def _gen_naive_grid(n_per_dim): "l3_m3", array( [ - [1, float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, float('NaN'), float('NaN'), float('NaN'), float('NaN')], - [0, 0, 0, 0, 0, float('NaN'), float('NaN')], + [ + 1, + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + ], + [ + 0, + 0, + 0, + float("NaN"), + float("NaN"), + float("NaN"), + float("NaN"), + ], + [0, 0, 0, 0, 0, float("NaN"), float("NaN")], [0, 0, 0, 0, 0, 0, 1], ] ), @@ -349,9 +458,7 @@ def test_conversion_to_complex_and_back(self): cshd = rshd.to_spherical_harmonics_distribution_complex() rshd2 = cshd.to_spherical_harmonics_distribution_real() - npt.assert_allclose( - rshd2.coeff_mat, rshd.coeff_mat, atol=1e-6, equal_nan=True - ) + npt.assert_allclose(rshd2.coeff_mat, rshd.coeff_mat, atol=1e-6, equal_nan=True) def test_integral_analytical(self): # Suppress warnings related to normalization @@ -360,10 +467,8 @@ def test_integral_analytical(self): warnings.simplefilter("ignore") shd = SphericalHarmonicsDistributionReal(unnormalized_coeffs) - npt.assert_allclose( - shd.integrate_numerically(), shd.integrate(), atol=1e-6 - ) + npt.assert_allclose(shd.integrate_numerically(), shd.integrate(), atol=1e-6) if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/distributions/test_toroidal_uniform_distribution.py b/pyrecest/tests/distributions/test_toroidal_uniform_distribution.py index 56a65280..e00922d3 100644 --- a/pyrecest/tests/distributions/test_toroidal_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_toroidal_uniform_distribution.py @@ -1,14 +1,8 @@ -from math import pi -from pyrecest.backend import tile -from pyrecest.backend import ones -from pyrecest.backend import array -from pyrecest.backend import allclose -from pyrecest.backend import all -from pyrecest.backend import zeros -import pyrecest.backend import unittest +from math import pi - +import pyrecest.backend +from pyrecest.backend import all, allclose, array, ones, tile, zeros from pyrecest.distributions.hypertorus.toroidal_uniform_distribution import ( ToroidalUniformDistribution, ) @@ -21,9 +15,7 @@ def setUp(self): def test_pdf(self): self.assertTrue( - allclose( - self.tud.pdf(self.x), (1 / (2 * pi) ** 2) * ones(self.x.shape[1]) - ) + allclose(self.tud.pdf(self.x), (1 / (2 * pi) ** 2) * ones(self.x.shape[1])) ) def test_shift(self): @@ -46,15 +38,11 @@ def test_trigonometric_moments(self): ) if k == 0: self.assertTrue( - allclose( - self.tud.trigonometric_moment(k), ones(2), rtol=1e-10 - ) + allclose(self.tud.trigonometric_moment(k), ones(2), rtol=1e-10) ) else: self.assertTrue( - allclose( - self.tud.trigonometric_moment(k), zeros(2), rtol=1e-10 - ) + allclose(self.tud.trigonometric_moment(k), zeros(2), rtol=1e-10) ) def test_mean_direction(self): @@ -66,7 +54,10 @@ def test_mean_direction(self): "Hypertoroidal uniform distributions do not have a unique mean", ) - @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") + @unittest.skipIf( + pyrecest.backend.__name__ == "pyrecest.pytorch", + reason="Not supported on PyTorch backend", + ) def test_entropy(self): self.assertAlmostEqual( self.tud.entropy(), self.tud.entropy_numerical(), delta=1e-10 @@ -81,4 +72,4 @@ def test_sampling(self): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/distributions/test_toroidal_von_mises_sine_distribution.py b/pyrecest/tests/distributions/test_toroidal_von_mises_sine_distribution.py index 1eb02af9..48275bfe 100644 --- a/pyrecest/tests/distributions/test_toroidal_von_mises_sine_distribution.py +++ b/pyrecest/tests/distributions/test_toroidal_von_mises_sine_distribution.py @@ -1,16 +1,10 @@ -from pyrecest.backend import column_stack -from math import pi -from pyrecest.backend import sin -from pyrecest.backend import exp -from pyrecest.backend import cos -from pyrecest.backend import array -from pyrecest.backend import arange -import pyrecest.backend import unittest -import numpy.testing as npt - +from math import pi +import numpy.testing as npt +import pyrecest.backend from parameterized import parameterized +from pyrecest.backend import arange, array, column_stack, cos, exp, sin from pyrecest.distributions.hypertorus.toroidal_von_mises_sine_distribution import ( ToroidalVonMisesSineDistribution, ) @@ -32,7 +26,10 @@ def test_mu_kappa_lambda(self): npt.assert_allclose(self.tvm.kappa, self.kappa) self.assertEqual(self.tvm.lambda_, self.lambda_) - @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") + @unittest.skipIf( + pyrecest.backend.__name__ == "pyrecest.pytorch", + reason="Not supported on PyTorch backend", + ) def test_integral(self): # test integral self.assertAlmostEqual(self.tvm.integrate(), 1.0, delta=1e-5) @@ -48,9 +45,7 @@ def _unnormalized_pdf(self, xs): return exp( self.kappa[0] * cos(xs[..., 0] - self.mu[0]) + self.kappa[1] * cos(xs[..., 1] - self.mu[1]) - + self.lambda_ - * sin(xs[..., 0] - self.mu[0]) - * sin(xs[..., 1] - self.mu[1]) + + self.lambda_ * sin(xs[..., 0] - self.mu[0]) * sin(xs[..., 1] - self.mu[1]) ) # jscpd:ignore-end @@ -81,4 +76,4 @@ def pdf(x): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/distributions/test_toroidal_wrapped_normal_distribution.py b/pyrecest/tests/distributions/test_toroidal_wrapped_normal_distribution.py index d70bc27f..dc7a42c0 100644 --- a/pyrecest/tests/distributions/test_toroidal_wrapped_normal_distribution.py +++ b/pyrecest/tests/distributions/test_toroidal_wrapped_normal_distribution.py @@ -1,12 +1,8 @@ -from math import pi -from pyrecest.backend import mod -from pyrecest.backend import array -from pyrecest.backend import allclose -from pyrecest.backend import all import unittest -import pyrecest.backend - +from math import pi +import pyrecest.backend +from pyrecest.backend import allclose, array, mod from pyrecest.distributions.hypertorus.toroidal_wrapped_normal_distribution import ( ToroidalWrappedNormalDistribution, ) @@ -23,7 +19,10 @@ def test_sanity_check(self): self.assertTrue(allclose(self.twn.mu, self.mu)) self.assertTrue(allclose(self.twn.C, self.C)) - @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") + @unittest.skipIf( + pyrecest.backend.__name__ == "pyrecest.pytorch", + reason="Not supported on PyTorch backend", + ) def test_integrate(self): self.assertAlmostEqual(self.twn.integrate(), 1, delta=1e-5) self.assertTrue( @@ -38,4 +37,4 @@ def test_sampling(self): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/distributions/test_von_mises_distribution.py b/pyrecest/tests/distributions/test_von_mises_distribution.py index c99634b8..5f5e9e99 100644 --- a/pyrecest/tests/distributions/test_von_mises_distribution.py +++ b/pyrecest/tests/distributions/test_von_mises_distribution.py @@ -1,12 +1,11 @@ -from pyrecest.backend import linspace -from pyrecest.backend import array import unittest import matplotlib import matplotlib.pyplot as plt - -from pyrecest.distributions import VonMisesDistribution import numpy.testing as npt +from pyrecest.backend import array, linspace +from pyrecest.distributions import VonMisesDistribution + matplotlib.use("Agg") @@ -42,4 +41,4 @@ def test_plot(self): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py b/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py index 15834536..c7d44e45 100644 --- a/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py +++ b/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py @@ -1,13 +1,8 @@ -from pyrecest.backend import linalg -from pyrecest.backend import sqrt -from pyrecest.backend import array -from pyrecest.backend import allclose -from pyrecest.backend import all -from pyrecest.backend import empty_like import unittest -import numpy.testing as npt +import numpy.testing as npt from parameterized import parameterized +from pyrecest.backend import allclose, array, linalg, sqrt from pyrecest.distributions import VonMisesFisherDistribution from pyrecest.distributions.hypersphere_subset.hyperspherical_dirac_distribution import ( HypersphericalDiracDistribution, @@ -31,7 +26,9 @@ def setUp(self): self.mu = self.mu / linalg.norm(self.mu) self.kappa = 2 self.vmf = VonMisesFisherDistribution(self.mu, self.kappa) - self.other = VonMisesFisherDistribution(array([0.0, 0.0, 1.0]), self.kappa / 3.0) + self.other = VonMisesFisherDistribution( + array([0.0, 0.0, 1.0]), self.kappa / 3.0 + ) def test_vmf_distribution_3d_sanity_check(self): self.assertIsInstance(self.vmf, VonMisesFisherDistribution) @@ -40,9 +37,7 @@ def test_vmf_distribution_3d_sanity_check(self): self.assertEqual(self.vmf.dim + 1, len(self.mu)) def test_vmf_distribution_3d_mode(self): - self.assertTrue( - allclose(self.vmf.mode_numerical(), self.vmf.mode(), atol=1e-5) - ) + self.assertTrue(allclose(self.vmf.mode_numerical(), self.vmf.mode(), atol=1e-5)) def test_vmf_distribution_3d_integral(self): self.assertAlmostEqual(self.vmf.integrate(), 1, delta=1e-5) @@ -51,7 +46,8 @@ def test_vmf_distribution_3d_multiplication(self): vmf_mul = self.vmf.multiply(self.other) vmf_mul2 = self.other.multiply(self.vmf) c = vmf_mul.pdf(array([1.0, 0.0, 0.0])) / ( - self.vmf.pdf(array([1.0, 0.0, 0.0])) * self.other.pdf(array([1.0, 0.0, 0.0])) + self.vmf.pdf(array([1.0, 0.0, 0.0])) + * self.other.pdf(array([1.0, 0.0, 0.0])) ) x = array([0.0, 1.0, 0.0]) self.assertAlmostEqual( @@ -196,7 +192,12 @@ def test_from_distribution_vmf(self, _, mu, kappa): def test_from_distribution_dirac(self): dirac_dist = HypersphericalDiracDistribution( array( - [[0.0, 0.0, 1.0], [0.0, 1.0, 0.0], [1.0, 0.0, 0.0], array([0.0, 1.0, 1.0]) / linalg.norm(array([0.0, 1.0, 1.0]))] + [ + [0.0, 0.0, 1.0], + [0.0, 1.0, 0.0], + [1.0, 0.0, 0.0], + array([0.0, 1.0, 1.0]) / linalg.norm(array([0.0, 1.0, 1.0])), + ] ) ) vmf = VonMisesFisherDistribution.from_distribution(dirac_dist) @@ -205,4 +206,4 @@ def test_from_distribution_dirac(self): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/distributions/test_watson_distribution.py b/pyrecest/tests/distributions/test_watson_distribution.py index 5ebb7f1b..2cafc051 100644 --- a/pyrecest/tests/distributions/test_watson_distribution.py +++ b/pyrecest/tests/distributions/test_watson_distribution.py @@ -1,15 +1,21 @@ -from pyrecest.backend import linalg -from pyrecest.backend import array import unittest -import numpy.testing as npt +import numpy.testing as npt +from pyrecest.backend import array, linalg from pyrecest.distributions import BinghamDistribution, WatsonDistribution class TestWatsonDistribution(unittest.TestCase): def setUp(self): self.xs = array( - [[1.0, 0.0, 0.0], [1.0, 2.0, 2.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0], [1.0, 1.0, 1.0], [-1.0, -1.0, -1.0]], + [ + [1.0, 0.0, 0.0], + [1.0, 2.0, 2.0], + [0.0, 1.0, 0.0], + [0.0, 0.0, 1.0], + [1.0, 1.0, 1.0], + [-1.0, -1.0, -1.0], + ], dtype=float, ) self.xs = self.xs / linalg.norm(self.xs, axis=1).reshape((-1, 1)) @@ -64,4 +70,4 @@ def test_to_bingham(self): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/distributions/test_wrapped_cauchy_distribution.py b/pyrecest/tests/distributions/test_wrapped_cauchy_distribution.py index a0a04645..54bed81c 100644 --- a/pyrecest/tests/distributions/test_wrapped_cauchy_distribution.py +++ b/pyrecest/tests/distributions/test_wrapped_cauchy_distribution.py @@ -1,10 +1,9 @@ -from math import pi -from pyrecest.backend import array -from pyrecest.backend import arange import unittest +from math import pi + import numpy.testing as npt import pyrecest.backend - +from pyrecest.backend import arange, array from pyrecest.distributions.circle.custom_circular_distribution import ( CustomCircularDistribution, ) @@ -25,9 +24,7 @@ def test_pdf(self): def pdf_wrapped(x, mu, gamma, terms=2000): summation = 0 for k in range(-terms, terms + 1): - summation += gamma / ( - pi * (gamma**2 + (x - mu + 2.0 * pi * k) ** 2) - ) + summation += gamma / (pi * (gamma**2 + (x - mu + 2.0 * pi * k) ** 2)) return summation custom_wrapped = CustomCircularDistribution( @@ -38,13 +35,14 @@ def pdf_wrapped(x, mu, gamma, terms=2000): dist.pdf(xs=self.xs), custom_wrapped.pdf(xs=self.xs), atol=0.0001 ) - @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") + @unittest.skipIf( + pyrecest.backend.__name__ == "pyrecest.pytorch", + reason="Not supported on PyTorch backend", + ) def test_cdf(self): dist = WrappedCauchyDistribution(self.mu, self.gamma) - npt.assert_allclose( - dist.cdf(array([1.0])), dist.integrate(array([0.0, 1.0])) - ) + npt.assert_allclose(dist.cdf(array([1.0])), dist.integrate(array([0.0, 1.0]))) if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/distributions/test_wrapped_laplace_distribution.py b/pyrecest/tests/distributions/test_wrapped_laplace_distribution.py index 10d9819e..5cb50e79 100644 --- a/pyrecest/tests/distributions/test_wrapped_laplace_distribution.py +++ b/pyrecest/tests/distributions/test_wrapped_laplace_distribution.py @@ -1,12 +1,9 @@ -from math import pi -from pyrecest.backend import linspace -from pyrecest.backend import exp -from pyrecest.backend import arange -from pyrecest.backend import array -import pyrecest.backend import unittest -import numpy.testing as npt +from math import pi +import numpy.testing as npt +import pyrecest.backend +from pyrecest.backend import arange, array, exp, linspace from pyrecest.distributions.circle.wrapped_laplace_distribution import ( WrappedLaplaceDistribution, ) @@ -38,12 +35,16 @@ def pdftemp(x): for x in [0.0, 1.0, 2.0, 3.0, 4.0]: npt.assert_allclose(self.wl.pdf(array(x)), pdftemp(array(x)), rtol=1e-10) - @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") + @unittest.skipIf( + pyrecest.backend.__name__ == "pyrecest.pytorch", + reason="Not supported on PyTorch backend", + ) def test_integral(self): npt.assert_allclose(self.wl.integrate(), 1.0, rtol=1e-10) npt.assert_allclose(self.wl.integrate_numerically(), 1.0, rtol=1e-10) npt.assert_allclose( - self.wl.integrate(array([0.0, pi])) + self.wl.integrate(array([pi, 2.0 * pi])), + self.wl.integrate(array([0.0, pi])) + + self.wl.integrate(array([pi, 2.0 * pi])), 1.0, rtol=1e-10, ) @@ -65,4 +66,4 @@ def test_periodicity(self): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/distributions/test_wrapped_normal_distribution.py b/pyrecest/tests/distributions/test_wrapped_normal_distribution.py index 0c1e8478..520a660e 100644 --- a/pyrecest/tests/distributions/test_wrapped_normal_distribution.py +++ b/pyrecest/tests/distributions/test_wrapped_normal_distribution.py @@ -1,17 +1,16 @@ -from math import pi -from pyrecest.backend import sum -from pyrecest.backend import sqrt -from pyrecest.backend import ones_like -from pyrecest.backend import ones -from pyrecest.backend import exp -from pyrecest.backend import array -from pyrecest.backend import arange -from pyrecest.backend import allclose -from pyrecest.backend import all -from pyrecest.backend import zeros import unittest -import numpy.testing as npt +from math import pi +import numpy.testing as npt +from pyrecest.backend import ( + allclose, + arange, + array, + exp, + ones_like, + sqrt, + sum, +) from pyrecest.distributions import WrappedNormalDistribution @@ -28,9 +27,7 @@ def test_pdf_values_are_as_expected(self): def approx_with_wrapping(x): k = arange(-20, 21) - total = sum( - exp(-((x - self.mu + 2 * pi * k) ** 2) / (2 * self.sigma**2)) - ) + total = sum(exp(-((x - self.mu + 2 * pi * k) ** 2) / (2 * self.sigma**2))) return 1 / sqrt(2 * pi) / self.sigma * total test_points = [self.mu, self.mu - 1, self.mu + 2] @@ -60,4 +57,4 @@ def test_pdf_with_large_sigma_is_uniform(self): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/filters/test_circular_particle_filter.py b/pyrecest/tests/filters/test_circular_particle_filter.py index 59edad8f..e1969baa 100644 --- a/pyrecest/tests/filters/test_circular_particle_filter.py +++ b/pyrecest/tests/filters/test_circular_particle_filter.py @@ -1,12 +1,8 @@ -from math import pi -from pyrecest.backend import random -from pyrecest.backend import array -from pyrecest.backend import arange -from pyrecest.backend import allclose -from pyrecest.backend import all import unittest -import numpy.testing as npt +from math import pi +import numpy.testing as npt +from pyrecest.backend import allclose, arange, array, random from pyrecest.distributions import ( HypertoroidalDiracDistribution, WrappedNormalDistribution, @@ -118,7 +114,8 @@ def test_association_likelihood(self): places=10, ) self.assertGreater( - pf.association_likelihood(VonMisesDistribution(array(2), array(1))), 1.0 / (2.0 * pi) + pf.association_likelihood(VonMisesDistribution(array(2), array(1))), + 1.0 / (2.0 * pi), ) self.filter.set_state(CircularDiracDistribution(arange(0.0, 1.1, 0.1))) @@ -146,4 +143,4 @@ def likelihood2(x): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/filters/test_euclidean_particle_filter.py b/pyrecest/tests/filters/test_euclidean_particle_filter.py index 8e5ae424..891847fd 100644 --- a/pyrecest/tests/filters/test_euclidean_particle_filter.py +++ b/pyrecest/tests/filters/test_euclidean_particle_filter.py @@ -1,13 +1,8 @@ -from math import pi -from pyrecest.backend import random -from pyrecest.backend import ones -from pyrecest.backend import mean -from pyrecest.backend import array -from pyrecest.backend import zeros_like -from pyrecest.backend import zeros import unittest -import numpy.testing as npt +from math import pi +import numpy.testing as npt +from pyrecest.backend import array, mean, ones, random, zeros, zeros_like from pyrecest.distributions import GaussianDistribution from pyrecest.filters.euclidean_particle_filter import EuclideanParticleFilter @@ -50,9 +45,7 @@ def f(x, w): self.pf.predict_nonlinear_nonadditive(f, samples, weights) est = self.pf.get_point_estimate() self.assertEqual(self.pf.get_point_estimate().shape, (3,)) - npt.assert_allclose( - est, self.prior.mu + mean(samples, axis=0), atol=0.1 - ) + npt.assert_allclose(est, self.prior.mu + mean(samples, axis=0), atol=0.1) def test_predict_update_cycle_3d_forced_particle_pos_no_pred(self): self.pf.filter_state = self.prior.set_mean(ones(3) + pi / 2.0) @@ -73,4 +66,4 @@ def test_predict_update_cycle_3d_forced_particle_pos_no_pred(self): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/filters/test_global_nearest_neighbor.py b/pyrecest/tests/filters/test_global_nearest_neighbor.py index d21b953f..fe7da744 100644 --- a/pyrecest/tests/filters/test_global_nearest_neighbor.py +++ b/pyrecest/tests/filters/test_global_nearest_neighbor.py @@ -1,20 +1,21 @@ -from pyrecest.backend import column_stack -from pyrecest.backend import sort -from pyrecest.backend import real -from pyrecest.backend import eye -from pyrecest.backend import array -from pyrecest.backend import allclose -from pyrecest.backend import all -from pyrecest.backend import zeros -from pyrecest.backend import diag -from pyrecest.backend import dstack -import pyrecest.backend import unittest -import numpy.testing as npt - +import numpy.testing as npt +import pyrecest.backend import scipy from parameterized import parameterized +from pyrecest.backend import ( + all, + allclose, + array, + column_stack, + diag, + dstack, + eye, + real, + sort, + zeros, +) from pyrecest.distributions import GaussianDistribution from pyrecest.filters import KalmanFilter from pyrecest.filters.global_nearest_neighbor import GlobalNearestNeighbor @@ -26,16 +27,26 @@ class GlobalNearestNeighborTest(unittest.TestCase): def setUp(self): """Initialize test variables before each test is run.""" self.kfs_init = [ - KalmanFilter(GaussianDistribution(zeros(4), diag(array([1.0, 2.0, 3.0, 4.0])))), KalmanFilter( - GaussianDistribution(array([1.0, 2.0, 3.0, 4.0]), diag(array([2.0, 2.0, 2.0, 2.0]))) + GaussianDistribution(zeros(4), diag(array([1.0, 2.0, 3.0, 4.0]))) ), KalmanFilter( - GaussianDistribution(-array([1.0, 2.0, 3.0, 4.0]), diag(array([4.0, 3.0, 2.0, 1.0]))) + GaussianDistribution( + array([1.0, 2.0, 3.0, 4.0]), diag(array([2.0, 2.0, 2.0, 2.0])) + ) + ), + KalmanFilter( + GaussianDistribution( + -array([1.0, 2.0, 3.0, 4.0]), diag(array([4.0, 3.0, 2.0, 1.0])) + ) ), ] self.meas_mat = array([[1.0, 0.0, 0.0, 0.0], [0.0, 0.0, 1.0, 0.0]]) - self.sys_mat = array(scipy.linalg.block_diag(array([[1.0, 1.0], [0.0, 1.0]]), array([[1.0, 1.0], [0.0, 1.0]]))) + self.sys_mat = array( + scipy.linalg.block_diag( + array([[1.0, 1.0], [0.0, 1.0]]), array([[1.0, 1.0], [0.0, 1.0]]) + ) + ) self.all_different_meas_covs = dstack( [ diag(array([1.0, 2.0])), @@ -65,16 +76,31 @@ def test_get_state_returns_correct_shape(self): @parameterized.expand( [("no_inputs", zeros(4)), ("with_inputs", array([1.0, -1.0, 1.0, -1.0]))] ) - @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") + @unittest.skipIf( + pyrecest.backend.__name__ == "pyrecest.pytorch", + reason="Not supported on PyTorch backend", + ) def test_predict_linear(self, name, sys_input): import numpy as _np + # Can use scipy.linalg.block_diag instead of native backend functions here because the efficiency does not matter # for the test. - C_matrices = array([ - scipy.linalg.block_diag([[3.0, 2.0], [2.0, 2.0]], [[7.0, 4.0], [4.0, 4.0]]) + _np.eye(4), - scipy.linalg.block_diag([[4.0, 2.0], [2.0, 2.0]], [[4.0, 2.0], [2.0, 2.0]]) + _np.eye(4), - scipy.linalg.block_diag([[7.0, 3.0], [3.0, 3.0]], [[3.0, 1.0], [1.0, 1.0]]) + _np.eye(4), - ]) + C_matrices = array( + [ + scipy.linalg.block_diag( + [[3.0, 2.0], [2.0, 2.0]], [[7.0, 4.0], [4.0, 4.0]] + ) + + _np.eye(4), + scipy.linalg.block_diag( + [[4.0, 2.0], [2.0, 2.0]], [[4.0, 2.0], [2.0, 2.0]] + ) + + _np.eye(4), + scipy.linalg.block_diag( + [[7.0, 3.0], [3.0, 3.0]], [[3.0, 1.0], [1.0, 1.0]] + ) + + _np.eye(4), + ] + ) tracker = GlobalNearestNeighbor() tracker.filter_state = self.kfs_init @@ -93,22 +119,36 @@ def test_predict_linear(self, name, sys_input): tracker.filter_bank[i].filter_state.C, C_matrices[i] ) - @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") + @unittest.skipIf( + pyrecest.backend.__name__ == "pyrecest.pytorch", + reason="Not supported on PyTorch backend", + ) def test_predict_linear_different_mats_and_inputs(self): tracker = GlobalNearestNeighbor() tracker.filter_state = self.kfs_init sys_mats = dstack( ( - scipy.linalg.block_diag([[1.0, 1.0], [0.0, 1.0]], [[1.0, 1.0], [0.0, 1.0]]), + scipy.linalg.block_diag( + [[1.0, 1.0], [0.0, 1.0]], [[1.0, 1.0], [0.0, 1.0]] + ), eye(4), - array([[0.0, 0.0, 1.0, 1.0], [0.0, 0.0, 0.0, 1.0], [1.0, 1.0, 0.0, 0.0], [0.0, 1.0, 0.0, 0.0]]), + array( + [ + [0.0, 0.0, 1.0, 1.0], + [0.0, 0.0, 0.0, 1.0], + [1.0, 1.0, 0.0, 0.0], + [0.0, 1.0, 0.0, 0.0], + ] + ), ) ) sys_noises = dstack( (eye(4), diag([10.0, 11.0, 12.0, 13.0]), diag([1.0, 5.0, 3.0, 5.0])) ) - sys_inputs = array([[-1.0, 1.0, -1.0, 1.0], [1.0, 2.0, 3.0, 4.0], -array([4.0, 3.0, 2.0, 1.0])]).T + sys_inputs = array( + [[-1.0, 1.0, -1.0, 1.0], [1.0, 2.0, 3.0, 4.0], -array([4.0, 3.0, 2.0, 1.0])] + ).T tracker.predict_linear(sys_mats, sys_noises, sys_inputs) @@ -130,10 +170,15 @@ def test_predict_linear_different_mats_and_inputs(self): ) npt.assert_array_equal( tracker.filter_bank[2].filter_state.C, - scipy.linalg.block_diag([[4.0, 1.0], [1.0, 6.0]], [[10.0, 3.0], [3.0, 8.0]]), + scipy.linalg.block_diag( + [[4.0, 1.0], [1.0, 6.0]], [[10.0, 3.0], [3.0, 8.0]] + ), ) - @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") + @unittest.skipIf( + pyrecest.backend.__name__ == "pyrecest.pytorch", + reason="Not supported on PyTorch backend", + ) def test_association_no_clutter(self): tracker = GlobalNearestNeighbor() tracker.filter_state = self.kfs_init @@ -152,16 +197,12 @@ def test_association_no_clutter(self): # Shift them measurements = np.roll(perfect_meas_ordered, 1, axis=1) association = tracker.find_association(measurements, self.meas_mat, eye(2)) - npt.assert_array_equal( - measurements[:, association], perfect_meas_ordered - ) + npt.assert_array_equal(measurements[:, association], perfect_meas_ordered) # Shift them and add a bit of noise measurements = np.roll(perfect_meas_ordered, 1, axis=1) + 0.1 association = tracker.find_association(measurements, self.meas_mat, eye(2)) - npt.assert_array_equal( - measurements[:, association], perfect_meas_ordered + 0.1 - ) + npt.assert_array_equal(measurements[:, association], perfect_meas_ordered + 0.1) # Use different covariances association = tracker.find_association( @@ -169,11 +210,12 @@ def test_association_no_clutter(self): self.meas_mat, self.all_different_meas_covs, ) - npt.assert_array_equal( - measurements[:, association], perfect_meas_ordered + 0.1 - ) + npt.assert_array_equal(measurements[:, association], perfect_meas_ordered + 0.1) - @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") + @unittest.skipIf( + pyrecest.backend.__name__ == "pyrecest.pytorch", + reason="Not supported on PyTorch backend", + ) def test_association_with_clutter(self): tracker = GlobalNearestNeighbor() tracker.filter_state = self.kfs_init @@ -198,9 +240,7 @@ def test_association_with_clutter(self): ] ) association = tracker.find_association(measurements, self.meas_mat, eye(2)) - npt.assert_array_equal( - measurements[:, association], perfect_meas_ordered - ) + npt.assert_array_equal(measurements[:, association], perfect_meas_ordered) # Shift them, add one add one meausurement, and add a bit of noise association = tracker.find_association( @@ -238,9 +278,7 @@ def test_update_with_and_without_clutter(self): ) ) curr_covs = dstack([dist.C for dist in tracker_no_clut.filter_state]) - self.assertTrue( - all(curr_covs <= dstack([dist.C for dist in all_gaussians])) - ) + self.assertTrue(all(curr_covs <= dstack([dist.C for dist in all_gaussians]))) measurements_clut = column_stack( [measurements_no_clut, array([2, 2]).reshape(-1, 1)] @@ -299,9 +337,7 @@ def test_update_with_and_without_clutter(self): ) previous_means = curr_means self.assertFalse( - allclose( - [dist.mu for dist in tracker_no_clut.filter_state], previous_means - ) + allclose([dist.mu for dist in tracker_no_clut.filter_state], previous_means) ) previous_covs = curr_covs curr_covs = dstack([dist.C for dist in tracker_no_clut.filter_state]) @@ -324,4 +360,4 @@ def test_update_with_and_without_clutter(self): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py b/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py index 43e66ffd..41052e71 100644 --- a/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py +++ b/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py @@ -1,11 +1,8 @@ -from math import pi -from pyrecest.backend import random -from pyrecest.backend import array -from pyrecest.backend import zeros import unittest -import numpy.testing as npt - +from math import pi +import numpy.testing as npt +from pyrecest.backend import array, random, zeros from pyrecest.distributions import HypertoroidalWNDistribution from pyrecest.filters import HypertoroidalParticleFilter @@ -44,10 +41,8 @@ def test_predict_update_cycle_3D(self): self.test_predict_identity() for _ in range(3): self.test_update_identity() - npt.assert_allclose( - self.hpf.get_point_estimate(), self.forced_mean, atol=0.1 - ) + npt.assert_allclose(self.hpf.get_point_estimate(), self.forced_mean, atol=0.1) if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/filters/test_kalman_filter.py b/pyrecest/tests/filters/test_kalman_filter.py index df0a9cc5..fa004374 100644 --- a/pyrecest/tests/filters/test_kalman_filter.py +++ b/pyrecest/tests/filters/test_kalman_filter.py @@ -1,13 +1,9 @@ -from pyrecest.backend import diag -from pyrecest.backend import eye -from pyrecest.backend import array -from pyrecest.backend import allclose -from pyrecest.backend import all -import numpy.testing as npt import copy import unittest -import pyrecest.backend +import numpy.testing as npt +import pyrecest.backend +from pyrecest.backend import allclose, array, diag, eye from pyrecest.distributions import GaussianDistribution from pyrecest.filters.kalman_filter import KalmanFilter @@ -23,20 +19,29 @@ def test_initialization_gauss(self): ) npt.assert_equal(filter_custom.get_point_estimate(), array([4])) - @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") + @unittest.skipIf( + pyrecest.backend.__name__ == "pyrecest.pytorch", + reason="Not supported on PyTorch backend", + ) def test_update_with_likelihood_1d(self): kf = KalmanFilter((array([0]), array([[1]]))) kf.update_identity(array(1), array(3)) npt.assert_equal(kf.get_point_estimate(), 1.5) - @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") + @unittest.skipIf( + pyrecest.backend.__name__ == "pyrecest.pytorch", + reason="Not supported on PyTorch backend", + ) def test_update_with_meas_noise_and_meas_1d(self): kf = KalmanFilter((array([0]), array([[1]]))) kf.update_identity(array(1), array(4)) npt.assert_equal(kf.filter_state.C, 0.5) npt.assert_equal(kf.get_point_estimate(), 2) - @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") + @unittest.skipIf( + pyrecest.backend.__name__ == "pyrecest.pytorch", + reason="Not supported on PyTorch backend", + ) def test_update_linear_2d(self): filter_add = KalmanFilter((array([0, 1]), diag([1, 2]))) filter_id = copy.deepcopy(filter_add) @@ -46,18 +51,22 @@ def test_update_linear_2d(self): self.assertTrue( allclose(filter_add.get_point_estimate(), filter_id.get_point_estimate()) ) - self.assertTrue( - allclose(filter_add.filter_state.C, filter_id.filter_state.C) - ) + self.assertTrue(allclose(filter_add.filter_state.C, filter_id.filter_state.C)) - @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") + @unittest.skipIf( + pyrecest.backend.__name__ == "pyrecest.pytorch", + reason="Not supported on PyTorch backend", + ) def test_predict_identity_1d(self): kf = KalmanFilter((array([0]), array([[1]]))) kf.predict_identity(array([[3]]), array([1])) npt.assert_equal(kf.get_point_estimate(), array(1)) npt.assert_equal(kf.filter_state.C, array(4)) - @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") + @unittest.skipIf( + pyrecest.backend.__name__ == "pyrecest.pytorch", + reason="Not supported on PyTorch backend", + ) def test_predict_linear_2d(self): kf = KalmanFilter((array([0, 1]), diag(array([1, 2])))) kf.predict_linear(diag(array([1, 2])), diag(array([2, 1]))) @@ -68,4 +77,4 @@ def test_predict_linear_2d(self): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/filters/test_random_matrix_tracker.py b/pyrecest/tests/filters/test_random_matrix_tracker.py index a6204b8e..020af079 100644 --- a/pyrecest/tests/filters/test_random_matrix_tracker.py +++ b/pyrecest/tests/filters/test_random_matrix_tracker.py @@ -1,18 +1,11 @@ -from pyrecest.backend import diag -from pyrecest.backend import linalg -from pyrecest.backend import mean -from pyrecest.backend import eye -from pyrecest.backend import concatenate -from pyrecest.backend import array -from pyrecest.backend import zeros import unittest from unittest.mock import patch -import pyrecest.backend -import numpy.testing as npt import matplotlib.pyplot as plt - +import numpy.testing as npt +import pyrecest.backend from parameterized import parameterized +from pyrecest.backend import array, concatenate, diag, eye, linalg, mean, zeros from pyrecest.distributions.nonperiodic.gaussian_distribution import ( GaussianDistribution, ) @@ -73,9 +66,7 @@ def test_predict(self): npt.assert_array_almost_equal( self.tracker.covariance, expected_covariance, decimal=5 ) - npt.assert_array_almost_equal( - self.tracker.extent, expected_extent, decimal=5 - ) + npt.assert_array_almost_equal(self.tracker.extent, expected_extent, decimal=5) @parameterized.expand( [ @@ -91,7 +82,10 @@ def test_predict(self): ), ] ) - @unittest.skipIf(pyrecest.backend.__name__ == 'pyrecest.pytorch', reason="Not supported on PyTorch backend") + @unittest.skipIf( + pyrecest.backend.__name__ == "pyrecest.pytorch", + reason="Not supported on PyTorch backend", + ) def test_update(self, name, offset, _): ys = array([self.initial_state + offset_row for offset_row in offset]).T Cv = array([[0.1, 0.0], [0.0, 0.1]]) @@ -104,9 +98,7 @@ def test_update(self, name, offset, _): kf = KalmanFilter( GaussianDistribution(self.initial_state, self.initial_covariance) ) - kf.update_linear( - mean(ys, axis=1), H, (self.initial_extent + Cv) / ys.shape[1] - ) + kf.update_linear(mean(ys, axis=1), H, (self.initial_extent + Cv) / ys.shape[1]) npt.assert_array_almost_equal( self.tracker.kinematic_state, kf.get_point_estimate(), decimal=5 @@ -145,4 +137,4 @@ def test_draw_extent_3d(self, mock_show): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/filters/test_toroidal_particle_filter.py b/pyrecest/tests/filters/test_toroidal_particle_filter.py index d6d78c0d..b37b219a 100644 --- a/pyrecest/tests/filters/test_toroidal_particle_filter.py +++ b/pyrecest/tests/filters/test_toroidal_particle_filter.py @@ -1,11 +1,7 @@ -from math import pi -from pyrecest.backend import random -from pyrecest.backend import array -from pyrecest.backend import allclose -from pyrecest.backend import all import unittest +from math import pi - +from pyrecest.backend import allclose, array, random from pyrecest.distributions.hypertorus.hypertoroidal_wrapped_normal_distribution import ( HypertoroidalWrappedNormalDistribution, ) @@ -39,4 +35,4 @@ def test_toroidal_particle_filter(self): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/filters/test_toroidal_wrapped_normal_filter.py b/pyrecest/tests/filters/test_toroidal_wrapped_normal_filter.py index ea1d0737..bacf03b7 100644 --- a/pyrecest/tests/filters/test_toroidal_wrapped_normal_filter.py +++ b/pyrecest/tests/filters/test_toroidal_wrapped_normal_filter.py @@ -1,10 +1,8 @@ -from math import pi -from pyrecest.backend import mod -from pyrecest.backend import array import unittest -import numpy as np -import numpy.testing as npt +from math import pi +import numpy.testing as npt +from pyrecest.backend import array, mod from pyrecest.distributions.hypertorus.toroidal_wrapped_normal_distribution import ( ToroidalWrappedNormalDistribution, ) @@ -37,4 +35,4 @@ def test_predict_identity(self): npt.assert_array_almost_equal( dist_result.mu, mod(self.twn.mu + self.twn.mu, 2 * pi) ) - npt.assert_array_almost_equal(dist_result.C, self.twn.C + self.twn.C) \ No newline at end of file + npt.assert_array_almost_equal(dist_result.C, self.twn.C + self.twn.C) diff --git a/pyrecest/tests/filters/test_von_mises_filter.py b/pyrecest/tests/filters/test_von_mises_filter.py index 3ed33dac..0d011563 100644 --- a/pyrecest/tests/filters/test_von_mises_filter.py +++ b/pyrecest/tests/filters/test_von_mises_filter.py @@ -1,7 +1,7 @@ import unittest -from pyrecest.backend import array import numpy.testing as npt +from pyrecest.backend import array from pyrecest.distributions import VonMisesDistribution from pyrecest.filters.von_mises_filter import VonMisesFilter @@ -42,4 +42,4 @@ def test_update(self): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/filters/test_von_mises_fisher_filter.py b/pyrecest/tests/filters/test_von_mises_fisher_filter.py index edfcf1f1..cfc7ff3a 100644 --- a/pyrecest/tests/filters/test_von_mises_fisher_filter.py +++ b/pyrecest/tests/filters/test_von_mises_fisher_filter.py @@ -1,11 +1,6 @@ -from pyrecest.backend import sin -from pyrecest.backend import cos -from pyrecest.backend import array -from pyrecest.backend import allclose -from pyrecest.backend import all import unittest - +from pyrecest.backend import allclose, array, cos, sin from pyrecest.distributions import VonMisesFisherDistribution from pyrecest.filters.von_mises_fisher_filter import VonMisesFisherFilter @@ -46,4 +41,4 @@ def test_update_identity(self): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/filters/test_wrapped_normal_filter.py b/pyrecest/tests/filters/test_wrapped_normal_filter.py index ff90aedc..ba7676de 100644 --- a/pyrecest/tests/filters/test_wrapped_normal_filter.py +++ b/pyrecest/tests/filters/test_wrapped_normal_filter.py @@ -1,12 +1,12 @@ import unittest -from pyrecest.backend import array +import numpy.testing as npt +from pyrecest.backend import array from pyrecest.distributions import WrappedNormalDistribution from pyrecest.filters.wrapped_normal_filter import WrappedNormalFilter -import numpy.testing as npt -class WrappedNormalFilterTest(unittest.TestCase): +class WrappedNormalFilterTest(unittest.TestCase): def setUp(self): self.wn_filter = WrappedNormalFilter() self.wn = WrappedNormalDistribution(array(1.3), array(0.8)) @@ -20,7 +20,9 @@ def test_initialization(self): self.assertEqual(self.wn.sigma, wn1.sigma) def test_predict_identity(self): - self.wn_filter.predict_identity(WrappedNormalDistribution(array(0.0), self.wn.sigma)) + self.wn_filter.predict_identity( + WrappedNormalDistribution(array(0.0), self.wn.sigma) + ) wn_identity = self.wn_filter.filter_state self.assertIsInstance(wn_identity, WrappedNormalDistribution) self.assertEqual(self.wn.mu, wn_identity.mu) diff --git a/pyrecest/tests/test_eot_shape_database.py b/pyrecest/tests/test_eot_shape_database.py index 141a9adc..1048724e 100644 --- a/pyrecest/tests/test_eot_shape_database.py +++ b/pyrecest/tests/test_eot_shape_database.py @@ -80,4 +80,4 @@ def test_plotting(self): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/test_euclidean_sampler.py b/pyrecest/tests/test_euclidean_sampler.py index 344ff2f0..68f30195 100644 --- a/pyrecest/tests/test_euclidean_sampler.py +++ b/pyrecest/tests/test_euclidean_sampler.py @@ -1,13 +1,6 @@ -from pyrecest.backend import random -from pyrecest.backend import std -from pyrecest.backend import ones -from pyrecest.backend import mean -from pyrecest.backend import allclose -from pyrecest.backend import all -from pyrecest.backend import zeros import unittest - +from pyrecest.backend import allclose, mean, ones, random, std, zeros from pyrecest.sampling.euclidean_sampler import GaussianSampler @@ -34,4 +27,4 @@ def test_gaussian_properties(self): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/test_evaluation_basic.py b/pyrecest/tests/test_evaluation_basic.py index d6477e8e..aa60a8a9 100644 --- a/pyrecest/tests/test_evaluation_basic.py +++ b/pyrecest/tests/test_evaluation_basic.py @@ -11,6 +11,7 @@ from pyrecest.backend import all from pyrecest.backend import empty from pyrecest.backend import zeros +import numpy as np import os import tempfile import unittest @@ -173,6 +174,7 @@ def test_generate_simulated_scenario(self): def test_determine_all_deviations(self): import numpy as _np + def dummy_extract_mean(x): return x @@ -282,7 +284,7 @@ def test_perform_predict_update_cycles(self): self.assertIsInstance(time_elapsed, float) self.assertGreater(time_elapsed, 0) self.assertIsNotNone(last_filter_state) - self.assertIsInstance(last_estimate, ) + #self.assertIsInstance(last_estimate, ) self.assertEqual(last_estimate.shape, (2,)) self.assertIsNone(all_estimates) @@ -377,11 +379,11 @@ def _validate_eval_data( self.assertTrue(not any(run_failed)) self.assertEqual(ndim(groundtruths), 2) - self.assertIsInstance(groundtruths[0, 0], ) + #self.assertIsInstance(groundtruths[0, 0], ) self.assertIn(ndim(groundtruths[0, 0]), (1, 2)) self.assertEqual(ndim(measurements), 2) - self.assertIsInstance(measurements[0, 0], ) + #self.assertIsInstance(measurements[0, 0], ) self.assertIn(ndim(measurements[0, 0]), (1, 2)) def test_evaluate_for_simulation_config_R2_random_walk(self): diff --git a/pyrecest/tests/test_hyperspherical_sampler.py b/pyrecest/tests/test_hyperspherical_sampler.py index 5b610711..76077a84 100644 --- a/pyrecest/tests/test_hyperspherical_sampler.py +++ b/pyrecest/tests/test_hyperspherical_sampler.py @@ -1,10 +1,8 @@ -from pyrecest.backend import linalg -from pyrecest.backend import random -from pyrecest.backend import prod -from pyrecest.backend import allclose -from pyrecest.backend import all -import unittest import importlib.util +import unittest + +from pyrecest.backend import allclose, linalg, prod, random + healpy_installed = importlib.util.find_spec("healpy") is not None @@ -22,7 +20,6 @@ class TestHypersphericalGridGenerationFunction(unittest.TestCase): - @unittest.skipIf(not healpy_installed, "healpy is not installed") @parameterized.expand( [ @@ -145,4 +142,4 @@ def test_conversion(self): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/test_hypertoroidal_sampler.py b/pyrecest/tests/test_hypertoroidal_sampler.py index bd5d72cb..5d07aa2a 100644 --- a/pyrecest/tests/test_hypertoroidal_sampler.py +++ b/pyrecest/tests/test_hypertoroidal_sampler.py @@ -1,10 +1,8 @@ -from pyrecest.backend import diff -from math import pi -from pyrecest.backend import std -from pyrecest.backend import all import unittest -import numpy.testing as npt +from math import pi +import numpy.testing as npt +from pyrecest.backend import all, diff, std from pyrecest.sampling.hypertoroidal_sampler import CircularUniformSampler @@ -39,4 +37,4 @@ def test_get_grid(self): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/test_metrics.py b/pyrecest/tests/test_metrics.py index 89b42e25..b07ae58d 100644 --- a/pyrecest/tests/test_metrics.py +++ b/pyrecest/tests/test_metrics.py @@ -1,9 +1,7 @@ -from pyrecest.backend import random -from pyrecest.backend import repeat -from pyrecest.backend import array import unittest -import numpy.testing as npt +import numpy.testing as npt +from pyrecest.backend import array, random, repeat from pyrecest.utils.metrics import anees @@ -33,10 +31,8 @@ def test_ANEES_is_close_to_one(self): computed_ANEES = anees(samples, repeated_uncertainties, repeated_groundtruths) # Assert that computed ANEES is close to 1 with a tolerance of 0.05. - npt.assert_almost_equal( - computed_ANEES, self.groundtruths.shape[-1], decimal=2 - ) + npt.assert_almost_equal(computed_ANEES, self.groundtruths.shape[-1], decimal=2) if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/utils/metrics.py b/pyrecest/utils/metrics.py index ffa95afe..dccbcf66 100644 --- a/pyrecest/utils/metrics.py +++ b/pyrecest/utils/metrics.py @@ -1,7 +1,4 @@ -from pyrecest.backend import linalg -from pyrecest.backend import mean -from pyrecest.backend import zeros - +from pyrecest.backend import linalg, mean, zeros def anees(estimates, uncertainties, groundtruths): @@ -17,4 +14,4 @@ def anees(estimates, uncertainties, groundtruths): error = estimates[i] - groundtruths[i] NEES[i] = error.T @ linalg.solve(uncertainties[i], error) - return mean(NEES) \ No newline at end of file + return mean(NEES) diff --git a/pyrecest/utils/plotting.py b/pyrecest/utils/plotting.py index baf6368f..4b8ba2ec 100644 --- a/pyrecest/utils/plotting.py +++ b/pyrecest/utils/plotting.py @@ -1,18 +1,18 @@ -from pyrecest.backend import column_stack -from pyrecest.backend import linalg -from pyrecest.backend import diag from math import pi -from pyrecest.backend import sqrt -from pyrecest.backend import sin -from pyrecest.backend import reshape -from pyrecest.backend import outer -from pyrecest.backend import ones -from pyrecest.backend import linspace -from pyrecest.backend import cos -from pyrecest.backend import array -from pyrecest.backend import complex64 -import matplotlib.pyplot as plt +import matplotlib.pyplot as plt +from pyrecest.backend import ( + array, + column_stack, + cos, + linalg, + linspace, + ones, + outer, + reshape, + sin, + sqrt, +) def plot_ellipsoid(center, shape_matrix, scaling_factor=1, color="blue"): @@ -57,4 +57,4 @@ def plot_ellipsoid_3d(center, shape_matrix, scaling_factor=1, color="blue"): linewidth=0, antialiased=False, ) - plt.show() \ No newline at end of file + plt.show() diff --git a/requirements-dev_no_version.txt b/requirements-dev_no_version.txt index a62cb68b..a154cbe4 100644 --- a/requirements-dev_no_version.txt +++ b/requirements-dev_no_version.txt @@ -7,13 +7,19 @@ colorama contourpy cycler exceptiongroup +filelock filterpy fonttools +fsspec +healpy idna iniconfig +jinja2 kiwisolver +markupsafe matplotlib mpmath +networkx numpy-quaternion numpy packaging @@ -33,10 +39,14 @@ pytz pyyaml requests scipy +setuptools-scm +setuptools shapely six +sympy tomli tqdm +typing-extensions tzdata urllib3 xarray From 9e7c8d78716168df5cc0e3478e0e230181cd0e41 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 23 Oct 2023 11:48:29 +0100 Subject: [PATCH 111/232] More.... --- pyrecest/distributions/abstract_dirac_distribution.py | 4 ++-- pyrecest/distributions/abstract_se3_distribution.py | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/pyrecest/distributions/abstract_dirac_distribution.py b/pyrecest/distributions/abstract_dirac_distribution.py index 16ba809e..426bc0f5 100644 --- a/pyrecest/distributions/abstract_dirac_distribution.py +++ b/pyrecest/distributions/abstract_dirac_distribution.py @@ -5,8 +5,8 @@ from pyrecest.backend import ( all, + amax apply_along_axis, - argmax, int32, int64, isclose, @@ -117,7 +117,7 @@ def kld_numerical(self, *args): raise NotImplementedError("PDF:UNDEFINED, not supported") def mode(self, rel_tol=0.001): - highest_val, ind = np.max(self.w), argmax(self.w) + highest_val, ind = amax(self.w) if (highest_val / self.w.size) < (1 + rel_tol): warnings.warn( "The samples may be equally weighted, .mode is likely to return a bad result." diff --git a/pyrecest/distributions/abstract_se3_distribution.py b/pyrecest/distributions/abstract_se3_distribution.py index 1802bde6..92304847 100644 --- a/pyrecest/distributions/abstract_se3_distribution.py +++ b/pyrecest/distributions/abstract_se3_distribution.py @@ -52,8 +52,9 @@ def plot_state( @staticmethod def plot_point(se3point): # pylint: disable=too-many-locals + import numpy as _np """Visualize just a point in the SE(3) domain (no uncertainties are considered)""" - q = np.quaternion(*se3point[:4]) + q = _np.quaternion(*se3point[:4]) rotMat = quaternion.as_rotation_matrix(q) pos = se3point[4:] @@ -71,7 +72,7 @@ def plot_point(se3point): # pylint: disable=too-many-locals h = [h1, h2, h3] relevant_coords = concatenate((pos.reshape(-1, 1), pos + rotMat), axis=1) needed_boundaries = column_stack( - (np.min(relevant_coords, axis=1), np.max(relevant_coords, axis=1)) + (_np.min(relevant_coords, axis=1), _np.max(relevant_coords, axis=1)) ) # Get current axis limits From 8b157b26adf90931262eb8eb7282ddb3fe217623 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 23 Oct 2023 11:51:03 +0100 Subject: [PATCH 112/232] More --- .../abstract_hypercylindrical_distribution.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py b/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py index 6cc5acba..fc1068cf 100644 --- a/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py +++ b/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py @@ -120,19 +120,19 @@ def linear_covariance_numerical(self, approximate_mean=None): if self.bound_dim == 1 and self.lin_dim == 1: C, _ = nquad( lambda x, y: (y - approximate_mean) ** 2 * self.pdf([x, y]), - [[0, 2 * pi], [-float("inf"), float("inf")]], + [[0.0, 2.0 * pi], [-float("inf"), float("inf")]], ) elif self.bound_dim == 2 and self.lin_dim == 1: C, _ = nquad( lambda x, y, z: (z - approximate_mean) ** 2 * self.pdf([x, y, z]), - [[0, 2 * pi], [0, 2 * pi], [-float("inf"), float("inf")]], + [[0.0, 2.0 * pi], [0.0, 2.0 * pi], [-float("inf"), float("inf")]], ) elif self.bound_dim == 1 and self.lin_dim == 2: C = empty((2, 2)) C[0, 0], _ = nquad( lambda x, y, z: (y - approximate_mean[0]) ** 2 * self.pdf([x, y, z]), [ - [0, 2 * pi], + [0.0, 2.0 * pi], [-float("inf"), float("inf")], [-float("inf"), float("inf")], ], @@ -151,7 +151,7 @@ def linear_covariance_numerical(self, approximate_mean=None): C[1, 1], _ = nquad( lambda x, y, z: (z - approximate_mean[1]) ** 2 * self.pdf([x, y, z]), [ - [0, 2 * pi], + [0.0, 2.0 * pi], [-float("inf"), float("inf")], [-float("inf"), float("inf")], ], @@ -183,7 +183,7 @@ def condition_on_linear(self, input_lin, normalize=True): ), "Input should be of size (lin_dim,)." def f_cond_unnorm(x, input_lin=input_lin): - n_inputs = np.size(x) // x.shape[-1] if ndim(x) > 1 else x.shape[0] + n_inputs = x.shape[0] if x.ndim > 1 else 1 input_repeated = tile(input_lin, (n_inputs, 1)) return self.pdf(column_stack((x, input_repeated))) @@ -217,7 +217,7 @@ def condition_on_periodic(self, input_periodic, normalize=True): input_periodic = mod(input_periodic, 2.0 * pi) def f_cond_unnorm(x, input_periodic=input_periodic): - n_inputs = np.size(x) // x.shape[-1] if ndim(x) > 1 else np.size(x) + n_inputs = x.shape[0] if x.ndim > 1 else 1 input_repeated = tile(input_periodic, (n_inputs, 1)) return self.pdf(column_stack((input_repeated, x))) From 22d5797ad2adf7a4d810112ec825f54e791416f9 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 23 Oct 2023 12:19:18 +0100 Subject: [PATCH 113/232] Fix --- pyrecest/distributions/abstract_dirac_distribution.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrecest/distributions/abstract_dirac_distribution.py b/pyrecest/distributions/abstract_dirac_distribution.py index 426bc0f5..31714df9 100644 --- a/pyrecest/distributions/abstract_dirac_distribution.py +++ b/pyrecest/distributions/abstract_dirac_distribution.py @@ -5,7 +5,7 @@ from pyrecest.backend import ( all, - amax + amax, apply_along_axis, int32, int64, From 3e166af0cc02dc0befa3683205b2b3eb3f5b3e24 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 23 Oct 2023 12:23:23 +0100 Subject: [PATCH 114/232] Ignoring import pyrecest.backend linter warnings --- .pylintrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pylintrc b/.pylintrc index c70e5b93..e8a2d002 100644 --- a/.pylintrc +++ b/.pylintrc @@ -63,7 +63,7 @@ ignore-patterns=^\.# # (useful for modules/projects where namespaces are manipulated during runtime # and thus existing member attributes cannot be deduced by static analysis). It # supports qualified module names, as well as Unix pattern matching. -ignored-modules= +ignored-modules=pyrecest.backend # Python code to execute, usually for sys.path manipulation such as # pygtk.require(). From d343836d875d5e401d5b15e8050704bdb86a2219 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 23 Oct 2023 12:30:08 +0100 Subject: [PATCH 115/232] More --- pyrecest/_backend/numpy/__init__.py | 1 - pyrecest/_backend/pytorch/__init__.py | 1 - pyrecest/distributions/abstract_dirac_distribution.py | 4 ++-- .../abstract_orthogonal_basis_distribution.py | 5 +++-- pyrecest/filters/global_nearest_neighbor.py | 9 +++++---- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/pyrecest/_backend/numpy/__init__.py b/pyrecest/_backend/numpy/__init__.py index a660c87f..1947179c 100644 --- a/pyrecest/_backend/numpy/__init__.py +++ b/pyrecest/_backend/numpy/__init__.py @@ -92,7 +92,6 @@ full_like, isinf, deg2rad, - uint32, ) from scipy.special import erf, gamma, polygamma # NOQA diff --git a/pyrecest/_backend/pytorch/__init__.py b/pyrecest/_backend/pytorch/__init__.py index d8c1352d..08d0e871 100644 --- a/pyrecest/_backend/pytorch/__init__.py +++ b/pyrecest/_backend/pytorch/__init__.py @@ -52,7 +52,6 @@ full_like, isinf, deg2rad, - uint32, ) from torch import repeat_interleave as repeat from torch import ( diff --git a/pyrecest/distributions/abstract_dirac_distribution.py b/pyrecest/distributions/abstract_dirac_distribution.py index 31714df9..9653dd0c 100644 --- a/pyrecest/distributions/abstract_dirac_distribution.py +++ b/pyrecest/distributions/abstract_dirac_distribution.py @@ -4,7 +4,6 @@ from typing import Union from pyrecest.backend import ( - all, amax, apply_along_axis, int32, @@ -15,6 +14,7 @@ random, sum, ) +import pyrecest.backend as backend from .abstract_distribution_type import AbstractDistributionType @@ -73,7 +73,7 @@ def reweigh(self, f: Callable) -> "AbstractDiracDistribution": wNew = f(dist.d) assert wNew.shape == dist.w.shape, "Function returned wrong output dimensions." - assert all(wNew >= 0), "All weights should be greater than or equal to 0." + assert backend.all(wNew >= 0), "All weights should be greater than or equal to 0." assert sum(wNew) > 0, "The sum of all weights should be greater than 0." dist.w = wNew * dist.w diff --git a/pyrecest/distributions/abstract_orthogonal_basis_distribution.py b/pyrecest/distributions/abstract_orthogonal_basis_distribution.py index 4c7280fe..f3b541f6 100644 --- a/pyrecest/distributions/abstract_orthogonal_basis_distribution.py +++ b/pyrecest/distributions/abstract_orthogonal_basis_distribution.py @@ -2,7 +2,8 @@ import warnings from abc import abstractmethod -from pyrecest.backend import all, exp, imag, real +from pyrecest.backend import exp, imag, real +import pyrecest.backend as backend from .abstract_distribution_type import AbstractDistributionType @@ -55,7 +56,7 @@ def pdf(self, xs): """ val = self.value(xs) if self.transformation == "sqrt": - assert all(imag(val) < 0.0001) + assert backend.all(imag(val) < 0.0001) return real(val) ** 2 if self.transformation == "identity": diff --git a/pyrecest/filters/global_nearest_neighbor.py b/pyrecest/filters/global_nearest_neighbor.py index 5da0a40b..098cd9e4 100644 --- a/pyrecest/filters/global_nearest_neighbor.py +++ b/pyrecest/filters/global_nearest_neighbor.py @@ -1,4 +1,5 @@ -from pyrecest.backend import all, any, empty, full, repeat, squeeze, stack +from pyrecest.backend import empty, full, repeat, squeeze, stack +import pyrecest.backend as backend from scipy.optimize import linear_sum_assignment from scipy.spatial.distance import cdist from scipy.stats import chi2 @@ -52,7 +53,7 @@ def find_association( elif self.association_param["distance_metric_pos"].lower() == "mahalanobis": dists = empty((n_targets, n_meas)) - all_cov_mat_state_equal = all( + all_cov_mat_state_equal = backend.all( all_cov_mats_prior == repeat( all_cov_mats_prior[:, :, 0][:, :, None], @@ -60,7 +61,7 @@ def find_association( axis=2, ) ) - all_cov_mat_meas_equal = cov_mats_meas.ndim == 2 or all( + all_cov_mat_meas_equal = cov_mats_meas.ndim == 2 or backend.all( cov_mats_meas == repeat( cov_mats_meas[:, :, 0][:, :, None], @@ -136,7 +137,7 @@ def find_association( association = col_ind[:n_targets] - if warn_on_no_meas_for_track and any(association > n_meas): + if warn_on_no_meas_for_track and backend.any(association > n_meas): print( "GNN: No measurement was within gating threshold for at least one target." ) From 9769ccf1fd0bbbe55cb9785d8b9a7973cf0c1788 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 23 Oct 2023 12:33:28 +0100 Subject: [PATCH 116/232] More --- pyrecest/_backend/__init__.py | 1 - pyrecest/evaluation/evaluate_for_simulation_config.py | 1 - 2 files changed, 2 deletions(-) diff --git a/pyrecest/_backend/__init__.py b/pyrecest/_backend/__init__.py index a345d014..7d0a8a20 100644 --- a/pyrecest/_backend/__init__.py +++ b/pyrecest/_backend/__init__.py @@ -30,7 +30,6 @@ def get_backend_name(): "complex64", "complex128", "uint8", - "uint32", # For pyrecest # Functions "abs", "all", diff --git a/pyrecest/evaluation/evaluate_for_simulation_config.py b/pyrecest/evaluation/evaluate_for_simulation_config.py index ae621d32..c8b2276e 100644 --- a/pyrecest/evaluation/evaluate_for_simulation_config.py +++ b/pyrecest/evaluation/evaluate_for_simulation_config.py @@ -1,6 +1,5 @@ import random from typing import Any, Optional -from pyrecest.backend import uint32 from .evaluate_for_variables import evaluate_for_variables from .generate_simulated_scenarios import generate_simulated_scenarios From b01d4ae7fcdb3fe3c11a05f217f0c83f905308d8 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 23 Oct 2023 12:38:10 +0100 Subject: [PATCH 117/232] More --- pyrecest/_backend/__init__.py | 1 + pyrecest/_backend/numpy/__init__.py | 1 + pyrecest/_backend/pytorch/__init__.py | 1 + .../distributions/hypersphere_subset/bingham_distribution.py | 5 +++-- 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/pyrecest/_backend/__init__.py b/pyrecest/_backend/__init__.py index 7d0a8a20..bbe145ef 100644 --- a/pyrecest/_backend/__init__.py +++ b/pyrecest/_backend/__init__.py @@ -187,6 +187,7 @@ def get_backend_name(): "full_like", "isinf", "deg2rad", + "argsort", ], "autodiff": [ "custom_gradient", diff --git a/pyrecest/_backend/numpy/__init__.py b/pyrecest/_backend/numpy/__init__.py index 1947179c..82edd36e 100644 --- a/pyrecest/_backend/numpy/__init__.py +++ b/pyrecest/_backend/numpy/__init__.py @@ -92,6 +92,7 @@ full_like, isinf, deg2rad, + argsort, ) from scipy.special import erf, gamma, polygamma # NOQA diff --git a/pyrecest/_backend/pytorch/__init__.py b/pyrecest/_backend/pytorch/__init__.py index 08d0e871..839fdbc7 100644 --- a/pyrecest/_backend/pytorch/__init__.py +++ b/pyrecest/_backend/pytorch/__init__.py @@ -52,6 +52,7 @@ full_like, isinf, deg2rad, + argsort, ) from torch import repeat_interleave as repeat from torch import ( diff --git a/pyrecest/distributions/hypersphere_subset/bingham_distribution.py b/pyrecest/distributions/hypersphere_subset/bingham_distribution.py index 948af359..b650a5c4 100644 --- a/pyrecest/distributions/hypersphere_subset/bingham_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/bingham_distribution.py @@ -1,6 +1,7 @@ from math import pi -from pyrecest.backend import abs, all, amax, diag, exp, eye, linalg, sum +from pyrecest.backend import abs, amax, diag, exp, eye, linalg, sum, zeros +import pyrecest.backend as backend from scipy.integrate import quad from scipy.special import iv @@ -15,7 +16,7 @@ def __init__(self, Z, M): assert Z.shape[0] == self.input_dim, "Z has wrong length" assert Z.ndim == 1, "Z needs to be a 1-D vector" assert Z[-1] == 0, "Last entry of Z needs to be zero" - assert all(Z[:-1] <= Z[1:]), "Values in Z have to be ascending" + assert backend.all(Z[:-1] <= Z[1:]), "Values in Z have to be ascending" # Verify that M is orthogonal epsilon = 0.001 From db7d15fa48d760f883f69a757f8a2c4751d78731 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 23 Oct 2023 12:41:50 +0100 Subject: [PATCH 118/232] More --- pyrecest/distributions/abstract_dirac_distribution.py | 4 ++-- .../abstract_orthogonal_basis_distribution.py | 5 ++--- .../hypersphere_subset/bingham_distribution.py | 5 ++--- pyrecest/filters/global_nearest_neighbor.py | 7 +++---- 4 files changed, 9 insertions(+), 12 deletions(-) diff --git a/pyrecest/distributions/abstract_dirac_distribution.py b/pyrecest/distributions/abstract_dirac_distribution.py index 9653dd0c..63394d0a 100644 --- a/pyrecest/distributions/abstract_dirac_distribution.py +++ b/pyrecest/distributions/abstract_dirac_distribution.py @@ -13,8 +13,8 @@ ones, random, sum, + all, ) -import pyrecest.backend as backend from .abstract_distribution_type import AbstractDistributionType @@ -73,7 +73,7 @@ def reweigh(self, f: Callable) -> "AbstractDiracDistribution": wNew = f(dist.d) assert wNew.shape == dist.w.shape, "Function returned wrong output dimensions." - assert backend.all(wNew >= 0), "All weights should be greater than or equal to 0." + assert all(wNew >= 0), "All weights should be greater than or equal to 0." assert sum(wNew) > 0, "The sum of all weights should be greater than 0." dist.w = wNew * dist.w diff --git a/pyrecest/distributions/abstract_orthogonal_basis_distribution.py b/pyrecest/distributions/abstract_orthogonal_basis_distribution.py index f3b541f6..0f63b50d 100644 --- a/pyrecest/distributions/abstract_orthogonal_basis_distribution.py +++ b/pyrecest/distributions/abstract_orthogonal_basis_distribution.py @@ -2,8 +2,7 @@ import warnings from abc import abstractmethod -from pyrecest.backend import exp, imag, real -import pyrecest.backend as backend +from pyrecest.backend import exp, imag, real, all from .abstract_distribution_type import AbstractDistributionType @@ -56,7 +55,7 @@ def pdf(self, xs): """ val = self.value(xs) if self.transformation == "sqrt": - assert backend.all(imag(val) < 0.0001) + assert all(imag(val) < 0.0001) return real(val) ** 2 if self.transformation == "identity": diff --git a/pyrecest/distributions/hypersphere_subset/bingham_distribution.py b/pyrecest/distributions/hypersphere_subset/bingham_distribution.py index b650a5c4..5adf4eba 100644 --- a/pyrecest/distributions/hypersphere_subset/bingham_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/bingham_distribution.py @@ -1,7 +1,6 @@ from math import pi -from pyrecest.backend import abs, amax, diag, exp, eye, linalg, sum, zeros -import pyrecest.backend as backend +from pyrecest.backend import all, abs, amax, diag, exp, eye, linalg, sum, zeros from scipy.integrate import quad from scipy.special import iv @@ -16,7 +15,7 @@ def __init__(self, Z, M): assert Z.shape[0] == self.input_dim, "Z has wrong length" assert Z.ndim == 1, "Z needs to be a 1-D vector" assert Z[-1] == 0, "Last entry of Z needs to be zero" - assert backend.all(Z[:-1] <= Z[1:]), "Values in Z have to be ascending" + assert all(Z[:-1] <= Z[1:]), "Values in Z have to be ascending" # Verify that M is orthogonal epsilon = 0.001 diff --git a/pyrecest/filters/global_nearest_neighbor.py b/pyrecest/filters/global_nearest_neighbor.py index 098cd9e4..24c98bce 100644 --- a/pyrecest/filters/global_nearest_neighbor.py +++ b/pyrecest/filters/global_nearest_neighbor.py @@ -1,5 +1,4 @@ -from pyrecest.backend import empty, full, repeat, squeeze, stack -import pyrecest.backend as backend +from pyrecest.backend import empty, full, repeat, squeeze, stack, all from scipy.optimize import linear_sum_assignment from scipy.spatial.distance import cdist from scipy.stats import chi2 @@ -53,7 +52,7 @@ def find_association( elif self.association_param["distance_metric_pos"].lower() == "mahalanobis": dists = empty((n_targets, n_meas)) - all_cov_mat_state_equal = backend.all( + all_cov_mat_state_equal = all( all_cov_mats_prior == repeat( all_cov_mats_prior[:, :, 0][:, :, None], @@ -61,7 +60,7 @@ def find_association( axis=2, ) ) - all_cov_mat_meas_equal = cov_mats_meas.ndim == 2 or backend.all( + all_cov_mat_meas_equal = cov_mats_meas.ndim == 2 or all( cov_mats_meas == repeat( cov_mats_meas[:, :, 0][:, :, None], From 278972c7390a7f6372c9fe39543c3f5a83b4c617 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 23 Oct 2023 13:20:47 +0100 Subject: [PATCH 119/232] Ignore linter warnings for all, sum, any --- pyrecest/__init__.py | 2 +- pyrecest/distributions/abstract_dirac_distribution.py | 1 + pyrecest/distributions/abstract_mixture.py | 1 + .../distributions/abstract_orthogonal_basis_distribution.py | 1 + pyrecest/distributions/cart_prod/__init__.py | 1 + .../cart_prod/abstract_hypercylindrical_distribution.py | 1 + .../cart_prod/hypercylindrical_dirac_distribution.py | 1 + .../cart_prod/partially_wrapped_normal_distribution.py | 1 + pyrecest/distributions/circle/__init__.py | 1 + .../distributions/circle/circular_fourier_distribution.py | 1 + pyrecest/distributions/circle/circular_mixture.py | 1 + pyrecest/distributions/conditional/__init__.py | 1 + pyrecest/distributions/hypersphere_subset/__init__.py | 1 + .../abstract_hypersphere_subset_dirac_distribution.py | 1 + .../abstract_hypersphere_subset_distribution.py | 1 + .../distributions/hypersphere_subset/bingham_distribution.py | 1 + .../hypersphere_subset/hyperspherical_dirac_distribution.py | 1 + .../spherical_harmonics_distribution_complex.py | 1 + .../spherical_harmonics_distribution_real.py | 1 + .../hypersphere_subset/von_mises_fisher_distribution.py | 1 + pyrecest/distributions/hypertorus/__init__.py | 1 + .../hypertorus/abstract_hypertoroidal_distribution.py | 1 + .../hypertorus/hypertoroidal_dirac_distribution.py | 1 + .../hypertorus/hypertoroidal_wrapped_normal_distribution.py | 1 + .../distributions/hypertorus/toroidal_dirac_distribution.py | 1 + .../hypertorus/toroidal_von_mises_sine_distribution.py | 1 + pyrecest/distributions/nonperiodic/__init__.py | 1 + .../distributions/nonperiodic/abstract_linear_distribution.py | 1 + pyrecest/distributions/nonperiodic/gaussian_mixture.py | 1 + pyrecest/evaluation/determine_all_deviations.py | 1 + pyrecest/evaluation/iterate_configs_and_runs.py | 2 +- pyrecest/evaluation/plot_results.py | 1 + pyrecest/evaluation/summarize_filter_results.py | 1 + pyrecest/filters/abstract_particle_filter.py | 1 + pyrecest/filters/circular_particle_filter.py | 1 + pyrecest/filters/global_nearest_neighbor.py | 1 + pyrecest/filters/hypertoroidal_particle_filter.py | 1 + pyrecest/sampling/hyperspherical_sampler.py | 2 +- pyrecest/sampling/hypertoroidal_sampler.py | 2 +- pyrecest/tests/__init__.py | 1 + pyrecest/tests/distributions/__init__.py | 1 + .../test_abstract_hyperhemispherical_distribution.py | 1 + .../distributions/test_hypercylindrical_dirac_distribution.py | 1 + .../distributions/test_hyperspherical_dirac_distribution.py | 1 + pyrecest/tests/distributions/test_hyperspherical_mixture.py | 1 + .../distributions/test_hypertoroidal_dirac_distribution.py | 1 + pyrecest/tests/distributions/test_se3_dirac_distribution.py | 1 + .../test_spherical_harmonics_distribution_complex.py | 1 + .../tests/distributions/test_toroidal_uniform_distribution.py | 1 + .../tests/distributions/test_wrapped_normal_distribution.py | 1 + pyrecest/tests/filters/__init__.py | 1 + pyrecest/tests/filters/test_global_nearest_neighbor.py | 1 + pyrecest/tests/test_evaluation_basic.py | 4 +++- pyrecest/tests/test_hypertoroidal_sampler.py | 1 + pyrecest/utils/__init__.py | 1 + 55 files changed, 57 insertions(+), 5 deletions(-) diff --git a/pyrecest/__init__.py b/pyrecest/__init__.py index 8cff810a..0beba0b6 100644 --- a/pyrecest/__init__.py +++ b/pyrecest/__init__.py @@ -1 +1 @@ -import pyrecest._backend \ No newline at end of file +import pyrecest._backend diff --git a/pyrecest/distributions/abstract_dirac_distribution.py b/pyrecest/distributions/abstract_dirac_distribution.py index 63394d0a..02843ac0 100644 --- a/pyrecest/distributions/abstract_dirac_distribution.py +++ b/pyrecest/distributions/abstract_dirac_distribution.py @@ -3,6 +3,7 @@ from collections.abc import Callable from typing import Union +# pylint: disable=redefined-builtin from pyrecest.backend import ( amax, apply_along_axis, diff --git a/pyrecest/distributions/abstract_mixture.py b/pyrecest/distributions/abstract_mixture.py index dbf1d88c..d8c219d9 100644 --- a/pyrecest/distributions/abstract_mixture.py +++ b/pyrecest/distributions/abstract_mixture.py @@ -3,6 +3,7 @@ import warnings from typing import Union +# pylint: disable=redefined-builtin from pyrecest.backend import ( count_nonzero, empty, diff --git a/pyrecest/distributions/abstract_orthogonal_basis_distribution.py b/pyrecest/distributions/abstract_orthogonal_basis_distribution.py index 0f63b50d..15aba14c 100644 --- a/pyrecest/distributions/abstract_orthogonal_basis_distribution.py +++ b/pyrecest/distributions/abstract_orthogonal_basis_distribution.py @@ -2,6 +2,7 @@ import warnings from abc import abstractmethod +# pylint: disable=redefined-builtin from pyrecest.backend import exp, imag, real, all from .abstract_distribution_type import AbstractDistributionType diff --git a/pyrecest/distributions/cart_prod/__init__.py b/pyrecest/distributions/cart_prod/__init__.py index e69de29b..8b137891 100644 --- a/pyrecest/distributions/cart_prod/__init__.py +++ b/pyrecest/distributions/cart_prod/__init__.py @@ -0,0 +1 @@ + diff --git a/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py b/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py index fc1068cf..12091c39 100644 --- a/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py +++ b/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py @@ -4,6 +4,7 @@ import scipy.integrate import scipy.optimize +# pylint: disable=redefined-builtin from pyrecest.backend import ( allclose, any, diff --git a/pyrecest/distributions/cart_prod/hypercylindrical_dirac_distribution.py b/pyrecest/distributions/cart_prod/hypercylindrical_dirac_distribution.py index a16ff6fa..2927e01a 100644 --- a/pyrecest/distributions/cart_prod/hypercylindrical_dirac_distribution.py +++ b/pyrecest/distributions/cart_prod/hypercylindrical_dirac_distribution.py @@ -1,5 +1,6 @@ from typing import Union +# pylint: disable=redefined-builtin from pyrecest.backend import cos, full, int32, int64, sin, sum, tile from ..hypertorus.hypertoroidal_dirac_distribution import HypertoroidalDiracDistribution diff --git a/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py b/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py index cad6510b..ba9e7fca 100644 --- a/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py +++ b/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py @@ -2,6 +2,7 @@ from math import pi from typing import Union +# pylint: disable=redefined-builtin from pyrecest.backend import ( allclose, array, diff --git a/pyrecest/distributions/circle/__init__.py b/pyrecest/distributions/circle/__init__.py index e69de29b..8b137891 100644 --- a/pyrecest/distributions/circle/__init__.py +++ b/pyrecest/distributions/circle/__init__.py @@ -0,0 +1 @@ + diff --git a/pyrecest/distributions/circle/circular_fourier_distribution.py b/pyrecest/distributions/circle/circular_fourier_distribution.py index a4d7c20e..3f4aa914 100644 --- a/pyrecest/distributions/circle/circular_fourier_distribution.py +++ b/pyrecest/distributions/circle/circular_fourier_distribution.py @@ -3,6 +3,7 @@ from typing import Union import matplotlib.pyplot as plt +# pylint: disable=redefined-builtin from pyrecest.backend import ( arange, array, diff --git a/pyrecest/distributions/circle/circular_mixture.py b/pyrecest/distributions/circle/circular_mixture.py index 720f5512..f716ff38 100644 --- a/pyrecest/distributions/circle/circular_mixture.py +++ b/pyrecest/distributions/circle/circular_mixture.py @@ -1,6 +1,7 @@ import collections import warnings +# pylint: disable=redefined-builtin from pyrecest.backend import shape, sum from ..hypertorus.hypertoroidal_mixture import HypertoroidalMixture diff --git a/pyrecest/distributions/conditional/__init__.py b/pyrecest/distributions/conditional/__init__.py index e69de29b..8b137891 100644 --- a/pyrecest/distributions/conditional/__init__.py +++ b/pyrecest/distributions/conditional/__init__.py @@ -0,0 +1 @@ + diff --git a/pyrecest/distributions/hypersphere_subset/__init__.py b/pyrecest/distributions/hypersphere_subset/__init__.py index e69de29b..8b137891 100644 --- a/pyrecest/distributions/hypersphere_subset/__init__.py +++ b/pyrecest/distributions/hypersphere_subset/__init__.py @@ -0,0 +1 @@ + diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_dirac_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_dirac_distribution.py index 0d73b52f..a675c6c6 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_dirac_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_dirac_distribution.py @@ -1,3 +1,4 @@ +# pylint: disable=redefined-builtin from pyrecest.backend import log, sum from ..abstract_dirac_distribution import AbstractDiracDistribution diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py index 8a89c6ec..188de10d 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py @@ -3,6 +3,7 @@ from math import pi from typing import Union +# pylint: disable=redefined-builtin from pyrecest.backend import ( abs, array, diff --git a/pyrecest/distributions/hypersphere_subset/bingham_distribution.py b/pyrecest/distributions/hypersphere_subset/bingham_distribution.py index 5adf4eba..9d0a23b6 100644 --- a/pyrecest/distributions/hypersphere_subset/bingham_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/bingham_distribution.py @@ -1,5 +1,6 @@ from math import pi +# pylint: disable=redefined-builtin from pyrecest.backend import all, abs, amax, diag, exp, eye, linalg, sum, zeros from scipy.integrate import quad from scipy.special import iv diff --git a/pyrecest/distributions/hypersphere_subset/hyperspherical_dirac_distribution.py b/pyrecest/distributions/hypersphere_subset/hyperspherical_dirac_distribution.py index 1d71282f..4ac972d7 100644 --- a/pyrecest/distributions/hypersphere_subset/hyperspherical_dirac_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/hyperspherical_dirac_distribution.py @@ -1,4 +1,5 @@ import matplotlib.pyplot as plt +# pylint: disable=redefined-builtin from pyrecest.backend import linalg, reshape, sum from ..circle.circular_dirac_distribution import CircularDiracDistribution diff --git a/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py b/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py index 005c879a..577cc315 100644 --- a/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py +++ b/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py @@ -1,6 +1,7 @@ from math import pi import scipy +# pylint: disable=redefined-builtin from pyrecest.backend import ( abs, all, diff --git a/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_real.py b/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_real.py index f612aec7..dbdbf4a1 100644 --- a/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_real.py +++ b/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_real.py @@ -1,3 +1,4 @@ +# pylint: disable=redefined-builtin from pyrecest.backend import ( all, atleast_2d, diff --git a/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py b/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py index 1cb4ea84..deeda7bb 100644 --- a/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py @@ -2,6 +2,7 @@ from typing import Union import pyrecest.backend +# pylint: disable=redefined-builtin from pyrecest.backend import ( abs, all, diff --git a/pyrecest/distributions/hypertorus/__init__.py b/pyrecest/distributions/hypertorus/__init__.py index e69de29b..8b137891 100644 --- a/pyrecest/distributions/hypertorus/__init__.py +++ b/pyrecest/distributions/hypertorus/__init__.py @@ -0,0 +1 @@ + diff --git a/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py b/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py index aadf6fab..d95a3274 100644 --- a/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py +++ b/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py @@ -4,6 +4,7 @@ import matplotlib.pyplot as plt import pyrecest.backend +# pylint: disable=redefined-builtin from pyrecest.backend import ( abs, angle, diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py b/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py index 142eb685..e54567ce 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py @@ -3,6 +3,7 @@ from math import pi from typing import Union +# pylint: disable=redefined-builtin from pyrecest.backend import ( arctan2, atleast_1d, diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py b/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py index a1768566..3bee59b6 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py @@ -2,6 +2,7 @@ from math import pi from typing import Union +# pylint: disable=redefined-builtin from pyrecest.backend import ( allclose, arange, diff --git a/pyrecest/distributions/hypertorus/toroidal_dirac_distribution.py b/pyrecest/distributions/hypertorus/toroidal_dirac_distribution.py index 66ec4ff6..ed60c465 100644 --- a/pyrecest/distributions/hypertorus/toroidal_dirac_distribution.py +++ b/pyrecest/distributions/hypertorus/toroidal_dirac_distribution.py @@ -1,3 +1,4 @@ +# pylint: disable=redefined-builtin from pyrecest.backend import column_stack, cos, diag, dot, sin, sqrt, sum, tile from .abstract_toroidal_distribution import AbstractToroidalDistribution diff --git a/pyrecest/distributions/hypertorus/toroidal_von_mises_sine_distribution.py b/pyrecest/distributions/hypertorus/toroidal_von_mises_sine_distribution.py index 6a0c31f9..95329c01 100644 --- a/pyrecest/distributions/hypertorus/toroidal_von_mises_sine_distribution.py +++ b/pyrecest/distributions/hypertorus/toroidal_von_mises_sine_distribution.py @@ -1,5 +1,6 @@ from math import pi +# pylint: disable=redefined-builtin from pyrecest.backend import all, array, cos, exp, mod, sin, sum from scipy.special import comb, iv diff --git a/pyrecest/distributions/nonperiodic/__init__.py b/pyrecest/distributions/nonperiodic/__init__.py index e69de29b..8b137891 100644 --- a/pyrecest/distributions/nonperiodic/__init__.py +++ b/pyrecest/distributions/nonperiodic/__init__.py @@ -0,0 +1 @@ + diff --git a/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py b/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py index 5725fd77..8e15210c 100644 --- a/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py +++ b/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py @@ -3,6 +3,7 @@ import matplotlib.pyplot as plt import pyrecest.backend +# pylint: disable=redefined-builtin from pyrecest.backend import ( array, atleast_1d, diff --git a/pyrecest/distributions/nonperiodic/gaussian_mixture.py b/pyrecest/distributions/nonperiodic/gaussian_mixture.py index 35285796..fa5a3bb9 100644 --- a/pyrecest/distributions/nonperiodic/gaussian_mixture.py +++ b/pyrecest/distributions/nonperiodic/gaussian_mixture.py @@ -1,4 +1,5 @@ +# pylint: disable=redefined-builtin from pyrecest.backend import array, dot, ones, stack, sum from .abstract_linear_distribution import AbstractLinearDistribution diff --git a/pyrecest/evaluation/determine_all_deviations.py b/pyrecest/evaluation/determine_all_deviations.py index 8cc90242..22f53637 100644 --- a/pyrecest/evaluation/determine_all_deviations.py +++ b/pyrecest/evaluation/determine_all_deviations.py @@ -2,6 +2,7 @@ from typing import Callable import numpy as np +# pylint: disable=redefined-builtin from pyrecest.backend import any, empty, isinf, ndim, sum diff --git a/pyrecest/evaluation/iterate_configs_and_runs.py b/pyrecest/evaluation/iterate_configs_and_runs.py index 450cb68e..387a2b0c 100644 --- a/pyrecest/evaluation/iterate_configs_and_runs.py +++ b/pyrecest/evaluation/iterate_configs_and_runs.py @@ -77,4 +77,4 @@ def iterate_configs_and_runs( f"Filter {config_no} config {filter_config['parameter']} run {run} FAILED: {str(err)}" ) - return last_filter_states, run_times, run_failed, groundtruths, measurements \ No newline at end of file + return last_filter_states, run_times, run_failed, groundtruths, measurements diff --git a/pyrecest/evaluation/plot_results.py b/pyrecest/evaluation/plot_results.py index 4e8bc0ac..7fe35f8f 100644 --- a/pyrecest/evaluation/plot_results.py +++ b/pyrecest/evaluation/plot_results.py @@ -1,6 +1,7 @@ import warnings import matplotlib.pyplot as plt +# pylint: disable=redefined-builtin from pyrecest.backend import any, array, isnan, ones, shape from .get_axis_label import get_axis_label diff --git a/pyrecest/evaluation/summarize_filter_results.py b/pyrecest/evaluation/summarize_filter_results.py index 77af38b2..67ab3d57 100644 --- a/pyrecest/evaluation/summarize_filter_results.py +++ b/pyrecest/evaluation/summarize_filter_results.py @@ -1,5 +1,6 @@ import warnings +# pylint: disable=redefined-builtin from pyrecest.backend import mean, std, sum from .determine_all_deviations import determine_all_deviations diff --git a/pyrecest/filters/abstract_particle_filter.py b/pyrecest/filters/abstract_particle_filter.py index e1f0d2b6..5295c492 100644 --- a/pyrecest/filters/abstract_particle_filter.py +++ b/pyrecest/filters/abstract_particle_filter.py @@ -1,5 +1,6 @@ from collections.abc import Callable +# pylint: disable=redefined-builtin from pyrecest.backend import ndim, ones_like, random, sum, zeros from pyrecest.distributions.abstract_manifold_specific_distribution import ( AbstractManifoldSpecificDistribution, diff --git a/pyrecest/filters/circular_particle_filter.py b/pyrecest/filters/circular_particle_filter.py index fdef6efe..4041a587 100644 --- a/pyrecest/filters/circular_particle_filter.py +++ b/pyrecest/filters/circular_particle_filter.py @@ -1,5 +1,6 @@ from typing import Union +# pylint: disable=redefined-builtin from pyrecest.backend import float64, int32, int64, sum from .hypertoroidal_particle_filter import HypertoroidalParticleFilter diff --git a/pyrecest/filters/global_nearest_neighbor.py b/pyrecest/filters/global_nearest_neighbor.py index 24c98bce..8962d465 100644 --- a/pyrecest/filters/global_nearest_neighbor.py +++ b/pyrecest/filters/global_nearest_neighbor.py @@ -1,3 +1,4 @@ +# pylint: disable=redefined-builtin from pyrecest.backend import empty, full, repeat, squeeze, stack, all from scipy.optimize import linear_sum_assignment from scipy.spatial.distance import cdist diff --git a/pyrecest/filters/hypertoroidal_particle_filter.py b/pyrecest/filters/hypertoroidal_particle_filter.py index fff92044..97d6b036 100644 --- a/pyrecest/filters/hypertoroidal_particle_filter.py +++ b/pyrecest/filters/hypertoroidal_particle_filter.py @@ -3,6 +3,7 @@ from math import pi from typing import Union +# pylint: disable=redefined-builtin from pyrecest.backend import ( arange, int32, diff --git a/pyrecest/sampling/hyperspherical_sampler.py b/pyrecest/sampling/hyperspherical_sampler.py index 1958da44..82169240 100644 --- a/pyrecest/sampling/hyperspherical_sampler.py +++ b/pyrecest/sampling/hyperspherical_sampler.py @@ -267,4 +267,4 @@ def get_grid(self, grid_density_parameter: int | list[int]): "scheme": "fibonacci_hopf", "layer-parameter": grid_density_parameter, } - return grid, grid_specific_description \ No newline at end of file + return grid, grid_specific_description diff --git a/pyrecest/sampling/hypertoroidal_sampler.py b/pyrecest/sampling/hypertoroidal_sampler.py index 78cd269b..8f358451 100644 --- a/pyrecest/sampling/hypertoroidal_sampler.py +++ b/pyrecest/sampling/hypertoroidal_sampler.py @@ -27,4 +27,4 @@ def get_grid(self, grid_density_parameter: int): points = linspace(0.0, 2.0 * pi, grid_density_parameter, endpoint=False) # Set it to the middle of the interval instead of the start points += (2.0 * pi / grid_density_parameter) / 2.0 - return points \ No newline at end of file + return points diff --git a/pyrecest/tests/__init__.py b/pyrecest/tests/__init__.py index e69de29b..8b137891 100644 --- a/pyrecest/tests/__init__.py +++ b/pyrecest/tests/__init__.py @@ -0,0 +1 @@ + diff --git a/pyrecest/tests/distributions/__init__.py b/pyrecest/tests/distributions/__init__.py index e69de29b..8b137891 100644 --- a/pyrecest/tests/distributions/__init__.py +++ b/pyrecest/tests/distributions/__init__.py @@ -0,0 +1 @@ + diff --git a/pyrecest/tests/distributions/test_abstract_hyperhemispherical_distribution.py b/pyrecest/tests/distributions/test_abstract_hyperhemispherical_distribution.py index aebc17ee..2fb2288d 100644 --- a/pyrecest/tests/distributions/test_abstract_hyperhemispherical_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hyperhemispherical_distribution.py @@ -2,6 +2,7 @@ from math import pi import numpy.testing as npt +# pylint: disable=redefined-builtin from pyrecest.backend import array, linalg, ones, sum from pyrecest.distributions import ( HyperhemisphericalWatsonDistribution, diff --git a/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py b/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py index 7aa6bad9..1050fcc2 100644 --- a/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py @@ -2,6 +2,7 @@ from math import pi import numpy.testing as npt +# pylint: disable=redefined-builtin from pyrecest.backend import ( array, exp, diff --git a/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py b/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py index d41eab2e..c108af98 100644 --- a/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py @@ -3,6 +3,7 @@ import numpy.testing as npt import pyrecest.backend +# pylint: disable=redefined-builtin from pyrecest.backend import array, linalg, mod, ones, random, sqrt, sum from pyrecest.distributions import VonMisesFisherDistribution from pyrecest.distributions.hypersphere_subset.hyperspherical_dirac_distribution import ( diff --git a/pyrecest/tests/distributions/test_hyperspherical_mixture.py b/pyrecest/tests/distributions/test_hyperspherical_mixture.py index a1743c23..6a0f9a34 100644 --- a/pyrecest/tests/distributions/test_hyperspherical_mixture.py +++ b/pyrecest/tests/distributions/test_hyperspherical_mixture.py @@ -2,6 +2,7 @@ from math import pi from numpy.testing import assert_allclose +# pylint: disable=redefined-builtin from pyrecest.backend import arange, array, linspace, meshgrid, sqrt, stack, sum from pyrecest.distributions import ( AbstractHypersphereSubsetDistribution, diff --git a/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py b/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py index 5c5f36fb..8acdd78e 100644 --- a/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py @@ -3,6 +3,7 @@ from math import pi import numpy.testing as npt +# pylint: disable=redefined-builtin from pyrecest.backend import ( array, exp, diff --git a/pyrecest/tests/distributions/test_se3_dirac_distribution.py b/pyrecest/tests/distributions/test_se3_dirac_distribution.py index 7c67cf21..7f11a031 100644 --- a/pyrecest/tests/distributions/test_se3_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_se3_dirac_distribution.py @@ -1,5 +1,6 @@ import unittest +# pylint: disable=redefined-builtin from pyrecest.backend import array, concatenate, diag, linalg, sum, tile from pyrecest.distributions import ( GaussianDistribution, diff --git a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py index f606b320..6e82c913 100644 --- a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py +++ b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py @@ -3,6 +3,7 @@ import numpy.testing as npt from parameterized import parameterized +# pylint: disable=redefined-builtin from pyrecest.backend import ( all, allclose, diff --git a/pyrecest/tests/distributions/test_toroidal_uniform_distribution.py b/pyrecest/tests/distributions/test_toroidal_uniform_distribution.py index e00922d3..e9e21472 100644 --- a/pyrecest/tests/distributions/test_toroidal_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_toroidal_uniform_distribution.py @@ -2,6 +2,7 @@ from math import pi import pyrecest.backend +# pylint: disable=redefined-builtin from pyrecest.backend import all, allclose, array, ones, tile, zeros from pyrecest.distributions.hypertorus.toroidal_uniform_distribution import ( ToroidalUniformDistribution, diff --git a/pyrecest/tests/distributions/test_wrapped_normal_distribution.py b/pyrecest/tests/distributions/test_wrapped_normal_distribution.py index 520a660e..d6f0c12b 100644 --- a/pyrecest/tests/distributions/test_wrapped_normal_distribution.py +++ b/pyrecest/tests/distributions/test_wrapped_normal_distribution.py @@ -2,6 +2,7 @@ from math import pi import numpy.testing as npt +# pylint: disable=redefined-builtin from pyrecest.backend import ( allclose, arange, diff --git a/pyrecest/tests/filters/__init__.py b/pyrecest/tests/filters/__init__.py index e69de29b..8b137891 100644 --- a/pyrecest/tests/filters/__init__.py +++ b/pyrecest/tests/filters/__init__.py @@ -0,0 +1 @@ + diff --git a/pyrecest/tests/filters/test_global_nearest_neighbor.py b/pyrecest/tests/filters/test_global_nearest_neighbor.py index fe7da744..d6a630be 100644 --- a/pyrecest/tests/filters/test_global_nearest_neighbor.py +++ b/pyrecest/tests/filters/test_global_nearest_neighbor.py @@ -4,6 +4,7 @@ import pyrecest.backend import scipy from parameterized import parameterized +# pylint: disable=redefined-builtin from pyrecest.backend import ( all, allclose, diff --git a/pyrecest/tests/test_evaluation_basic.py b/pyrecest/tests/test_evaluation_basic.py index aa60a8a9..ad666db3 100644 --- a/pyrecest/tests/test_evaluation_basic.py +++ b/pyrecest/tests/test_evaluation_basic.py @@ -7,7 +7,9 @@ from pyrecest.backend import ndim from pyrecest.backend import eye from pyrecest.backend import array +# pylint: disable=redefined-builtin from pyrecest.backend import any +# pylint: disable=redefined-builtin from pyrecest.backend import all from pyrecest.backend import empty from pyrecest.backend import zeros @@ -545,4 +547,4 @@ def test_summarize_filter_results(self): if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyrecest/tests/test_hypertoroidal_sampler.py b/pyrecest/tests/test_hypertoroidal_sampler.py index 5d07aa2a..a0134ef5 100644 --- a/pyrecest/tests/test_hypertoroidal_sampler.py +++ b/pyrecest/tests/test_hypertoroidal_sampler.py @@ -2,6 +2,7 @@ from math import pi import numpy.testing as npt +# pylint: disable=redefined-builtin from pyrecest.backend import all, diff, std from pyrecest.sampling.hypertoroidal_sampler import CircularUniformSampler diff --git a/pyrecest/utils/__init__.py b/pyrecest/utils/__init__.py index e69de29b..8b137891 100644 --- a/pyrecest/utils/__init__.py +++ b/pyrecest/utils/__init__.py @@ -0,0 +1 @@ + From 0f00bea4f72ca13873a3a237accbcf9025752d4c Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 23 Oct 2023 13:34:20 +0100 Subject: [PATCH 120/232] More..... --- pyrecest/_backend/__init__.py | 2 ++ pyrecest/_backend/numpy/__init__.py | 2 ++ pyrecest/_backend/pytorch/__init__.py | 2 ++ pyrecest/distributions/abstract_dirac_distribution.py | 2 +- .../lin_hypersphere_cart_prod_dirac_distribution.py | 4 ++-- .../circle/abstract_circular_distribution.py | 2 +- .../hypersphere_subset/bingham_distribution.py | 4 ++-- pyrecest/filters/wrapped_normal_filter.py | 10 +++++----- pyrecest/tests/test_evaluation_basic.py | 1 - 9 files changed, 17 insertions(+), 12 deletions(-) diff --git a/pyrecest/_backend/__init__.py b/pyrecest/_backend/__init__.py index bbe145ef..27c5b91d 100644 --- a/pyrecest/_backend/__init__.py +++ b/pyrecest/_backend/__init__.py @@ -188,6 +188,8 @@ def get_backend_name(): "isinf", "deg2rad", "argsort", + "max", + "min", ], "autodiff": [ "custom_gradient", diff --git a/pyrecest/_backend/numpy/__init__.py b/pyrecest/_backend/numpy/__init__.py index 82edd36e..a7c8ddef 100644 --- a/pyrecest/_backend/numpy/__init__.py +++ b/pyrecest/_backend/numpy/__init__.py @@ -93,6 +93,8 @@ isinf, deg2rad, argsort, + max, + min, ) from scipy.special import erf, gamma, polygamma # NOQA diff --git a/pyrecest/_backend/pytorch/__init__.py b/pyrecest/_backend/pytorch/__init__.py index 839fdbc7..23705965 100644 --- a/pyrecest/_backend/pytorch/__init__.py +++ b/pyrecest/_backend/pytorch/__init__.py @@ -53,6 +53,8 @@ isinf, deg2rad, argsort, + max, + min, ) from torch import repeat_interleave as repeat from torch import ( diff --git a/pyrecest/distributions/abstract_dirac_distribution.py b/pyrecest/distributions/abstract_dirac_distribution.py index 02843ac0..a6fe7f56 100644 --- a/pyrecest/distributions/abstract_dirac_distribution.py +++ b/pyrecest/distributions/abstract_dirac_distribution.py @@ -118,7 +118,7 @@ def kld_numerical(self, *args): raise NotImplementedError("PDF:UNDEFINED, not supported") def mode(self, rel_tol=0.001): - highest_val, ind = amax(self.w) + highest_val, ind = max(self.w) if (highest_val / self.w.size) < (1 + rel_tol): warnings.warn( "The samples may be equally weighted, .mode is likely to return a bad result." diff --git a/pyrecest/distributions/cart_prod/lin_hypersphere_cart_prod_dirac_distribution.py b/pyrecest/distributions/cart_prod/lin_hypersphere_cart_prod_dirac_distribution.py index d5077dbe..5857a1c2 100644 --- a/pyrecest/distributions/cart_prod/lin_hypersphere_cart_prod_dirac_distribution.py +++ b/pyrecest/distributions/cart_prod/lin_hypersphere_cart_prod_dirac_distribution.py @@ -1,4 +1,4 @@ -from pyrecest.backend import abs, amax, linalg +from pyrecest.backend import abs, max, linalg from ..abstract_se3_distribution import AbstractSE3Distribution from .lin_bounded_cart_prod_dirac_distribution import ( @@ -11,7 +11,7 @@ class LinHypersphereCartProdDiracDistribution( ): def __init__(self, bound_dim, d, w=None): assert ( - amax(abs(linalg.norm(d[:, : (bound_dim + 1)], None, -1) - 1), 0) < 1e-5 + max(abs(linalg.norm(d[:, : (bound_dim + 1)], None, -1) - 1), 0) < 1e-5 ), "The hypersphere ssubset part of d must be normalized" AbstractSE3Distribution.__init__(self) LinBoundedCartProdDiracDistribution.__init__(self, d, w) diff --git a/pyrecest/distributions/circle/abstract_circular_distribution.py b/pyrecest/distributions/circle/abstract_circular_distribution.py index 8d75b322..eaa7b924 100644 --- a/pyrecest/distributions/circle/abstract_circular_distribution.py +++ b/pyrecest/distributions/circle/abstract_circular_distribution.py @@ -67,6 +67,6 @@ def to_wn(self): @staticmethod def plot_circle(*args, **kwargs): - theta = np.append(linspace(0.0, 2.0 * pi, 320), 0) + theta = linspace(0.0, 2.0 * pi, 320) p = plt.plot(cos(theta), sin(theta), *args, **kwargs) return p diff --git a/pyrecest/distributions/hypersphere_subset/bingham_distribution.py b/pyrecest/distributions/hypersphere_subset/bingham_distribution.py index 9d0a23b6..0793304b 100644 --- a/pyrecest/distributions/hypersphere_subset/bingham_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/bingham_distribution.py @@ -1,7 +1,7 @@ from math import pi # pylint: disable=redefined-builtin -from pyrecest.backend import all, abs, amax, diag, exp, eye, linalg, sum, zeros +from pyrecest.backend import all, abs, max, diag, exp, eye, linalg, sum, zeros from scipy.integrate import quad from scipy.special import iv @@ -20,7 +20,7 @@ def __init__(self, Z, M): # Verify that M is orthogonal epsilon = 0.001 - assert amax(abs(M @ M.T - eye(self.dim + 1))) < epsilon, "M is not orthogonal" + assert max(abs(M @ M.T - eye(self.dim + 1))) < epsilon, "M is not orthogonal" self.Z = Z self.M = M diff --git a/pyrecest/filters/wrapped_normal_filter.py b/pyrecest/filters/wrapped_normal_filter.py index 2369be84..021cd902 100644 --- a/pyrecest/filters/wrapped_normal_filter.py +++ b/pyrecest/filters/wrapped_normal_filter.py @@ -2,7 +2,7 @@ from functools import partial from math import pi -from pyrecest.backend import amax, amin, array, log, mod +from pyrecest.backend import max, min, array, log, mod from pyrecest.distributions import CircularDiracDistribution, WrappedNormalDistribution from pyrecest.filters.abstract_circular_filter import AbstractCircularFilter @@ -43,16 +43,16 @@ def update_nonlinear_progressive( while lambda_ > 0: wd = self.filter_state.to_dirac5() likelihood_vals = array([likelihood(z, x) for x in wd.d]) - likelihood_vals_min = amin(likelihood_vals) - likelihood_vals_max = amax(likelihood_vals) + likelihood_vals_min = min(likelihood_vals) + likelihood_vals_max = max(likelihood_vals) if likelihood_vals_max == 0: raise ValueError( "Progressive update failed because likelihood is 0 everywhere" ) - w_min = amin(wd.w) - w_max = amax(wd.w) + w_min = min(wd.w) + w_max = max(wd.w) if likelihood_vals_min == 0 or w_min == 0: raise ZeroDivisionError("Cannot perform division by zero") diff --git a/pyrecest/tests/test_evaluation_basic.py b/pyrecest/tests/test_evaluation_basic.py index ad666db3..8bd4215c 100644 --- a/pyrecest/tests/test_evaluation_basic.py +++ b/pyrecest/tests/test_evaluation_basic.py @@ -11,7 +11,6 @@ from pyrecest.backend import any # pylint: disable=redefined-builtin from pyrecest.backend import all -from pyrecest.backend import empty from pyrecest.backend import zeros import numpy as np import os From da49fe72c1e37d01ee1daa3622463f3f054310e5 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 23 Oct 2023 13:40:22 +0100 Subject: [PATCH 121/232] More --- pyrecest/evaluation/evaluate_for_simulation_config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrecest/evaluation/evaluate_for_simulation_config.py b/pyrecest/evaluation/evaluate_for_simulation_config.py index c8b2276e..5a5ee95c 100644 --- a/pyrecest/evaluation/evaluate_for_simulation_config.py +++ b/pyrecest/evaluation/evaluate_for_simulation_config.py @@ -61,7 +61,7 @@ def evaluate_for_simulation_config( def get_all_seeds(n_runs: int, seed_input=None, consecutive_seed: bool = True): if seed_input is None: - seed_input = random.randint(1, 0xFFFFFFFF, dtype=uint32) # nosec + seed_input = random.randint(1, 0xFFFFFFFF) # nosec if seed_input.shape[0] == n_runs: all_seeds = seed_input From 8948afa0f7414ae6326ec4e02693bd97ebd29962 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 23 Oct 2023 13:42:08 +0100 Subject: [PATCH 122/232] More....... --- pyrecest/_backend/pytorch/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrecest/_backend/pytorch/__init__.py b/pyrecest/_backend/pytorch/__init__.py index 23705965..fad4054c 100644 --- a/pyrecest/_backend/pytorch/__init__.py +++ b/pyrecest/_backend/pytorch/__init__.py @@ -186,7 +186,7 @@ def convert_to_wider_dtype(tensor_list): if len(set(dtype_list)) == 1: return tensor_list - wider_dtype_index = max(dtype_list) + wider_dtype_index = amax(dtype_list) wider_dtype = list(_DTYPES.keys())[wider_dtype_index] From 433368f1b8df9ccb3fe3d999353991ac8d2d00de Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 23 Oct 2023 13:45:33 +0100 Subject: [PATCH 123/232] More............. --- .../abstract_hypercylindrical_distribution.py | 32 +++++-------------- 1 file changed, 8 insertions(+), 24 deletions(-) diff --git a/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py b/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py index 12091c39..4efc6a8c 100644 --- a/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py +++ b/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py @@ -129,34 +129,18 @@ def linear_covariance_numerical(self, approximate_mean=None): [[0.0, 2.0 * pi], [0.0, 2.0 * pi], [-float("inf"), float("inf")]], ) elif self.bound_dim == 1 and self.lin_dim == 2: - C = empty((2, 2)) - C[0, 0], _ = nquad( - lambda x, y, z: (y - approximate_mean[0]) ** 2 * self.pdf([x, y, z]), - [ + range_list = [ [0.0, 2.0 * pi], [-float("inf"), float("inf")], [-float("inf"), float("inf")], - ], - ) - C[0, 1], _ = nquad( - lambda x, y, z: (y - approximate_mean[0]) - * (z - approximate_mean[1]) - * self.pdf([x, y, z]), - [ - [0, 2 * pi], - [-float("inf"), float("inf")], - [-float("inf"), float("inf")], - ], - ) + ] + C = empty((2, 2)) + C[0, 0], _ = nquad(lambda x, y, z: (y - approximate_mean[0]) ** 2 * self.pdf([x, y, z]), range_list) + C[0, 1], _ = nquad(lambda x, y, z: (y - approximate_mean[0]) + * (z - approximate_mean[1]) + * self.pdf([x, y, z]), range_list) C[1, 0] = C[0, 1] - C[1, 1], _ = nquad( - lambda x, y, z: (z - approximate_mean[1]) ** 2 * self.pdf([x, y, z]), - [ - [0.0, 2.0 * pi], - [-float("inf"), float("inf")], - [-float("inf"), float("inf")], - ], - ) + C[1, 1], _ = nquad(lambda x, y, z: (z - approximate_mean[1]) ** 2 * self.pdf([x, y, z]), range_list) else: raise ValueError("Cannot determine linear covariance for this dimension.") From 304731e26c894bd1bb06167c41efa77a1ff37b7e Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 23 Oct 2023 14:02:45 +0100 Subject: [PATCH 124/232] More... --- .github/workflows/tests.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index ffb364d9..8cad835b 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -30,14 +30,11 @@ jobs: export CUDA_VISIBLE_DEVICES="" python -m pip install --upgrade pip python -m pip install poetry - poetry env use python poetry install --extras healpy_support --extras pytorch_support - name: List files and check Python and package versions run: | poetry env use python - #poetry run python -c "import torch; print(torch.version.cuda)" - poetry run python -m pip install --upgrade --force-reinstall torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu poetry run python -c "import torch; print(torch.version.cuda)" poetry run python -c 'import sys; print(sys.version_info[:])' poetry run python -m pip freeze From 6f8f60f023b58874cb81c421247d50d8024f5e70 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 23 Oct 2023 16:36:17 +0100 Subject: [PATCH 125/232] More... --- pyrecest/_backend/__init__.py | 1 + pyrecest/_backend/numpy/__init__.py | 1 + pyrecest/_backend/pytorch/__init__.py | 1 + .../hypersphere_subset/bingham_distribution.py | 4 ++-- .../hyperhemispherical_watson_distribution.py | 6 +++--- pyrecest/tests/filters/test_global_nearest_neighbor.py | 7 ++++--- 6 files changed, 12 insertions(+), 8 deletions(-) diff --git a/pyrecest/_backend/__init__.py b/pyrecest/_backend/__init__.py index 27c5b91d..a0721881 100644 --- a/pyrecest/_backend/__init__.py +++ b/pyrecest/_backend/__init__.py @@ -190,6 +190,7 @@ def get_backend_name(): "argsort", "max", "min", + "roll", ], "autodiff": [ "custom_gradient", diff --git a/pyrecest/_backend/numpy/__init__.py b/pyrecest/_backend/numpy/__init__.py index a7c8ddef..f7b180a3 100644 --- a/pyrecest/_backend/numpy/__init__.py +++ b/pyrecest/_backend/numpy/__init__.py @@ -95,6 +95,7 @@ argsort, max, min, + roll, ) from scipy.special import erf, gamma, polygamma # NOQA diff --git a/pyrecest/_backend/pytorch/__init__.py b/pyrecest/_backend/pytorch/__init__.py index fad4054c..9360d13b 100644 --- a/pyrecest/_backend/pytorch/__init__.py +++ b/pyrecest/_backend/pytorch/__init__.py @@ -55,6 +55,7 @@ argsort, max, min, + roll, ) from torch import repeat_interleave as repeat from torch import ( diff --git a/pyrecest/distributions/hypersphere_subset/bingham_distribution.py b/pyrecest/distributions/hypersphere_subset/bingham_distribution.py index 0793304b..5f4dc1da 100644 --- a/pyrecest/distributions/hypersphere_subset/bingham_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/bingham_distribution.py @@ -1,7 +1,7 @@ from math import pi # pylint: disable=redefined-builtin -from pyrecest.backend import all, abs, max, diag, exp, eye, linalg, sum, zeros +from pyrecest.backend import all, abs, max, diag, exp, eye, linalg, sum, zeros, argsort from scipy.integrate import quad from scipy.special import iv @@ -81,7 +81,7 @@ def multiply(self, B2): C = 0.5 * (C + C.T) # Symmetrize D, V = linalg.eig(C) - order = np.argsort(D) # Sort eigenvalues + order = argsort(D) # Sort eigenvalues V = V[:, order] Z_ = D[order] Z_ = Z_ - Z_[-1] # Ensure last entry is zero diff --git a/pyrecest/distributions/hypersphere_subset/hyperhemispherical_watson_distribution.py b/pyrecest/distributions/hypersphere_subset/hyperhemispherical_watson_distribution.py index 8aae6ef1..c4b1f83e 100644 --- a/pyrecest/distributions/hypersphere_subset/hyperhemispherical_watson_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/hyperhemispherical_watson_distribution.py @@ -1,6 +1,6 @@ from typing import Union -from pyrecest.backend import allclose, int32, int64, zeros +from pyrecest.backend import allclose, int32, int64, zeros, concatenate, array from .abstract_hyperhemispherical_distribution import ( AbstractHyperhemisphericalDistribution, @@ -17,7 +17,7 @@ def __init__(self, mu, kappa): ) def pdf(self, xs): - return 2 * self.dist_full_sphere.pdf(xs) + return 2.0 * self.dist_full_sphere.pdf(xs) def set_mode(self, mu) -> "HyperhemisphericalWatsonDistribution": w = self @@ -50,7 +50,7 @@ def mode(self): def shift(self, shift_by) -> "HyperhemisphericalWatsonDistribution": assert allclose( - self.mu, np.append(zeros(self.dim - 1), 1) + self.mu, concatenate((zeros(self.dim - 1), array([1]))) ), "There is no true shifting for the hyperhemisphere. This is a function for compatibility and only works when mu is [0,0,...,1]." dist_shifted = self dist_shifted.mu = shift_by diff --git a/pyrecest/tests/filters/test_global_nearest_neighbor.py b/pyrecest/tests/filters/test_global_nearest_neighbor.py index d6a630be..2c1bf59b 100644 --- a/pyrecest/tests/filters/test_global_nearest_neighbor.py +++ b/pyrecest/tests/filters/test_global_nearest_neighbor.py @@ -16,6 +16,7 @@ real, sort, zeros, + roll, ) from pyrecest.distributions import GaussianDistribution from pyrecest.filters import KalmanFilter @@ -196,18 +197,18 @@ def test_association_no_clutter(self): npt.assert_array_equal(association, [0, 1, 2]) # Shift them - measurements = np.roll(perfect_meas_ordered, 1, axis=1) + measurements = roll(perfect_meas_ordered, 1, axis=1) association = tracker.find_association(measurements, self.meas_mat, eye(2)) npt.assert_array_equal(measurements[:, association], perfect_meas_ordered) # Shift them and add a bit of noise - measurements = np.roll(perfect_meas_ordered, 1, axis=1) + 0.1 + measurements = roll(perfect_meas_ordered, 1, axis=1) + 0.1 association = tracker.find_association(measurements, self.meas_mat, eye(2)) npt.assert_array_equal(measurements[:, association], perfect_meas_ordered + 0.1) # Use different covariances association = tracker.find_association( - np.roll(perfect_meas_ordered, 1, axis=1) + 0.1, + roll(perfect_meas_ordered, 1, axis=1) + 0.1, self.meas_mat, self.all_different_meas_covs, ) From d3500eaedc3f6afde77976eea03b1d92272e4ed8 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 23 Oct 2023 16:42:30 +0100 Subject: [PATCH 126/232] Let megalinter pass once so that the cache is generated --- .github/workflows/mega-linter.yml | 57 +------------------------------ 1 file changed, 1 insertion(+), 56 deletions(-) diff --git a/.github/workflows/mega-linter.yml b/.github/workflows/mega-linter.yml index 8a00a80e..42377008 100644 --- a/.github/workflows/mega-linter.yml +++ b/.github/workflows/mega-linter.yml @@ -169,59 +169,4 @@ jobs: - name: Clean up temporary files (in case they are generated) run: rm -rf myenv CMakeFiles CMakeCache.txt cmake_install.cmake Makefile - # MegaLinter - - name: MegaLinter - id: ml - # You can override MegaLinter flavor used to have faster performances - # More info at https://megalinter.io/latest/configuration/#shared-variables - uses: oxsecurity/megalinter/flavors/python@v7.4.0 - env: - # All available variables are described in documentation - # https://megalinter.io/latest/configuration/#shared-variables - # ADD YOUR CUSTOM ENV VARIABLES HERE OR DEFINE THEM IN A FILE .mega-linter.yml AT THE ROOT OF YOUR REPOSITORY - VALIDATE_ALL_CODEBASE: true # ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} # Validates all source when push on main, else just the git diff with main. Override with true if you always want to lint all sources - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - EMAIL_REPORTER_SMTP_PASSWORD: ${{ secrets.SMTP_PASSWORD }} - - # Upload MegaLinter artifacts - - name: Archive production artifacts - if: always() - uses: actions/upload-artifact@v3 - with: - name: MegaLinter reports - path: | - megalinter-reports - mega-linter.log - - # Create Pull Request step - - name: Create Pull Request with applied fixes - id: cpr - if: github.ref == 'refs/heads/main' && steps.ml.outputs.has_updated_sources == 1 && (env.APPLY_FIXES_EVENT == 'all' || env.APPLY_FIXES_EVENT == github.event_name) && env.APPLY_FIXES_MODE == 'pull_request' && (github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository) && !contains(github.event.head_commit.message, 'skip fix') - uses: peter-evans/create-pull-request@v5 - with: - token: ${{ secrets.PAT || secrets.GITHUB_TOKEN }} - commit-message: "[MegaLinter] Apply linters automatic fixes" - title: "[MegaLinter] Apply linters automatic fixes" - branch: megalinter-fixes - labels: bot - base: main - - # Output PR details - - name: Create PR output - if: github.ref == 'refs/heads/main' && steps.ml.outputs.has_updated_sources == 1 && (env.APPLY_FIXES_EVENT == 'all' || env.APPLY_FIXES_EVENT == github.event_name) && env.APPLY_FIXES_MODE == 'pull_request' && (github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository) && !contains(github.event.head_commit.message, 'skip fix') - run: | - echo "Pull Request Number - ${{ steps.cpr.outputs.pull-request-number }}" - echo "Pull Request URL - ${{ steps.cpr.outputs.pull-request-url }}" - - # Push new commit if applicable (for now works only on PR from same repository, not from forks) - - name: Prepare commit - if: steps.ml.outputs.has_updated_sources == 1 && (env.APPLY_FIXES_EVENT == 'all' || env.APPLY_FIXES_EVENT == github.event_name) && env.APPLY_FIXES_MODE == 'commit' && github.ref != 'refs/heads/main' && (github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository) && !contains(github.event.head_commit.message, 'skip fix') - run: sudo chown -Rc $UID .git/ - - name: Commit and push applied linter fixes - if: steps.ml.outputs.has_updated_sources == 1 && (env.APPLY_FIXES_EVENT == 'all' || env.APPLY_FIXES_EVENT == github.event_name) && env.APPLY_FIXES_MODE == 'commit' && github.ref != 'refs/heads/main' && (github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository) && !contains(github.event.head_commit.message, 'skip fix') - uses: stefanzweifel/git-auto-commit-action@v4 - with: - branch: ${{ github.event.pull_request.head.ref || github.head_ref || github.ref }} - commit_message: "[MegaLinter] Apply linters fixes" - commit_user_name: megalinter-bot - commit_user_email: megalinter-bot@iar.kit.edu + \ No newline at end of file From a82e3b2cf03f4fe4b92d31d39f8dbee62e44cc54 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 23 Oct 2023 17:11:33 +0100 Subject: [PATCH 127/232] Reverted change to megalinter --- .github/workflows/mega-linter.yml | 394 +++++++++++++++++------------- 1 file changed, 223 insertions(+), 171 deletions(-) diff --git a/.github/workflows/mega-linter.yml b/.github/workflows/mega-linter.yml index 42377008..2853f1aa 100644 --- a/.github/workflows/mega-linter.yml +++ b/.github/workflows/mega-linter.yml @@ -1,172 +1,224 @@ ---- -# MegaLinter GitHub Action configuration file -# More info at https://megalinter.io -name: MegaLinter - -permissions: - checks: write - pull-requests: write - contents: write - -on: # yamllint disable-line rule:truthy - # Trigger mega-linter at every push. Action will also be visible from Pull Requests to main - push: # Comment this line to trigger action only on pull-requests (not recommended if you don't pay for GH Actions) - pull_request: - branches: [master, main] - -env: # Comment env block if you do not want to apply fixes - # Apply linter fixes configuration - APPLY_FIXES: all # When active, APPLY_FIXES must also be defined as environment variable (in github/workflows/mega-linter.yml or other CI tool) - APPLY_FIXES_EVENT: push # Decide which event triggers application of fixes in a commit or a PR (pull_request, push, all) - # I tried around a lot to make the test workflow run on pull_request events, - # but it it only worked when creating a new PR. By default, this would target the branch of the PR - # and not the main branch. Instead of trying around to cherry-pick the commits from the PR - # etc. I decided to just run the workflow on push events to the main branch and then create - # a PR targeting the main branch. - APPLY_FIXES_MODE: pull_request # If APPLY_FIXES is used, defines if the fixes are directly committed (commit) or posted in a PR (pull_request) - -concurrency: - group: ${{ github.ref }}-${{ github.workflow }} - cancel-in-progress: true - -jobs: - build: - name: MegaLinter - runs-on: ubuntu-latest - permissions: - # Give the default GITHUB_TOKEN write permission to commit and push, comment issues & post new PR - # Remove the ones you do not need - contents: write - issues: write - pull-requests: write - steps: - - name: Checkout Code - uses: actions/checkout@v4 - with: - ref: ${{ github.head_ref }} - fetch-depth: 0 - - - name: Create alpine-wheels folder - run: mkdir alpine-wheels - - - name: Cache wheel directory - id: cache-wheels - uses: actions/cache@v3 - with: - path: ${{ github.workspace }}/alpine-wheels - key: ${{ runner.os }}-alpine-wheels-${{ hashFiles('requirements-dev.txt') }} - restore-keys: | - ${{ runner.os }}-alpine-wheels-${{ hashFiles('requirements-dev.txt') }} - - - name: Set up Alpine Linux - if: steps.cache-wheels.outputs.cache-hit != 'true' - uses: jirutka/setup-alpine@v1 - with: # cfitsio, py3-pkgconfig, curl-dev, and zlib for healpy - packages: > - build-base - python3-dev - py3-pip - gfortran - fftw-dev - git - openblas-dev - cmake - geos-dev - cfitsio - py3-pkgconfig - curl-dev - zlib-dev - - - name: List workspace - run: ls -l . - - - name: Upgrade pip and install requirements for building - if: steps.cache-wheels.outputs.cache-hit != 'true' - run: | - python -m pip install --upgrade pip - python -m pip install meson-python meson ninja wheel build - shell: alpine.sh {0} - - - name: Remove version settings - if: steps.cache-wheels.outputs.cache-hit != 'true' - run: | - sed 's/==.*//' requirements-dev.txt > requirements-dev_no_version.txt - shell: alpine.sh {0} - - name: Remove torch entry (unsupported by alpine) - if: steps.cache-wheels.outputs.cache-hit != 'true' - run: | - sed -i '/^torch/d' requirements-dev_no_version.txt - shell: alpine.sh {0} - - - name: Run CMake to find LAPACK - if: steps.cache-wheels.outputs.cache-hit != 'true' - run: | - echo "find_package(LAPACK)" > CMakeLists.txt - echo "if(LAPACK_FOUND)" >> CMakeLists.txt - echo ' message("LAPACK found")' >> CMakeLists.txt - echo ' message("LAPACK include dirs: ${LAPACK_INCLUDE_DIRS}")' >> CMakeLists.txt - echo ' message("LAPACK libraries: ${LAPACK_LIBRARIES}")' >> CMakeLists.txt - echo "else()" >> CMakeLists.txt - echo ' message(FATAL_ERROR "LAPACK not found")' >> CMakeLists.txt - echo "endif()" >> CMakeLists.txt - cmake . - shell: alpine.sh {0} - - - name: Run pkg-config to find LAPACK - if: steps.cache-wheels.outputs.cache-hit != 'true' - run: | - pkg-config --libs --cflags lapack || true - shell: alpine.sh {0} - - - name: Build wheel for pyshtools - if: steps.cache-wheels.outputs.cache-hit != 'true' - run: | - git clone https://github.com/FlorianPfaff/SHTOOLS.git - cd SHTOOLS - git checkout meson - python -m build - cd .. - mv SHTOOLS/dist/*.whl ./alpine-wheels/ - rm -rf SHTOOLS - shell: alpine.sh {0} - - - name: Install required packages and dependencies - if: steps.cache-wheels.outputs.cache-hit != 'true' - run: python -m pip install --find-links=./alpine-wheels -r requirements-dev_no_version.txt - shell: alpine.sh {0} - - - name: Print requirements-dev_no_version.txt - if: steps.cache-wheels.outputs.cache-hit != 'true' - run: cat requirements-dev_no_version.txt - shell: alpine.sh {0} - - - name: Freeze requirements - if: steps.cache-wheels.outputs.cache-hit != 'true' - run: python -m pip freeze > requirements-tmp.txt - shell: alpine.sh {0} - - - name: Download compatible packages - if: steps.cache-wheels.outputs.cache-hit != 'true' - run: | - python -m pip download --find-links=./alpine-wheels -r requirements-tmp.txt -d ./alpine-wheels - shell: alpine.sh {0} - - - name: Build wheels - if: steps.cache-wheels.outputs.cache-hit != 'true' - run: | - cd ./alpine-wheels - for src in *.tar.gz; do - python -m pip wheel "$src" --no-deps --wheel-dir=./ - rm "$src" - done - cd .. - shell: alpine.sh {0} - - - name: List available wheels - run: ls -l ./alpine-wheels - - - name: Clean up temporary files (in case they are generated) - run: rm -rf myenv CMakeFiles CMakeCache.txt cmake_install.cmake Makefile - - \ No newline at end of file +--- + # MegaLinter GitHub Action configuration file + # More info at https://megalinter.io + name: MegaLinter + + permissions: + checks: write + pull-requests: write + contents: write + + on: # yamllint disable-line rule:truthy + # Trigger mega-linter at every push. Action will also be visible from Pull Requests to main + push: # Comment this line to trigger action only on pull-requests (not recommended if you don't pay for GH Actions) + pull_request: + branches: [master, main] + + env: # Comment env block if you do not want to apply fixes + # Apply linter fixes configuration + APPLY_FIXES: all # When active, APPLY_FIXES must also be defined as environment variable (in github/workflows/mega-linter.yml or other CI tool) + APPLY_FIXES_EVENT: push # Decide which event triggers application of fixes in a commit or a PR (pull_request, push, all) + # I tried around a lot to make the test workflow run on pull_request events, + # but it it only worked when creating a new PR. By default, this would target the branch of the PR + # and not the main branch. Instead of trying around to cherry-pick the commits from the PR + # etc. I decided to just run the workflow on push events to the main branch and then create + # a PR targeting the main branch. + APPLY_FIXES_MODE: pull_request # If APPLY_FIXES is used, defines if the fixes are directly committed (commit) or posted in a PR (pull_request) + + concurrency: + group: ${{ github.ref }}-${{ github.workflow }} + cancel-in-progress: true + + jobs: + build: + name: MegaLinter + runs-on: ubuntu-latest + permissions: + # Give the default GITHUB_TOKEN write permission to commit and push, comment issues & post new PR + # Remove the ones you do not need + contents: write + issues: write + pull-requests: write + steps: + - name: Checkout Code + uses: actions/checkout@v4 + with: + ref: ${{ github.head_ref }} + fetch-depth: 0 + + - name: Create alpine-wheels folder + run: mkdir alpine-wheels + + - name: Cache wheel directory + id: cache-wheels + uses: actions/cache@v3 + with: + path: ${{ github.workspace }}/alpine-wheels + key: ${{ runner.os }}-alpine-wheels-${{ hashFiles('requirements-dev.txt') }} + restore-keys: | + ${{ runner.os }}-alpine-wheels-${{ hashFiles('requirements-dev.txt') }} + - name: Set up Alpine Linux + if: steps.cache-wheels.outputs.cache-hit != 'true' + uses: jirutka/setup-alpine@v1 + with: # cfitsio, py3-pkgconfig, curl-dev, and zlib for healpy + packages: > + build-base + python3-dev + py3-pip + gfortran + fftw-dev + git + openblas-dev + cmake + geos-dev + cfitsio + py3-pkgconfig + curl-dev + zlib-dev + - name: List workspace + run: ls -l . + + - name: Upgrade pip and install requirements for building + if: steps.cache-wheels.outputs.cache-hit != 'true' + run: | + python -m pip install --upgrade pip + python -m pip install meson-python meson ninja wheel build + shell: alpine.sh {0} + + - name: Remove version settings + if: steps.cache-wheels.outputs.cache-hit != 'true' + run: | + sed 's/==.*//' requirements-dev.txt > requirements-dev_no_version.txt + shell: alpine.sh {0} + + - name: Remove torch entry (unsupported by alpine) + if: steps.cache-wheels.outputs.cache-hit != 'true' + run: | + sed -i '/^torch/d' requirements-dev_no_version.txt + shell: alpine.sh {0} + + - name: Run CMake to find LAPACK + if: steps.cache-wheels.outputs.cache-hit != 'true' + run: | + echo "find_package(LAPACK)" > CMakeLists.txt + echo "if(LAPACK_FOUND)" >> CMakeLists.txt + echo ' message("LAPACK found")' >> CMakeLists.txt + echo ' message("LAPACK include dirs: ${LAPACK_INCLUDE_DIRS}")' >> CMakeLists.txt + echo ' message("LAPACK libraries: ${LAPACK_LIBRARIES}")' >> CMakeLists.txt + echo "else()" >> CMakeLists.txt + echo ' message(FATAL_ERROR "LAPACK not found")' >> CMakeLists.txt + echo "endif()" >> CMakeLists.txt + cmake . + shell: alpine.sh {0} + + - name: Run pkg-config to find LAPACK + if: steps.cache-wheels.outputs.cache-hit != 'true' + run: | + pkg-config --libs --cflags lapack || true + shell: alpine.sh {0} + + - name: Build wheel for pyshtools + if: steps.cache-wheels.outputs.cache-hit != 'true' + run: | + git clone https://github.com/FlorianPfaff/SHTOOLS.git + cd SHTOOLS + git checkout meson + python -m build + cd .. + mv SHTOOLS/dist/*.whl ./alpine-wheels/ + rm -rf SHTOOLS + shell: alpine.sh {0} + + - name: Install required packages and dependencies + if: steps.cache-wheels.outputs.cache-hit != 'true' + run: python -m pip install --find-links=./alpine-wheels -r requirements-dev_no_version.txt + shell: alpine.sh {0} + + - name: Print requirements-dev_no_version.txt + if: steps.cache-wheels.outputs.cache-hit != 'true' + run: cat requirements-dev_no_version.txt + shell: alpine.sh {0} + + - name: Freeze requirements + if: steps.cache-wheels.outputs.cache-hit != 'true' + run: python -m pip freeze > requirements-tmp.txt + shell: alpine.sh {0} + + - name: Download compatible packages + if: steps.cache-wheels.outputs.cache-hit != 'true' + run: | + python -m pip download --find-links=./alpine-wheels -r requirements-tmp.txt -d ./alpine-wheels + shell: alpine.sh {0} + + - name: Build wheels + if: steps.cache-wheels.outputs.cache-hit != 'true' + run: | + cd ./alpine-wheels + for src in *.tar.gz; do + python -m pip wheel "$src" --no-deps --wheel-dir=./ + rm "$src" + done + cd .. + shell: alpine.sh {0} + + - name: List available wheels + run: ls -l ./alpine-wheels + + - name: Clean up temporary files (in case they are generated) + run: rm -rf myenv CMakeFiles CMakeCache.txt cmake_install.cmake Makefile + + # MegaLinter + - name: MegaLinter + id: ml + # You can override MegaLinter flavor used to have faster performances + # More info at https://megalinter.io/latest/configuration/#shared-variables + uses: oxsecurity/megalinter/flavors/python@v7.4.0 + env: + # All available variables are described in documentation + # https://megalinter.io/latest/configuration/#shared-variables + # ADD YOUR CUSTOM ENV VARIABLES HERE OR DEFINE THEM IN A FILE .mega-linter.yml AT THE ROOT OF YOUR REPOSITORY + VALIDATE_ALL_CODEBASE: true # ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} # Validates all source when push on main, else just the git diff with main. Override with true if you always want to lint all sources + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + EMAIL_REPORTER_SMTP_PASSWORD: ${{ secrets.SMTP_PASSWORD }} + + # Upload MegaLinter artifacts + - name: Archive production artifacts + if: always() + uses: actions/upload-artifact@v3 + with: + name: MegaLinter reports + path: | + megalinter-reports + mega-linter.log + # Create Pull Request step + - name: Create Pull Request with applied fixes + id: cpr + if: github.ref == 'refs/heads/main' && steps.ml.outputs.has_updated_sources == 1 && (env.APPLY_FIXES_EVENT == 'all' || env.APPLY_FIXES_EVENT == github.event_name) && env.APPLY_FIXES_MODE == 'pull_request' && (github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository) && !contains(github.event.head_commit.message, 'skip fix') + uses: peter-evans/create-pull-request@v5 + with: + token: ${{ secrets.PAT || secrets.GITHUB_TOKEN }} + commit-message: "[MegaLinter] Apply linters automatic fixes" + title: "[MegaLinter] Apply linters automatic fixes" + branch: megalinter-fixes + labels: bot + base: main + + # Output PR details + - name: Create PR output + if: github.ref == 'refs/heads/main' && steps.ml.outputs.has_updated_sources == 1 && (env.APPLY_FIXES_EVENT == 'all' || env.APPLY_FIXES_EVENT == github.event_name) && env.APPLY_FIXES_MODE == 'pull_request' && (github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository) && !contains(github.event.head_commit.message, 'skip fix') + run: | + echo "Pull Request Number - ${{ steps.cpr.outputs.pull-request-number }}" + echo "Pull Request URL - ${{ steps.cpr.outputs.pull-request-url }}" + # Push new commit if applicable (for now works only on PR from same repository, not from forks) + - name: Prepare commit + if: steps.ml.outputs.has_updated_sources == 1 && (env.APPLY_FIXES_EVENT == 'all' || env.APPLY_FIXES_EVENT == github.event_name) && env.APPLY_FIXES_MODE == 'commit' && github.ref != 'refs/heads/main' && (github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository) && !contains(github.event.head_commit.message, 'skip fix') + run: sudo chown -Rc $UID .git/ + - name: Commit and push applied linter fixes + if: steps.ml.outputs.has_updated_sources == 1 && (env.APPLY_FIXES_EVENT == 'all' || env.APPLY_FIXES_EVENT == github.event_name) && env.APPLY_FIXES_MODE == 'commit' && github.ref != 'refs/heads/main' && (github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository) && !contains(github.event.head_commit.message, 'skip fix') + uses: stefanzweifel/git-auto-commit-action@v4 + with: + branch: ${{ github.event.pull_request.head.ref || github.head_ref || github.ref }} + commit_message: "[MegaLinter] Apply linters fixes" + commit_user_name: megalinter-bot + commit_user_email: megalinter-bot@iar.kit.edu \ No newline at end of file From 55779785d5bd4081fa5f4bc0e776cbd710e1b6f3 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 23 Oct 2023 17:20:02 +0100 Subject: [PATCH 128/232] Adapted tests --- .github/workflows/tests.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 8cad835b..523d6415 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -30,7 +30,10 @@ jobs: export CUDA_VISIBLE_DEVICES="" python -m pip install --upgrade pip python -m pip install poetry - poetry install --extras healpy_support --extras pytorch_support + poetry env use python + # Install CPU-only version of PyTorch + python -m pip install torch torchvision torchaudio -f https://download.pytorch.org/whl/cpu + poetry install --extras healpy_support --no-root - name: List files and check Python and package versions run: | From 0de563db11c79fe2a889b5dc399db74871deff2e Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 23 Oct 2023 17:24:46 +0100 Subject: [PATCH 129/232] Fixes --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 523d6415..99c61909 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -38,9 +38,9 @@ jobs: - name: List files and check Python and package versions run: | poetry env use python - poetry run python -c "import torch; print(torch.version.cuda)" poetry run python -c 'import sys; print(sys.version_info[:])' poetry run python -m pip freeze + poetry run python -c "import torch; print(torch.version.cuda)" - name: Run tests with numpy backend run: | From f6c256dd8d157c8a0a604bca8e1e052c6e35d8c6 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 23 Oct 2023 17:30:33 +0100 Subject: [PATCH 130/232] Trying around --- .github/workflows/tests.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 99c61909..bb44ef0f 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -31,9 +31,8 @@ jobs: python -m pip install --upgrade pip python -m pip install poetry poetry env use python - # Install CPU-only version of PyTorch - python -m pip install torch torchvision torchaudio -f https://download.pytorch.org/whl/cpu - poetry install --extras healpy_support --no-root + poetry install --extras healpy_support --no-root # skip the project root package + python -m pip install torch==2.1.0 torchvision torchaudio -f https://download.pytorch.org/whl/cpu - name: List files and check Python and package versions run: | From d25f918877d279f9968668547223320ee9458238 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 23 Oct 2023 17:30:58 +0100 Subject: [PATCH 131/232] Trying --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index bb44ef0f..67262bb2 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -32,7 +32,7 @@ jobs: python -m pip install poetry poetry env use python poetry install --extras healpy_support --no-root # skip the project root package - python -m pip install torch==2.1.0 torchvision torchaudio -f https://download.pytorch.org/whl/cpu + poetry run python -m pip install torch==2.1.0 torchvision torchaudio -f https://download.pytorch.org/whl/cpu - name: List files and check Python and package versions run: | From 4cea9471c36c8355ad62bcc01298091df642e0a8 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 23 Oct 2023 17:31:22 +0100 Subject: [PATCH 132/232] More trying --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 67262bb2..b89c5d30 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -32,7 +32,7 @@ jobs: python -m pip install poetry poetry env use python poetry install --extras healpy_support --no-root # skip the project root package - poetry run python -m pip install torch==2.1.0 torchvision torchaudio -f https://download.pytorch.org/whl/cpu + poetry run python -m pip install torch==2.1.0+cpu torchvision torchaudio -f https://download.pytorch.org/whl/cpu - name: List files and check Python and package versions run: | From e16c955a07986f5e890b7c4062eef375c62348af Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 23 Oct 2023 17:44:58 +0100 Subject: [PATCH 133/232] Flag for cpu support --- .github/workflows/tests.yml | 5 +++-- pyproject.toml | 12 +++++++----- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index b89c5d30..a9e6865c 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -31,8 +31,9 @@ jobs: python -m pip install --upgrade pip python -m pip install poetry poetry env use python - poetry install --extras healpy_support --no-root # skip the project root package - poetry run python -m pip install torch==2.1.0+cpu torchvision torchaudio -f https://download.pytorch.org/whl/cpu + # poetry install --extras healpy_support --no-root # skip the project root package + # poetry run python -m pip install torch==2.1.0+cpu torchvision torchaudio -f https://download.pytorch.org/whl/cpu + poetry install --extras healpy_support --extras "pytorch_cpu_support" - name: List files and check Python and package versions run: | diff --git a/pyproject.toml b/pyproject.toml index 495cb6de..e93c3a90 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ description = "Framework for recursive Bayesian estimation in Python." readme = "README.md" authors = ["Florian Pfaff "] version = "0.5.0" - + [tool.poetry.dependencies] python = ">=3.10,<3.13" numpy = "*" @@ -16,15 +16,17 @@ pyshtools = "*" beartype = "*" numpy-quaternion = "*" shapely = "*" +torch = { version = "*", optional = true, markers = "extra == 'torch-cpu'" } +torchvision = { version = "*", optional = true, markers = "extra == 'torch-cpu'" } +torchaudio = { version = "*", optional = true, markers = "extra == 'torch-cpu'" } [tool.poetry.extras] healpy_support = ["healpy"] -pytorch_support = ["torch"] +pytorch_support = ["torch", "torchvision", "torchaudio"] +pytorch_cpu_support = ["torch-cpu"] [tool.poetry.group.dev.dependencies] healpy = "*" -torch = "*" autopep8 = "^2.0.2" pytest = "*" -parameterized = "*" - +parameterized = "*" \ No newline at end of file From 5ec54e14d7b43a84f3a98d2693192ab3dd687db6 Mon Sep 17 00:00:00 2001 From: github-actions Date: Mon, 23 Oct 2023 16:46:00 +0000 Subject: [PATCH 134/232] Update requirements.txt --- poetry.lock | 89 +++++++++++++++++++++++++++++++++++++++----- requirements-dev.txt | 7 ---- requirements.txt | 9 +++++ 3 files changed, 89 insertions(+), 16 deletions(-) diff --git a/poetry.lock b/poetry.lock index a78fa8eb..6525cff2 100644 --- a/poetry.lock +++ b/poetry.lock @@ -312,7 +312,7 @@ test = ["pytest (>=6)"] name = "filelock" version = "3.12.4" description = "A platform independent file lock." -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "filelock-3.12.4-py3-none-any.whl", hash = "sha256:08c21d87ded6e2b9da6728c3dff51baf1dcecf973b768ef35bcbc3447edb9ad4"}, @@ -408,7 +408,7 @@ woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] name = "fsspec" version = "2023.10.0" description = "File-system specification" -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "fsspec-2023.10.0-py3-none-any.whl", hash = "sha256:346a8f024efeb749d2a5fca7ba8854474b1ff9af7c3faaf636a4548781136529"}, @@ -496,7 +496,7 @@ files = [ name = "jinja2" version = "3.1.2" description = "A very fast and expressive template engine." -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, @@ -626,7 +626,7 @@ files = [ name = "markupsafe" version = "2.1.3" description = "Safely add untrusted strings to HTML/XML markup." -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa"}, @@ -761,7 +761,7 @@ tests = ["pytest (>=4.6)"] name = "networkx" version = "3.2" description = "Python package for creating and manipulating graphs and networks" -optional = false +optional = true python-versions = ">=3.9" files = [ {file = "networkx-3.2-py3-none-any.whl", hash = "sha256:8b25f564bd28f94ac821c58b04ae1a3109e73b001a7d476e4bb0d00d63706bf8"}, @@ -1456,7 +1456,7 @@ files = [ name = "sympy" version = "1.12" description = "Computer algebra system (CAS) in Python" -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "sympy-1.12-py3-none-any.whl", hash = "sha256:c3588cd4295d0c0f603d0f2ae780587e64e2efeedb3521e46b9bb1d08d184fa5"}, @@ -1481,7 +1481,7 @@ files = [ name = "torch" version = "2.1.0" description = "Tensors and Dynamic neural networks in Python with strong GPU acceleration" -optional = false +optional = true python-versions = ">=3.8.0" files = [ {file = "torch-2.1.0-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:bf57f8184b2c317ef81fb33dc233ce4d850cd98ef3f4a38be59c7c1572d175db"}, @@ -1517,6 +1517,76 @@ typing-extensions = "*" [package.extras] opt-einsum = ["opt-einsum (>=3.3)"] +[[package]] +name = "torchaudio" +version = "2.1.0" +description = "An audio package for PyTorch" +optional = true +python-versions = "*" +files = [ + {file = "torchaudio-2.1.0-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:445eba044d70e292acab2a67763ee682af8c776d2d0ca671cdbe43ba396422a3"}, + {file = "torchaudio-2.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cd6f29c78358b632ff7123929e5358dbdf0505849811b57e7108cbd2af42bb44"}, + {file = "torchaudio-2.1.0-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:1602cafb47dd04a61a9b0d77f79721979dacbc844de73174b84467992237c9b2"}, + {file = "torchaudio-2.1.0-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:010f63fe766787e058989ffadd793daadd946ce1de903be171087938cdbdc1d7"}, + {file = "torchaudio-2.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:3629b358af5df25f9b018e3aba09a84c59c809712d7dfe9e31a4145d0092a1df"}, + {file = "torchaudio-2.1.0-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:8bd1eef53c353cea7eb6cbe1013cbd9e51c48987e19d06bdbb29a22846b8c6b1"}, + {file = "torchaudio-2.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fc97182abab2065d8bbf56f3732883e40acfcfec38f2581c97710b1fca93c4a7"}, + {file = "torchaudio-2.1.0-cp311-cp311-manylinux1_x86_64.whl", hash = "sha256:b2cd0873d24645b67c7e269c8a24bd160b8214874207ba90fbc133a482e85b6e"}, + {file = "torchaudio-2.1.0-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:328e5f36830e886c2b6f2a35868858aa464b9c1aae3c87d70b2b4fac3721b822"}, + {file = "torchaudio-2.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:eddd74545d73a74c424936fdc98d817b139be994185eebf60c7663f578118a47"}, + {file = "torchaudio-2.1.0-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:6dd5933188154cb8bd9e634c7812186c1df382a6b5d7be471e894fb488a6757e"}, + {file = "torchaudio-2.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:96a635120c6dd35926aafe1f20bbaf5325c775813082832dde6df390cc8be90e"}, + {file = "torchaudio-2.1.0-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:1cce2133f7b9f813ff146dffccfdb616b73932cec2fc69aa3a4189b8a8b17f8d"}, + {file = "torchaudio-2.1.0-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:0a337db1d5f134d2168870ea0bc026107af0fe1e80ad7d93dee002daae5fe363"}, + {file = "torchaudio-2.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:e91f31e17e2c341a39143197aa552abc55066c178065fa2524b27630e39505cc"}, + {file = "torchaudio-2.1.0-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:349f7b1c28724445fc460f2ec9f60631a5a335dfaebad36994bd11ce22056b1e"}, + {file = "torchaudio-2.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ed92f59d8863578298b3f238cfc6c4c74251598c9e4642246731ba0b8043a033"}, + {file = "torchaudio-2.1.0-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:08818dc390fb398974b7d68ec9fafb16345b3366fa884139a04a062e9cb60684"}, + {file = "torchaudio-2.1.0-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:653016d59401e1f84412e8b76960866f4aeb8a403e3a4d04d5c9a55b67de825b"}, + {file = "torchaudio-2.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:34f66c7171330e3213bf7d76a9efda51067857411aac60d70570239c9ed8c56d"}, +] + +[package.dependencies] +torch = "2.1.0" + +[[package]] +name = "torchvision" +version = "0.16.0" +description = "image and video datasets and models for torch deep learning" +optional = true +python-versions = ">=3.8" +files = [ + {file = "torchvision-0.16.0-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:16c300fdbbe91469f5e9feef8d24c6acabd8849db502a06160dd76ba68e897a0"}, + {file = "torchvision-0.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ef5dec6c48b715353781b83749efcdea03835720a71b377684453ee117aab3c7"}, + {file = "torchvision-0.16.0-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:9e3a2012e463f498de21f6598cc7a266b9a8c6fe15788472fdc419233ea6f3f2"}, + {file = "torchvision-0.16.0-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:e4327e082b703921ae52caeee4f7839f7e6c73cfc5eedea468ecb5c1487ecdbf"}, + {file = "torchvision-0.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:62f01513687cce3480df8928fcc6c09b4aa0433d05ac75e82877acc773f6a568"}, + {file = "torchvision-0.16.0-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:31fdf289bdfb2976f65a14f79f6ddd1ee60113db34622674918e61521c2dc41f"}, + {file = "torchvision-0.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2294a6514a31a6fda562288b28cf6db57877237f4b56ff693262f237a7ed4035"}, + {file = "torchvision-0.16.0-cp311-cp311-manylinux1_x86_64.whl", hash = "sha256:6a24a1e83e4bc7a31b39ef05d2ca4cd2182e95ff10f525edffe1473f7ce16ca1"}, + {file = "torchvision-0.16.0-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:9ed5f21e5a56e466667c6f9f6f93dba2a75e29921108bd70043eaf8e9ba0a7cc"}, + {file = "torchvision-0.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:9ee3d4df7d4a84f883f8ad11fb6510549f40f68dd5469eae601d7e02fb4809b2"}, + {file = "torchvision-0.16.0-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:0c6f36d00b9ce412e367ad6f42e9054cbc890cd9ddd0d200ed9b3b52dd9c225b"}, + {file = "torchvision-0.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:597f60cb03e6f758a00b36b38506f6f38b6c3f1fdfd3921bb9abd60b72d522fd"}, + {file = "torchvision-0.16.0-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:eddd91da4603f1dbb340d9aca82344df64605a0897b17014ac8e0b54dd6e5716"}, + {file = "torchvision-0.16.0-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:79875f5247337723ec363762c2716bcfc13b78b3045e4e58847c696f03d9ed4d"}, + {file = "torchvision-0.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:550c9793637c5369fbcb4e4b6b0e6d53a4f6cc22389f0563ad60ab90e4f1c8ba"}, + {file = "torchvision-0.16.0-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:de7c7302fa2f67a2a151e595a8e7dc3865a445d952e99d5c682ba78f312fedc3"}, + {file = "torchvision-0.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f044cffd252fd293b6df46f38d7eeb2fd4fe931e0114c5263735e3b8c9c60a4f"}, + {file = "torchvision-0.16.0-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:8cb501061f6654da494dd975acc1fa301c4b8aacf96bdbcf1553f51a53ebfd1f"}, + {file = "torchvision-0.16.0-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:5a47108ae6a8effdf09fe35fd0c4d5414e69ca8d2334e87339de497b7b64b0c9"}, + {file = "torchvision-0.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:9b8f06e6a2f80576007b88846f74b680a1ad3b59d2e22b075587b430180e9cfa"}, +] + +[package.dependencies] +numpy = "*" +pillow = ">=5.3.0,<8.3.dev0 || >=8.4.dev0" +requests = "*" +torch = "2.1.0" + +[package.extras] +scipy = ["scipy"] + [[package]] name = "tqdm" version = "4.66.1" @@ -1601,9 +1671,10 @@ viz = ["matplotlib", "nc-time-axis", "seaborn"] [extras] healpy-support = [] -pytorch-support = [] +pytorch-cpu-support = [] +pytorch-support = ["torch", "torchaudio", "torchvision"] [metadata] lock-version = "2.0" python-versions = ">=3.10,<3.13" -content-hash = "0999488f2868769e363292457227ed356e9167576ec5163ca347b800776d1b4d" +content-hash = "36f1963ed6254824942e4eca6d184ab3da24511badd145d7f180614a4bb378fc" diff --git a/requirements-dev.txt b/requirements-dev.txt index ef40946b..3f67c306 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -7,19 +7,14 @@ colorama==0.4.6 ; python_version >= "3.10" and python_version < "3.13" and (sys_ contourpy==1.1.1 ; python_version >= "3.10" and python_version < "3.13" cycler==0.12.1 ; python_version >= "3.10" and python_version < "3.13" exceptiongroup==1.1.3 ; python_version >= "3.10" and python_version < "3.11" -filelock==3.12.4 ; python_version >= "3.10" and python_version < "3.13" filterpy==1.4.5 ; python_version >= "3.10" and python_version < "3.13" fonttools==4.43.1 ; python_version >= "3.10" and python_version < "3.13" -fsspec==2023.10.0 ; python_version >= "3.10" and python_version < "3.13" healpy==1.16.6 ; python_version >= "3.10" and python_version < "3.13" idna==3.4 ; python_version >= "3.10" and python_version < "3.13" iniconfig==2.0.0 ; python_version >= "3.10" and python_version < "3.13" -jinja2==3.1.2 ; python_version >= "3.10" and python_version < "3.13" kiwisolver==1.4.5 ; python_version >= "3.10" and python_version < "3.13" -markupsafe==2.1.3 ; python_version >= "3.10" and python_version < "3.13" matplotlib==3.8.0 ; python_version >= "3.10" and python_version < "3.13" mpmath==1.3.0 ; python_version >= "3.10" and python_version < "3.13" -networkx==3.2 ; python_version >= "3.10" and python_version < "3.13" numpy-quaternion==2022.4.3 ; python_version >= "3.10" and python_version < "3.13" numpy==1.26.1 ; python_version >= "3.10" and python_version < "3.13" packaging==23.2 ; python_version >= "3.10" and python_version < "3.13" @@ -43,9 +38,7 @@ setuptools-scm==8.0.4 ; python_version >= "3.10" and python_version < "3.13" setuptools==68.2.2 ; python_version >= "3.10" and python_version < "3.13" shapely==2.0.2 ; python_version >= "3.10" and python_version < "3.13" six==1.16.0 ; python_version >= "3.10" and python_version < "3.13" -sympy==1.12 ; python_version >= "3.10" and python_version < "3.13" tomli==2.0.1 ; python_version >= "3.10" and python_version < "3.11" -torch==2.1.0 ; python_version >= "3.10" and python_version < "3.13" tqdm==4.66.1 ; python_version >= "3.10" and python_version < "3.13" typing-extensions==4.8.0 ; python_version >= "3.10" and python_version < "3.13" tzdata==2023.3 ; python_version >= "3.10" and python_version < "3.13" diff --git a/requirements.txt b/requirements.txt index cd879482..46f8becf 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,12 +5,17 @@ charset-normalizer==3.3.1 ; python_version >= "3.10" and python_version < "3.13" colorama==0.4.6 ; python_version >= "3.10" and python_version < "3.13" and platform_system == "Windows" contourpy==1.1.1 ; python_version >= "3.10" and python_version < "3.13" cycler==0.12.1 ; python_version >= "3.10" and python_version < "3.13" +filelock==3.12.4 ; python_version >= "3.10" and python_version < "3.13" filterpy==1.4.5 ; python_version >= "3.10" and python_version < "3.13" fonttools==4.43.1 ; python_version >= "3.10" and python_version < "3.13" +fsspec==2023.10.0 ; python_version >= "3.10" and python_version < "3.13" idna==3.4 ; python_version >= "3.10" and python_version < "3.13" +jinja2==3.1.2 ; python_version >= "3.10" and python_version < "3.13" kiwisolver==1.4.5 ; python_version >= "3.10" and python_version < "3.13" +markupsafe==2.1.3 ; python_version >= "3.10" and python_version < "3.13" matplotlib==3.8.0 ; python_version >= "3.10" and python_version < "3.13" mpmath==1.3.0 ; python_version >= "3.10" and python_version < "3.13" +networkx==3.2 ; python_version >= "3.10" and python_version < "3.13" numpy-quaternion==2022.4.3 ; python_version >= "3.10" and python_version < "3.13" numpy==1.26.1 ; python_version >= "3.10" and python_version < "3.13" packaging==23.2 ; python_version >= "3.10" and python_version < "3.13" @@ -30,7 +35,11 @@ setuptools-scm==8.0.4 ; python_version >= "3.10" and python_version < "3.13" setuptools==68.2.2 ; python_version >= "3.10" and python_version < "3.13" shapely==2.0.2 ; python_version >= "3.10" and python_version < "3.13" six==1.16.0 ; python_version >= "3.10" and python_version < "3.13" +sympy==1.12 ; python_version >= "3.10" and python_version < "3.13" tomli==2.0.1 ; python_version >= "3.10" and python_version < "3.11" +torch==2.1.0 ; python_version >= "3.10" and python_version < "3.13" +torchaudio==2.1.0 ; python_version >= "3.10" and python_version < "3.13" +torchvision==0.16.0 ; python_version >= "3.10" and python_version < "3.13" tqdm==4.66.1 ; python_version >= "3.10" and python_version < "3.13" typing-extensions==4.8.0 ; python_version >= "3.10" and python_version < "3.13" tzdata==2023.3 ; python_version >= "3.10" and python_version < "3.13" From 2641300ab7b44428668a0197f5959cd2bc2e8875 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 23 Oct 2023 17:48:38 +0100 Subject: [PATCH 135/232] Removed poetry.lock so that it gets updated --- poetry.lock | 1609 --------------------------------------------------- 1 file changed, 1609 deletions(-) delete mode 100644 poetry.lock diff --git a/poetry.lock b/poetry.lock deleted file mode 100644 index a78fa8eb..00000000 --- a/poetry.lock +++ /dev/null @@ -1,1609 +0,0 @@ -# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. - -[[package]] -name = "astropy" -version = "5.3.4" -description = "Astronomy and astrophysics core library" -optional = false -python-versions = ">=3.9" -files = [ - {file = "astropy-5.3.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a3a6c63abc95d094cd3062e32c1ebf80c07502e4f3094b1e276458db5ce6b6a2"}, - {file = "astropy-5.3.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e85871ec762fc7eab2f7e716c97dad1b3c546bb75941ea7fae6c8eadd51f0bf8"}, - {file = "astropy-5.3.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e82fdad3417b70af381945aa42fdae0f11bc9aaf94b95027b1e24379bf847d6"}, - {file = "astropy-5.3.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbce56f46ec1051fd67a5e2244e5f2e08599a176fe524c0bee2294c62be317b3"}, - {file = "astropy-5.3.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a489c2322136b76a43208e3e9b5a7947a7fd624a10e49d2909b94f12b624da06"}, - {file = "astropy-5.3.4-cp310-cp310-win32.whl", hash = "sha256:c713695e39f5a874705bc3bd262c5d218890e3e7c43f0b6c0b5e7d46bdff527c"}, - {file = "astropy-5.3.4-cp310-cp310-win_amd64.whl", hash = "sha256:2576579befb0674cdfd18f5cc138c919a109c6886a25aa3d8ed8ab4e4607c581"}, - {file = "astropy-5.3.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4ce096dde6b86a87aa84aec4198732ec379fbb7649af66a96f85b96d17214c2a"}, - {file = "astropy-5.3.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:830fb4b19c36bf8092fdd74ecf9df5b78c6435bf571c5e09b7f644875148a058"}, - {file = "astropy-5.3.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9a707c534408d26d90014a1938af883f6cbf43a3dd78df8bb9a191d275c09f8d"}, - {file = "astropy-5.3.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f0bb2b9b93bc879bcd032931e7fc07c3a3de6f9546fed17f0f12974e0ffc83e0"}, - {file = "astropy-5.3.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1fa4437fe8d1e103f14cb1cb4e8449c93ae4190b5e9fd97e9c61a5155de9af0d"}, - {file = "astropy-5.3.4-cp311-cp311-win32.whl", hash = "sha256:c656c7fd3d862bcb9d3c4a87b8e9488d0c351b4edf348410c09a26641b9d4731"}, - {file = "astropy-5.3.4-cp311-cp311-win_amd64.whl", hash = "sha256:4c4971abae8e3ddfb8f40447d78aaf24e6ce44b976b3874770ff533609050366"}, - {file = "astropy-5.3.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:887db411555692fb1858ae305f87fd2ff42a021b68c78abbf3fa1fc64641e895"}, - {file = "astropy-5.3.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e4033d7a6bd2da38b83ec65f7282dfeb2641f2b2d41b1cd392cdbe3d6f8abfff"}, - {file = "astropy-5.3.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2cc6503b79d4fb61ca80e1d37dd609fabca6d2e0124e17f831cc08c2e6ff75e"}, - {file = "astropy-5.3.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f3f9fe1d76d151428a8d2bc7d50f4a47ae6e7141c11880a3ad259ac7b906b03"}, - {file = "astropy-5.3.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:6e0f7ecbb2a8acb3eace99bcaca30dd1ce001e6f4750a009fd9cc3b8d1b49c58"}, - {file = "astropy-5.3.4-cp312-cp312-win32.whl", hash = "sha256:d915e6370315a1a6a40c2576e77d0063f48cc3b5f8873087cad8ad19dd429d19"}, - {file = "astropy-5.3.4-cp312-cp312-win_amd64.whl", hash = "sha256:69f5a3789a8a4cb00815630b63f950be629a983896dc1aba92566ccc7937a77d"}, - {file = "astropy-5.3.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d5d1a1be788344f11a94a5356c1a25b4d45f1736b740edb4d8e3a272b872a8fa"}, - {file = "astropy-5.3.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ae59e4d41461ad96a2573bc51408000a7b4f90dce2bad07646fa6409a12a5a74"}, - {file = "astropy-5.3.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4c4d3a14e8e3a33208683331b16a721ab9f9493ed998d34533532fdaeaa3642"}, - {file = "astropy-5.3.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8f58f53294f07cd3f9173bb113ad60d2cd823501c99251891936202fed76681"}, - {file = "astropy-5.3.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:f79400dc6641bb0202a8998cfb08ad1afe197818e27c946491a292e2ffd16a1b"}, - {file = "astropy-5.3.4-cp39-cp39-win32.whl", hash = "sha256:fd0baa7621d03aa74bb8ba673d7955381d15aed4f30dc2a56654560401fc3aca"}, - {file = "astropy-5.3.4-cp39-cp39-win_amd64.whl", hash = "sha256:9ed6116d07de02183d966e9a5dabc86f6fd3d86cc3e1e8b9feef89fd757be8a6"}, - {file = "astropy-5.3.4.tar.gz", hash = "sha256:d490f7e2faac2ccc01c9244202d629154259af8a979104ced89dc4ace4e6f1d8"}, -] - -[package.dependencies] -numpy = ">=1.21,<2" -packaging = ">=19.0" -pyerfa = ">=2.0" -PyYAML = ">=3.13" - -[package.extras] -all = ["asdf (>=2.10.0)", "beautifulsoup4", "bleach", "bottleneck", "certifi", "dask[array]", "fsspec[http] (>=2022.8.2)", "h5py", "html5lib", "ipython (>=4.2)", "jplephem", "matplotlib (>=3.3,!=3.4.0,!=3.5.2)", "mpmath", "pandas", "pre-commit", "pyarrow (>=5.0.0)", "pytest (>=7.0,<8)", "pytz", "s3fs (>=2022.8.2)", "scipy (>=1.5)", "sortedcontainers", "typing-extensions (>=3.10.0.1)"] -docs = ["Jinja2 (>=3.0)", "matplotlib (>=3.3,!=3.4.0,!=3.5.2)", "pytest (>=7.0,<8)", "scipy (>=1.3)", "sphinx", "sphinx-astropy (>=1.6)", "sphinx-changelog (>=1.2.0)"] -recommended = ["matplotlib (>=3.3,!=3.4.0,!=3.5.2)", "scipy (>=1.5)"] -test = ["pytest (>=7.0,<8)", "pytest-astropy (>=0.10)", "pytest-astropy-header (>=0.2.1)", "pytest-doctestplus (>=0.12)", "pytest-xdist"] -test-all = ["coverage[toml]", "ipython (>=4.2)", "objgraph", "pytest (>=7.0,<8)", "pytest-astropy (>=0.10)", "pytest-astropy-header (>=0.2.1)", "pytest-doctestplus (>=0.12)", "pytest-xdist", "sgp4 (>=2.3)", "skyfield (>=1.20)"] - -[[package]] -name = "autopep8" -version = "2.0.4" -description = "A tool that automatically formats Python code to conform to the PEP 8 style guide" -optional = false -python-versions = ">=3.6" -files = [ - {file = "autopep8-2.0.4-py2.py3-none-any.whl", hash = "sha256:067959ca4a07b24dbd5345efa8325f5f58da4298dab0dde0443d5ed765de80cb"}, - {file = "autopep8-2.0.4.tar.gz", hash = "sha256:2913064abd97b3419d1cc83ea71f042cb821f87e45b9c88cad5ad3c4ea87fe0c"}, -] - -[package.dependencies] -pycodestyle = ">=2.10.0" -tomli = {version = "*", markers = "python_version < \"3.11\""} - -[[package]] -name = "beartype" -version = "0.16.4" -description = "Unbearably fast runtime type checking in pure Python." -optional = false -python-versions = ">=3.8.0" -files = [ - {file = "beartype-0.16.4-py3-none-any.whl", hash = "sha256:64865952f9dff1e17f22684b3c7286fc79754553b47eaefeb1286224ae8c1bd9"}, - {file = "beartype-0.16.4.tar.gz", hash = "sha256:1ada89cf2d6eb30eb6e156eed2eb5493357782937910d74380918e53c2eae0bf"}, -] - -[package.extras] -all = ["typing-extensions (>=3.10.0.0)"] -dev = ["autoapi (>=0.9.0)", "coverage (>=5.5)", "mypy (>=0.800)", "numpy", "pandera", "pydata-sphinx-theme (<=0.7.2)", "pytest (>=4.0.0)", "sphinx", "sphinx (>=4.2.0,<6.0.0)", "sphinxext-opengraph (>=0.7.5)", "tox (>=3.20.1)", "typing-extensions (>=3.10.0.0)"] -doc-rtd = ["autoapi (>=0.9.0)", "pydata-sphinx-theme (<=0.7.2)", "sphinx (>=4.2.0,<6.0.0)", "sphinxext-opengraph (>=0.7.5)"] -test-tox = ["mypy (>=0.800)", "numpy", "pandera", "pytest (>=4.0.0)", "sphinx", "typing-extensions (>=3.10.0.0)"] -test-tox-coverage = ["coverage (>=5.5)"] - -[[package]] -name = "certifi" -version = "2023.7.22" -description = "Python package for providing Mozilla's CA Bundle." -optional = false -python-versions = ">=3.6" -files = [ - {file = "certifi-2023.7.22-py3-none-any.whl", hash = "sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9"}, - {file = "certifi-2023.7.22.tar.gz", hash = "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082"}, -] - -[[package]] -name = "charset-normalizer" -version = "3.3.1" -description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -optional = false -python-versions = ">=3.7.0" -files = [ - {file = "charset-normalizer-3.3.1.tar.gz", hash = "sha256:d9137a876020661972ca6eec0766d81aef8a5627df628b664b234b73396e727e"}, - {file = "charset_normalizer-3.3.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8aee051c89e13565c6bd366813c386939f8e928af93c29fda4af86d25b73d8f8"}, - {file = "charset_normalizer-3.3.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:352a88c3df0d1fa886562384b86f9a9e27563d4704ee0e9d56ec6fcd270ea690"}, - {file = "charset_normalizer-3.3.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:223b4d54561c01048f657fa6ce41461d5ad8ff128b9678cfe8b2ecd951e3f8a2"}, - {file = "charset_normalizer-3.3.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4f861d94c2a450b974b86093c6c027888627b8082f1299dfd5a4bae8e2292821"}, - {file = "charset_normalizer-3.3.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1171ef1fc5ab4693c5d151ae0fdad7f7349920eabbaca6271f95969fa0756c2d"}, - {file = "charset_normalizer-3.3.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28f512b9a33235545fbbdac6a330a510b63be278a50071a336afc1b78781b147"}, - {file = "charset_normalizer-3.3.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0e842112fe3f1a4ffcf64b06dc4c61a88441c2f02f373367f7b4c1aa9be2ad5"}, - {file = "charset_normalizer-3.3.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3f9bc2ce123637a60ebe819f9fccc614da1bcc05798bbbaf2dd4ec91f3e08846"}, - {file = "charset_normalizer-3.3.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:f194cce575e59ffe442c10a360182a986535fd90b57f7debfaa5c845c409ecc3"}, - {file = "charset_normalizer-3.3.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:9a74041ba0bfa9bc9b9bb2cd3238a6ab3b7618e759b41bd15b5f6ad958d17605"}, - {file = "charset_normalizer-3.3.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:b578cbe580e3b41ad17b1c428f382c814b32a6ce90f2d8e39e2e635d49e498d1"}, - {file = "charset_normalizer-3.3.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:6db3cfb9b4fcecb4390db154e75b49578c87a3b9979b40cdf90d7e4b945656e1"}, - {file = "charset_normalizer-3.3.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:debb633f3f7856f95ad957d9b9c781f8e2c6303ef21724ec94bea2ce2fcbd056"}, - {file = "charset_normalizer-3.3.1-cp310-cp310-win32.whl", hash = "sha256:87071618d3d8ec8b186d53cb6e66955ef2a0e4fa63ccd3709c0c90ac5a43520f"}, - {file = "charset_normalizer-3.3.1-cp310-cp310-win_amd64.whl", hash = "sha256:e372d7dfd154009142631de2d316adad3cc1c36c32a38b16a4751ba78da2a397"}, - {file = "charset_normalizer-3.3.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ae4070f741f8d809075ef697877fd350ecf0b7c5837ed68738607ee0a2c572cf"}, - {file = "charset_normalizer-3.3.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:58e875eb7016fd014c0eea46c6fa92b87b62c0cb31b9feae25cbbe62c919f54d"}, - {file = "charset_normalizer-3.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dbd95e300367aa0827496fe75a1766d198d34385a58f97683fe6e07f89ca3e3c"}, - {file = "charset_normalizer-3.3.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:de0b4caa1c8a21394e8ce971997614a17648f94e1cd0640fbd6b4d14cab13a72"}, - {file = "charset_normalizer-3.3.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:985c7965f62f6f32bf432e2681173db41336a9c2611693247069288bcb0c7f8b"}, - {file = "charset_normalizer-3.3.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a15c1fe6d26e83fd2e5972425a772cca158eae58b05d4a25a4e474c221053e2d"}, - {file = "charset_normalizer-3.3.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ae55d592b02c4349525b6ed8f74c692509e5adffa842e582c0f861751701a673"}, - {file = "charset_normalizer-3.3.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:be4d9c2770044a59715eb57c1144dedea7c5d5ae80c68fb9959515037cde2008"}, - {file = "charset_normalizer-3.3.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:851cf693fb3aaef71031237cd68699dded198657ec1e76a76eb8be58c03a5d1f"}, - {file = "charset_normalizer-3.3.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:31bbaba7218904d2eabecf4feec0d07469284e952a27400f23b6628439439fa7"}, - {file = "charset_normalizer-3.3.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:871d045d6ccc181fd863a3cd66ee8e395523ebfbc57f85f91f035f50cee8e3d4"}, - {file = "charset_normalizer-3.3.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:501adc5eb6cd5f40a6f77fbd90e5ab915c8fd6e8c614af2db5561e16c600d6f3"}, - {file = "charset_normalizer-3.3.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f5fb672c396d826ca16a022ac04c9dce74e00a1c344f6ad1a0fdc1ba1f332213"}, - {file = "charset_normalizer-3.3.1-cp311-cp311-win32.whl", hash = "sha256:bb06098d019766ca16fc915ecaa455c1f1cd594204e7f840cd6258237b5079a8"}, - {file = "charset_normalizer-3.3.1-cp311-cp311-win_amd64.whl", hash = "sha256:8af5a8917b8af42295e86b64903156b4f110a30dca5f3b5aedea123fbd638bff"}, - {file = "charset_normalizer-3.3.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:7ae8e5142dcc7a49168f4055255dbcced01dc1714a90a21f87448dc8d90617d1"}, - {file = "charset_normalizer-3.3.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5b70bab78accbc672f50e878a5b73ca692f45f5b5e25c8066d748c09405e6a55"}, - {file = "charset_normalizer-3.3.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5ceca5876032362ae73b83347be8b5dbd2d1faf3358deb38c9c88776779b2e2f"}, - {file = "charset_normalizer-3.3.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:34d95638ff3613849f473afc33f65c401a89f3b9528d0d213c7037c398a51296"}, - {file = "charset_normalizer-3.3.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9edbe6a5bf8b56a4a84533ba2b2f489d0046e755c29616ef8830f9e7d9cf5728"}, - {file = "charset_normalizer-3.3.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f6a02a3c7950cafaadcd46a226ad9e12fc9744652cc69f9e5534f98b47f3bbcf"}, - {file = "charset_normalizer-3.3.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10b8dd31e10f32410751b3430996f9807fc4d1587ca69772e2aa940a82ab571a"}, - {file = "charset_normalizer-3.3.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edc0202099ea1d82844316604e17d2b175044f9bcb6b398aab781eba957224bd"}, - {file = "charset_normalizer-3.3.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b891a2f68e09c5ef989007fac11476ed33c5c9994449a4e2c3386529d703dc8b"}, - {file = "charset_normalizer-3.3.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:71ef3b9be10070360f289aea4838c784f8b851be3ba58cf796262b57775c2f14"}, - {file = "charset_normalizer-3.3.1-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:55602981b2dbf8184c098bc10287e8c245e351cd4fdcad050bd7199d5a8bf514"}, - {file = "charset_normalizer-3.3.1-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:46fb9970aa5eeca547d7aa0de5d4b124a288b42eaefac677bde805013c95725c"}, - {file = "charset_normalizer-3.3.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:520b7a142d2524f999447b3a0cf95115df81c4f33003c51a6ab637cbda9d0bf4"}, - {file = "charset_normalizer-3.3.1-cp312-cp312-win32.whl", hash = "sha256:8ec8ef42c6cd5856a7613dcd1eaf21e5573b2185263d87d27c8edcae33b62a61"}, - {file = "charset_normalizer-3.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:baec8148d6b8bd5cee1ae138ba658c71f5b03e0d69d5907703e3e1df96db5e41"}, - {file = "charset_normalizer-3.3.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:63a6f59e2d01310f754c270e4a257426fe5a591dc487f1983b3bbe793cf6bac6"}, - {file = "charset_normalizer-3.3.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d6bfc32a68bc0933819cfdfe45f9abc3cae3877e1d90aac7259d57e6e0f85b1"}, - {file = "charset_normalizer-3.3.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4f3100d86dcd03c03f7e9c3fdb23d92e32abbca07e7c13ebd7ddfbcb06f5991f"}, - {file = "charset_normalizer-3.3.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:39b70a6f88eebe239fa775190796d55a33cfb6d36b9ffdd37843f7c4c1b5dc67"}, - {file = "charset_normalizer-3.3.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e12f8ee80aa35e746230a2af83e81bd6b52daa92a8afaef4fea4a2ce9b9f4fa"}, - {file = "charset_normalizer-3.3.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7b6cefa579e1237ce198619b76eaa148b71894fb0d6bcf9024460f9bf30fd228"}, - {file = "charset_normalizer-3.3.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:61f1e3fb621f5420523abb71f5771a204b33c21d31e7d9d86881b2cffe92c47c"}, - {file = "charset_normalizer-3.3.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:4f6e2a839f83a6a76854d12dbebde50e4b1afa63e27761549d006fa53e9aa80e"}, - {file = "charset_normalizer-3.3.1-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:1ec937546cad86d0dce5396748bf392bb7b62a9eeb8c66efac60e947697f0e58"}, - {file = "charset_normalizer-3.3.1-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:82ca51ff0fc5b641a2d4e1cc8c5ff108699b7a56d7f3ad6f6da9dbb6f0145b48"}, - {file = "charset_normalizer-3.3.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:633968254f8d421e70f91c6ebe71ed0ab140220469cf87a9857e21c16687c034"}, - {file = "charset_normalizer-3.3.1-cp37-cp37m-win32.whl", hash = "sha256:c0c72d34e7de5604df0fde3644cc079feee5e55464967d10b24b1de268deceb9"}, - {file = "charset_normalizer-3.3.1-cp37-cp37m-win_amd64.whl", hash = "sha256:63accd11149c0f9a99e3bc095bbdb5a464862d77a7e309ad5938fbc8721235ae"}, - {file = "charset_normalizer-3.3.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5a3580a4fdc4ac05f9e53c57f965e3594b2f99796231380adb2baaab96e22761"}, - {file = "charset_normalizer-3.3.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2465aa50c9299d615d757c1c888bc6fef384b7c4aec81c05a0172b4400f98557"}, - {file = "charset_normalizer-3.3.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cb7cd68814308aade9d0c93c5bd2ade9f9441666f8ba5aa9c2d4b389cb5e2a45"}, - {file = "charset_normalizer-3.3.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:91e43805ccafa0a91831f9cd5443aa34528c0c3f2cc48c4cb3d9a7721053874b"}, - {file = "charset_normalizer-3.3.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:854cc74367180beb327ab9d00f964f6d91da06450b0855cbbb09187bcdb02de5"}, - {file = "charset_normalizer-3.3.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c15070ebf11b8b7fd1bfff7217e9324963c82dbdf6182ff7050519e350e7ad9f"}, - {file = "charset_normalizer-3.3.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c4c99f98fc3a1835af8179dcc9013f93594d0670e2fa80c83aa36346ee763d2"}, - {file = "charset_normalizer-3.3.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3fb765362688821404ad6cf86772fc54993ec11577cd5a92ac44b4c2ba52155b"}, - {file = "charset_normalizer-3.3.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:dced27917823df984fe0c80a5c4ad75cf58df0fbfae890bc08004cd3888922a2"}, - {file = "charset_normalizer-3.3.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a66bcdf19c1a523e41b8e9d53d0cedbfbac2e93c649a2e9502cb26c014d0980c"}, - {file = "charset_normalizer-3.3.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:ecd26be9f112c4f96718290c10f4caea6cc798459a3a76636b817a0ed7874e42"}, - {file = "charset_normalizer-3.3.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:3f70fd716855cd3b855316b226a1ac8bdb3caf4f7ea96edcccc6f484217c9597"}, - {file = "charset_normalizer-3.3.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:17a866d61259c7de1bdadef418a37755050ddb4b922df8b356503234fff7932c"}, - {file = "charset_normalizer-3.3.1-cp38-cp38-win32.whl", hash = "sha256:548eefad783ed787b38cb6f9a574bd8664468cc76d1538215d510a3cd41406cb"}, - {file = "charset_normalizer-3.3.1-cp38-cp38-win_amd64.whl", hash = "sha256:45f053a0ece92c734d874861ffe6e3cc92150e32136dd59ab1fb070575189c97"}, - {file = "charset_normalizer-3.3.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:bc791ec3fd0c4309a753f95bb6c749ef0d8ea3aea91f07ee1cf06b7b02118f2f"}, - {file = "charset_normalizer-3.3.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0c8c61fb505c7dad1d251c284e712d4e0372cef3b067f7ddf82a7fa82e1e9a93"}, - {file = "charset_normalizer-3.3.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2c092be3885a1b7899cd85ce24acedc1034199d6fca1483fa2c3a35c86e43041"}, - {file = "charset_normalizer-3.3.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c2000c54c395d9e5e44c99dc7c20a64dc371f777faf8bae4919ad3e99ce5253e"}, - {file = "charset_normalizer-3.3.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4cb50a0335382aac15c31b61d8531bc9bb657cfd848b1d7158009472189f3d62"}, - {file = "charset_normalizer-3.3.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c30187840d36d0ba2893bc3271a36a517a717f9fd383a98e2697ee890a37c273"}, - {file = "charset_normalizer-3.3.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe81b35c33772e56f4b6cf62cf4aedc1762ef7162a31e6ac7fe5e40d0149eb67"}, - {file = "charset_normalizer-3.3.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d0bf89afcbcf4d1bb2652f6580e5e55a840fdf87384f6063c4a4f0c95e378656"}, - {file = "charset_normalizer-3.3.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:06cf46bdff72f58645434d467bf5228080801298fbba19fe268a01b4534467f5"}, - {file = "charset_normalizer-3.3.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:3c66df3f41abee950d6638adc7eac4730a306b022570f71dd0bd6ba53503ab57"}, - {file = "charset_normalizer-3.3.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:cd805513198304026bd379d1d516afbf6c3c13f4382134a2c526b8b854da1c2e"}, - {file = "charset_normalizer-3.3.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:9505dc359edb6a330efcd2be825fdb73ee3e628d9010597aa1aee5aa63442e97"}, - {file = "charset_normalizer-3.3.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:31445f38053476a0c4e6d12b047b08ced81e2c7c712e5a1ad97bc913256f91b2"}, - {file = "charset_normalizer-3.3.1-cp39-cp39-win32.whl", hash = "sha256:bd28b31730f0e982ace8663d108e01199098432a30a4c410d06fe08fdb9e93f4"}, - {file = "charset_normalizer-3.3.1-cp39-cp39-win_amd64.whl", hash = "sha256:555fe186da0068d3354cdf4bbcbc609b0ecae4d04c921cc13e209eece7720727"}, - {file = "charset_normalizer-3.3.1-py3-none-any.whl", hash = "sha256:800561453acdecedaac137bf09cd719c7a440b6800ec182f077bb8e7025fb708"}, -] - -[[package]] -name = "colorama" -version = "0.4.6" -description = "Cross-platform colored terminal text." -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -files = [ - {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, - {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, -] - -[[package]] -name = "contourpy" -version = "1.1.1" -description = "Python library for calculating contours of 2D quadrilateral grids" -optional = false -python-versions = ">=3.8" -files = [ - {file = "contourpy-1.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:46e24f5412c948d81736509377e255f6040e94216bf1a9b5ea1eaa9d29f6ec1b"}, - {file = "contourpy-1.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0e48694d6a9c5a26ee85b10130c77a011a4fedf50a7279fa0bdaf44bafb4299d"}, - {file = "contourpy-1.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a66045af6cf00e19d02191ab578a50cb93b2028c3eefed999793698e9ea768ae"}, - {file = "contourpy-1.1.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4ebf42695f75ee1a952f98ce9775c873e4971732a87334b099dde90b6af6a916"}, - {file = "contourpy-1.1.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f6aec19457617ef468ff091669cca01fa7ea557b12b59a7908b9474bb9674cf0"}, - {file = "contourpy-1.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:462c59914dc6d81e0b11f37e560b8a7c2dbab6aca4f38be31519d442d6cde1a1"}, - {file = "contourpy-1.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6d0a8efc258659edc5299f9ef32d8d81de8b53b45d67bf4bfa3067f31366764d"}, - {file = "contourpy-1.1.1-cp310-cp310-win32.whl", hash = "sha256:d6ab42f223e58b7dac1bb0af32194a7b9311065583cc75ff59dcf301afd8a431"}, - {file = "contourpy-1.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:549174b0713d49871c6dee90a4b499d3f12f5e5f69641cd23c50a4542e2ca1eb"}, - {file = "contourpy-1.1.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:407d864db716a067cc696d61fa1ef6637fedf03606e8417fe2aeed20a061e6b2"}, - {file = "contourpy-1.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dfe80c017973e6a4c367e037cb31601044dd55e6bfacd57370674867d15a899b"}, - {file = "contourpy-1.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e30aaf2b8a2bac57eb7e1650df1b3a4130e8d0c66fc2f861039d507a11760e1b"}, - {file = "contourpy-1.1.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3de23ca4f381c3770dee6d10ead6fff524d540c0f662e763ad1530bde5112532"}, - {file = "contourpy-1.1.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:566f0e41df06dfef2431defcfaa155f0acfa1ca4acbf8fd80895b1e7e2ada40e"}, - {file = "contourpy-1.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b04c2f0adaf255bf756cf08ebef1be132d3c7a06fe6f9877d55640c5e60c72c5"}, - {file = "contourpy-1.1.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d0c188ae66b772d9d61d43c6030500344c13e3f73a00d1dc241da896f379bb62"}, - {file = "contourpy-1.1.1-cp311-cp311-win32.whl", hash = "sha256:0683e1ae20dc038075d92e0e0148f09ffcefab120e57f6b4c9c0f477ec171f33"}, - {file = "contourpy-1.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:8636cd2fc5da0fb102a2504fa2c4bea3cbc149533b345d72cdf0e7a924decc45"}, - {file = "contourpy-1.1.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:560f1d68a33e89c62da5da4077ba98137a5e4d3a271b29f2f195d0fba2adcb6a"}, - {file = "contourpy-1.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24216552104ae8f3b34120ef84825400b16eb6133af2e27a190fdc13529f023e"}, - {file = "contourpy-1.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56de98a2fb23025882a18b60c7f0ea2d2d70bbbcfcf878f9067234b1c4818442"}, - {file = "contourpy-1.1.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:07d6f11dfaf80a84c97f1a5ba50d129d9303c5b4206f776e94037332e298dda8"}, - {file = "contourpy-1.1.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1eaac5257a8f8a047248d60e8f9315c6cff58f7803971170d952555ef6344a7"}, - {file = "contourpy-1.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:19557fa407e70f20bfaba7d55b4d97b14f9480856c4fb65812e8a05fe1c6f9bf"}, - {file = "contourpy-1.1.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:081f3c0880712e40effc5f4c3b08feca6d064cb8cfbb372ca548105b86fd6c3d"}, - {file = "contourpy-1.1.1-cp312-cp312-win32.whl", hash = "sha256:059c3d2a94b930f4dafe8105bcdc1b21de99b30b51b5bce74c753686de858cb6"}, - {file = "contourpy-1.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:f44d78b61740e4e8c71db1cf1fd56d9050a4747681c59ec1094750a658ceb970"}, - {file = "contourpy-1.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:70e5a10f8093d228bb2b552beeb318b8928b8a94763ef03b858ef3612b29395d"}, - {file = "contourpy-1.1.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8394e652925a18ef0091115e3cc191fef350ab6dc3cc417f06da66bf98071ae9"}, - {file = "contourpy-1.1.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5bd5680f844c3ff0008523a71949a3ff5e4953eb7701b28760805bc9bcff217"}, - {file = "contourpy-1.1.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:66544f853bfa85c0d07a68f6c648b2ec81dafd30f272565c37ab47a33b220684"}, - {file = "contourpy-1.1.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e0c02b75acfea5cab07585d25069207e478d12309557f90a61b5a3b4f77f46ce"}, - {file = "contourpy-1.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41339b24471c58dc1499e56783fedc1afa4bb018bcd035cfb0ee2ad2a7501ef8"}, - {file = "contourpy-1.1.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f29fb0b3f1217dfe9362ec55440d0743fe868497359f2cf93293f4b2701b8251"}, - {file = "contourpy-1.1.1-cp38-cp38-win32.whl", hash = "sha256:f9dc7f933975367251c1b34da882c4f0e0b2e24bb35dc906d2f598a40b72bfc7"}, - {file = "contourpy-1.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:498e53573e8b94b1caeb9e62d7c2d053c263ebb6aa259c81050766beb50ff8d9"}, - {file = "contourpy-1.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ba42e3810999a0ddd0439e6e5dbf6d034055cdc72b7c5c839f37a7c274cb4eba"}, - {file = "contourpy-1.1.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6c06e4c6e234fcc65435223c7b2a90f286b7f1b2733058bdf1345d218cc59e34"}, - {file = "contourpy-1.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca6fab080484e419528e98624fb5c4282148b847e3602dc8dbe0cb0669469887"}, - {file = "contourpy-1.1.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:93df44ab351119d14cd1e6b52a5063d3336f0754b72736cc63db59307dabb718"}, - {file = "contourpy-1.1.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eafbef886566dc1047d7b3d4b14db0d5b7deb99638d8e1be4e23a7c7ac59ff0f"}, - {file = "contourpy-1.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efe0fab26d598e1ec07d72cf03eaeeba8e42b4ecf6b9ccb5a356fde60ff08b85"}, - {file = "contourpy-1.1.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:f08e469821a5e4751c97fcd34bcb586bc243c39c2e39321822060ba902eac49e"}, - {file = "contourpy-1.1.1-cp39-cp39-win32.whl", hash = "sha256:bfc8a5e9238232a45ebc5cb3bfee71f1167064c8d382cadd6076f0d51cff1da0"}, - {file = "contourpy-1.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:c84fdf3da00c2827d634de4fcf17e3e067490c4aea82833625c4c8e6cdea0887"}, - {file = "contourpy-1.1.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:229a25f68046c5cf8067d6d6351c8b99e40da11b04d8416bf8d2b1d75922521e"}, - {file = "contourpy-1.1.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a10dab5ea1bd4401c9483450b5b0ba5416be799bbd50fc7a6cc5e2a15e03e8a3"}, - {file = "contourpy-1.1.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:4f9147051cb8fdb29a51dc2482d792b3b23e50f8f57e3720ca2e3d438b7adf23"}, - {file = "contourpy-1.1.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a75cc163a5f4531a256f2c523bd80db509a49fc23721b36dd1ef2f60ff41c3cb"}, - {file = "contourpy-1.1.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b53d5769aa1f2d4ea407c65f2d1d08002952fac1d9e9d307aa2e1023554a163"}, - {file = "contourpy-1.1.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:11b836b7dbfb74e049c302bbf74b4b8f6cb9d0b6ca1bf86cfa8ba144aedadd9c"}, - {file = "contourpy-1.1.1.tar.gz", hash = "sha256:96ba37c2e24b7212a77da85004c38e7c4d155d3e72a45eeaf22c1f03f607e8ab"}, -] - -[package.dependencies] -numpy = [ - {version = ">=1.16,<2.0", markers = "python_version <= \"3.11\""}, - {version = ">=1.26.0rc1,<2.0", markers = "python_version >= \"3.12\""}, -] - -[package.extras] -bokeh = ["bokeh", "selenium"] -docs = ["furo", "sphinx (>=7.2)", "sphinx-copybutton"] -mypy = ["contourpy[bokeh,docs]", "docutils-stubs", "mypy (==1.4.1)", "types-Pillow"] -test = ["Pillow", "contourpy[test-no-images]", "matplotlib"] -test-no-images = ["pytest", "pytest-cov", "wurlitzer"] - -[[package]] -name = "cycler" -version = "0.12.1" -description = "Composable style cycles" -optional = false -python-versions = ">=3.8" -files = [ - {file = "cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30"}, - {file = "cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c"}, -] - -[package.extras] -docs = ["ipython", "matplotlib", "numpydoc", "sphinx"] -tests = ["pytest", "pytest-cov", "pytest-xdist"] - -[[package]] -name = "exceptiongroup" -version = "1.1.3" -description = "Backport of PEP 654 (exception groups)" -optional = false -python-versions = ">=3.7" -files = [ - {file = "exceptiongroup-1.1.3-py3-none-any.whl", hash = "sha256:343280667a4585d195ca1cf9cef84a4e178c4b6cf2274caef9859782b567d5e3"}, - {file = "exceptiongroup-1.1.3.tar.gz", hash = "sha256:097acd85d473d75af5bb98e41b61ff7fe35efe6675e4f9370ec6ec5126d160e9"}, -] - -[package.extras] -test = ["pytest (>=6)"] - -[[package]] -name = "filelock" -version = "3.12.4" -description = "A platform independent file lock." -optional = false -python-versions = ">=3.8" -files = [ - {file = "filelock-3.12.4-py3-none-any.whl", hash = "sha256:08c21d87ded6e2b9da6728c3dff51baf1dcecf973b768ef35bcbc3447edb9ad4"}, - {file = "filelock-3.12.4.tar.gz", hash = "sha256:2e6f249f1f3654291606e046b09f1fd5eac39b360664c27f5aad072012f8bcbd"}, -] - -[package.extras] -docs = ["furo (>=2023.7.26)", "sphinx (>=7.1.2)", "sphinx-autodoc-typehints (>=1.24)"] -testing = ["covdefaults (>=2.3)", "coverage (>=7.3)", "diff-cover (>=7.7)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)", "pytest-timeout (>=2.1)"] -typing = ["typing-extensions (>=4.7.1)"] - -[[package]] -name = "filterpy" -version = "1.4.5" -description = "Kalman filtering and optimal estimation library" -optional = false -python-versions = "*" -files = [ - {file = "filterpy-1.4.5.zip", hash = "sha256:4f2a4d39e4ea601b9ab42b2db08b5918a9538c168cff1c6895ae26646f3d73b1"}, -] - -[package.dependencies] -matplotlib = "*" -numpy = "*" -scipy = "*" - -[[package]] -name = "fonttools" -version = "4.43.1" -description = "Tools to manipulate font files" -optional = false -python-versions = ">=3.8" -files = [ - {file = "fonttools-4.43.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:bf11e2cca121df35e295bd34b309046c29476ee739753bc6bc9d5050de319273"}, - {file = "fonttools-4.43.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:10b3922875ffcba636674f406f9ab9a559564fdbaa253d66222019d569db869c"}, - {file = "fonttools-4.43.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f727c3e3d08fd25352ed76cc3cb61486f8ed3f46109edf39e5a60fc9fecf6ca"}, - {file = "fonttools-4.43.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad0b3f6342cfa14be996971ea2b28b125ad681c6277c4cd0fbdb50340220dfb6"}, - {file = "fonttools-4.43.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3b7ad05b2beeebafb86aa01982e9768d61c2232f16470f9d0d8e385798e37184"}, - {file = "fonttools-4.43.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4c54466f642d2116686268c3e5f35ebb10e49b0d48d41a847f0e171c785f7ac7"}, - {file = "fonttools-4.43.1-cp310-cp310-win32.whl", hash = "sha256:1e09da7e8519e336239fbd375156488a4c4945f11c4c5792ee086dd84f784d02"}, - {file = "fonttools-4.43.1-cp310-cp310-win_amd64.whl", hash = "sha256:1cf9e974f63b1080b1d2686180fc1fbfd3bfcfa3e1128695b5de337eb9075cef"}, - {file = "fonttools-4.43.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5db46659cfe4e321158de74c6f71617e65dc92e54980086823a207f1c1c0e24b"}, - {file = "fonttools-4.43.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1952c89a45caceedf2ab2506d9a95756e12b235c7182a7a0fff4f5e52227204f"}, - {file = "fonttools-4.43.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c36da88422e0270fbc7fd959dc9749d31a958506c1d000e16703c2fce43e3d0"}, - {file = "fonttools-4.43.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7bbbf8174501285049e64d174e29f9578495e1b3b16c07c31910d55ad57683d8"}, - {file = "fonttools-4.43.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d4071bd1c183b8d0b368cc9ed3c07a0f6eb1bdfc4941c4c024c49a35429ac7cd"}, - {file = "fonttools-4.43.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d21099b411e2006d3c3e1f9aaf339e12037dbf7bf9337faf0e93ec915991f43b"}, - {file = "fonttools-4.43.1-cp311-cp311-win32.whl", hash = "sha256:b84a1c00f832feb9d0585ca8432fba104c819e42ff685fcce83537e2e7e91204"}, - {file = "fonttools-4.43.1-cp311-cp311-win_amd64.whl", hash = "sha256:9a2f0aa6ca7c9bc1058a9d0b35483d4216e0c1bbe3962bc62ce112749954c7b8"}, - {file = "fonttools-4.43.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:4d9740e3783c748521e77d3c397dc0662062c88fd93600a3c2087d3d627cd5e5"}, - {file = "fonttools-4.43.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:884ef38a5a2fd47b0c1291647b15f4e88b9de5338ffa24ee52c77d52b4dfd09c"}, - {file = "fonttools-4.43.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9648518ef687ba818db3fcc5d9aae27a369253ac09a81ed25c3867e8657a0680"}, - {file = "fonttools-4.43.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95e974d70238fc2be5f444fa91f6347191d0e914d5d8ae002c9aa189572cc215"}, - {file = "fonttools-4.43.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:34f713dad41aa21c637b4e04fe507c36b986a40f7179dcc86402237e2d39dcd3"}, - {file = "fonttools-4.43.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:360201d46165fc0753229afe785900bc9596ee6974833124f4e5e9f98d0f592b"}, - {file = "fonttools-4.43.1-cp312-cp312-win32.whl", hash = "sha256:bb6d2f8ef81ea076877d76acfb6f9534a9c5f31dc94ba70ad001267ac3a8e56f"}, - {file = "fonttools-4.43.1-cp312-cp312-win_amd64.whl", hash = "sha256:25d3da8a01442cbc1106490eddb6d31d7dffb38c1edbfabbcc8db371b3386d72"}, - {file = "fonttools-4.43.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:8da417431bfc9885a505e86ba706f03f598c85f5a9c54f67d63e84b9948ce590"}, - {file = "fonttools-4.43.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:51669b60ee2a4ad6c7fc17539a43ffffc8ef69fd5dbed186a38a79c0ac1f5db7"}, - {file = "fonttools-4.43.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:748015d6f28f704e7d95cd3c808b483c5fb87fd3eefe172a9da54746ad56bfb6"}, - {file = "fonttools-4.43.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f7a58eb5e736d7cf198eee94844b81c9573102ae5989ebcaa1d1a37acd04b33d"}, - {file = "fonttools-4.43.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6bb5ea9076e0e39defa2c325fc086593ae582088e91c0746bee7a5a197be3da0"}, - {file = "fonttools-4.43.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5f37e31291bf99a63328668bb83b0669f2688f329c4c0d80643acee6e63cd933"}, - {file = "fonttools-4.43.1-cp38-cp38-win32.whl", hash = "sha256:9c60ecfa62839f7184f741d0509b5c039d391c3aff71dc5bc57b87cc305cff3b"}, - {file = "fonttools-4.43.1-cp38-cp38-win_amd64.whl", hash = "sha256:fe9b1ec799b6086460a7480e0f55c447b1aca0a4eecc53e444f639e967348896"}, - {file = "fonttools-4.43.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:13a9a185259ed144def3682f74fdcf6596f2294e56fe62dfd2be736674500dba"}, - {file = "fonttools-4.43.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b2adca1b46d69dce4a37eecc096fe01a65d81a2f5c13b25ad54d5430ae430b13"}, - {file = "fonttools-4.43.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18eefac1b247049a3a44bcd6e8c8fd8b97f3cad6f728173b5d81dced12d6c477"}, - {file = "fonttools-4.43.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2062542a7565091cea4cc14dd99feff473268b5b8afdee564f7067dd9fff5860"}, - {file = "fonttools-4.43.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:18a2477c62a728f4d6e88c45ee9ee0229405e7267d7d79ce1f5ce0f3e9f8ab86"}, - {file = "fonttools-4.43.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a7a06f8d95b7496e53af80d974d63516ffb263a468e614978f3899a6df52d4b3"}, - {file = "fonttools-4.43.1-cp39-cp39-win32.whl", hash = "sha256:10003ebd81fec0192c889e63a9c8c63f88c7d72ae0460b7ba0cd2a1db246e5ad"}, - {file = "fonttools-4.43.1-cp39-cp39-win_amd64.whl", hash = "sha256:e117a92b07407a061cde48158c03587ab97e74e7d73cb65e6aadb17af191162a"}, - {file = "fonttools-4.43.1-py3-none-any.whl", hash = "sha256:4f88cae635bfe4bbbdc29d479a297bb525a94889184bb69fa9560c2d4834ddb9"}, - {file = "fonttools-4.43.1.tar.gz", hash = "sha256:17dbc2eeafb38d5d0e865dcce16e313c58265a6d2d20081c435f84dc5a9d8212"}, -] - -[package.extras] -all = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "fs (>=2.2.0,<3)", "lxml (>=4.0,<5)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres", "scipy", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.23.0)", "unicodedata2 (>=15.0.0)", "xattr", "zopfli (>=0.1.4)"] -graphite = ["lz4 (>=1.7.4.2)"] -interpolatable = ["munkres", "scipy"] -lxml = ["lxml (>=4.0,<5)"] -pathops = ["skia-pathops (>=0.5.0)"] -plot = ["matplotlib"] -repacker = ["uharfbuzz (>=0.23.0)"] -symfont = ["sympy"] -type1 = ["xattr"] -ufo = ["fs (>=2.2.0,<3)"] -unicode = ["unicodedata2 (>=15.0.0)"] -woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] - -[[package]] -name = "fsspec" -version = "2023.10.0" -description = "File-system specification" -optional = false -python-versions = ">=3.8" -files = [ - {file = "fsspec-2023.10.0-py3-none-any.whl", hash = "sha256:346a8f024efeb749d2a5fca7ba8854474b1ff9af7c3faaf636a4548781136529"}, - {file = "fsspec-2023.10.0.tar.gz", hash = "sha256:330c66757591df346ad3091a53bd907e15348c2ba17d63fd54f5c39c4457d2a5"}, -] - -[package.extras] -abfs = ["adlfs"] -adl = ["adlfs"] -arrow = ["pyarrow (>=1)"] -dask = ["dask", "distributed"] -devel = ["pytest", "pytest-cov"] -dropbox = ["dropbox", "dropboxdrivefs", "requests"] -full = ["adlfs", "aiohttp (!=4.0.0a0,!=4.0.0a1)", "dask", "distributed", "dropbox", "dropboxdrivefs", "fusepy", "gcsfs", "libarchive-c", "ocifs", "panel", "paramiko", "pyarrow (>=1)", "pygit2", "requests", "s3fs", "smbprotocol", "tqdm"] -fuse = ["fusepy"] -gcs = ["gcsfs"] -git = ["pygit2"] -github = ["requests"] -gs = ["gcsfs"] -gui = ["panel"] -hdfs = ["pyarrow (>=1)"] -http = ["aiohttp (!=4.0.0a0,!=4.0.0a1)", "requests"] -libarchive = ["libarchive-c"] -oci = ["ocifs"] -s3 = ["s3fs"] -sftp = ["paramiko"] -smb = ["smbprotocol"] -ssh = ["paramiko"] -tqdm = ["tqdm"] - -[[package]] -name = "healpy" -version = "1.16.6" -description = "Healpix tools package for Python" -optional = false -python-versions = ">=3.9" -files = [ - {file = "healpy-1.16.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1cad7ed1d7030eeb06081240f669c9107db1282678512c85f5cf6eef1bea01bb"}, - {file = "healpy-1.16.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6be3ca85cb78f3f243f660f3105d362615843f32c1ff53ffdead5ea1ffe07eb6"}, - {file = "healpy-1.16.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af4469864f465fc4bc3752543812ab1161d84eff4a8aead3842d56ea1b2585bb"}, - {file = "healpy-1.16.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:366a269b239eeabf924d4a069cce5f2f1d72c7af24132d59f95fec09f670a38a"}, - {file = "healpy-1.16.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3324fc5aa737188db8017819d4ecb18c11315873481f31d97aceb29958591f40"}, - {file = "healpy-1.16.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd5adc827a90dffa72158b8a576143459d06dbd3afc52c2ff5c4a566aafcb049"}, - {file = "healpy-1.16.6-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:12b5c5ea0c767b7ae7659b18bd4c42b11384765b44b9205b27147ab4686657bf"}, - {file = "healpy-1.16.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f72338a29fc776a4031cb2e9b7bd9306cbe2f0b6355e9541716b38ad23ba880d"}, - {file = "healpy-1.16.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d13dd979e804d2d7e80f5121b0acf46f94dcddfac757ebb01cecbcb3304b285"}, - {file = "healpy-1.16.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0a0e0b725c9fa2777f184c70beed87ff7c8dfa1869aca1fc370b40057db5c739"}, - {file = "healpy-1.16.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7e5a284e7ec4cc06b7b222098ab0961a3b31f72014f0194b3cfd62e4dcd2963e"}, - {file = "healpy-1.16.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:754fed0f2313f805535ea44e37a538b8d7b58b377cdfe8f36accdf8fec417f4a"}, - {file = "healpy-1.16.6.tar.gz", hash = "sha256:0ab26e828fcd251a141095af6d9bf3dba43cec6f0f5cd48b65bf0af8f56329f1"}, -] - -[package.dependencies] -astropy = "*" -matplotlib = "*" -numpy = ">=1.19" -scipy = "*" - -[package.extras] -test = ["pytest", "pytest-cython", "pytest-doctestplus", "requests"] - -[[package]] -name = "idna" -version = "3.4" -description = "Internationalized Domain Names in Applications (IDNA)" -optional = false -python-versions = ">=3.5" -files = [ - {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, - {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, -] - -[[package]] -name = "iniconfig" -version = "2.0.0" -description = "brain-dead simple config-ini parsing" -optional = false -python-versions = ">=3.7" -files = [ - {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, - {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, -] - -[[package]] -name = "jinja2" -version = "3.1.2" -description = "A very fast and expressive template engine." -optional = false -python-versions = ">=3.7" -files = [ - {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, - {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, -] - -[package.dependencies] -MarkupSafe = ">=2.0" - -[package.extras] -i18n = ["Babel (>=2.7)"] - -[[package]] -name = "kiwisolver" -version = "1.4.5" -description = "A fast implementation of the Cassowary constraint solver" -optional = false -python-versions = ">=3.7" -files = [ - {file = "kiwisolver-1.4.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:05703cf211d585109fcd72207a31bb170a0f22144d68298dc5e61b3c946518af"}, - {file = "kiwisolver-1.4.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:146d14bebb7f1dc4d5fbf74f8a6cb15ac42baadee8912eb84ac0b3b2a3dc6ac3"}, - {file = "kiwisolver-1.4.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6ef7afcd2d281494c0a9101d5c571970708ad911d028137cd558f02b851c08b4"}, - {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9eaa8b117dc8337728e834b9c6e2611f10c79e38f65157c4c38e9400286f5cb1"}, - {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ec20916e7b4cbfb1f12380e46486ec4bcbaa91a9c448b97023fde0d5bbf9e4ff"}, - {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39b42c68602539407884cf70d6a480a469b93b81b7701378ba5e2328660c847a"}, - {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa12042de0171fad672b6c59df69106d20d5596e4f87b5e8f76df757a7c399aa"}, - {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2a40773c71d7ccdd3798f6489aaac9eee213d566850a9533f8d26332d626b82c"}, - {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:19df6e621f6d8b4b9c4d45f40a66839294ff2bb235e64d2178f7522d9170ac5b"}, - {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:83d78376d0d4fd884e2c114d0621624b73d2aba4e2788182d286309ebdeed770"}, - {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e391b1f0a8a5a10ab3b9bb6afcfd74f2175f24f8975fb87ecae700d1503cdee0"}, - {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:852542f9481f4a62dbb5dd99e8ab7aedfeb8fb6342349a181d4036877410f525"}, - {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59edc41b24031bc25108e210c0def6f6c2191210492a972d585a06ff246bb79b"}, - {file = "kiwisolver-1.4.5-cp310-cp310-win32.whl", hash = "sha256:a6aa6315319a052b4ee378aa171959c898a6183f15c1e541821c5c59beaa0238"}, - {file = "kiwisolver-1.4.5-cp310-cp310-win_amd64.whl", hash = "sha256:d0ef46024e6a3d79c01ff13801cb19d0cad7fd859b15037aec74315540acc276"}, - {file = "kiwisolver-1.4.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:11863aa14a51fd6ec28688d76f1735f8f69ab1fabf388851a595d0721af042f5"}, - {file = "kiwisolver-1.4.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8ab3919a9997ab7ef2fbbed0cc99bb28d3c13e6d4b1ad36e97e482558a91be90"}, - {file = "kiwisolver-1.4.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fcc700eadbbccbf6bc1bcb9dbe0786b4b1cb91ca0dcda336eef5c2beed37b797"}, - {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dfdd7c0b105af050eb3d64997809dc21da247cf44e63dc73ff0fd20b96be55a9"}, - {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76c6a5964640638cdeaa0c359382e5703e9293030fe730018ca06bc2010c4437"}, - {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bbea0db94288e29afcc4c28afbf3a7ccaf2d7e027489c449cf7e8f83c6346eb9"}, - {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ceec1a6bc6cab1d6ff5d06592a91a692f90ec7505d6463a88a52cc0eb58545da"}, - {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:040c1aebeda72197ef477a906782b5ab0d387642e93bda547336b8957c61022e"}, - {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f91de7223d4c7b793867797bacd1ee53bfe7359bd70d27b7b58a04efbb9436c8"}, - {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:faae4860798c31530dd184046a900e652c95513796ef51a12bc086710c2eec4d"}, - {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:b0157420efcb803e71d1b28e2c287518b8808b7cf1ab8af36718fd0a2c453eb0"}, - {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:06f54715b7737c2fecdbf140d1afb11a33d59508a47bf11bb38ecf21dc9ab79f"}, - {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fdb7adb641a0d13bdcd4ef48e062363d8a9ad4a182ac7647ec88f695e719ae9f"}, - {file = "kiwisolver-1.4.5-cp311-cp311-win32.whl", hash = "sha256:bb86433b1cfe686da83ce32a9d3a8dd308e85c76b60896d58f082136f10bffac"}, - {file = "kiwisolver-1.4.5-cp311-cp311-win_amd64.whl", hash = "sha256:6c08e1312a9cf1074d17b17728d3dfce2a5125b2d791527f33ffbe805200a355"}, - {file = "kiwisolver-1.4.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:32d5cf40c4f7c7b3ca500f8985eb3fb3a7dfc023215e876f207956b5ea26632a"}, - {file = "kiwisolver-1.4.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f846c260f483d1fd217fe5ed7c173fb109efa6b1fc8381c8b7552c5781756192"}, - {file = "kiwisolver-1.4.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5ff5cf3571589b6d13bfbfd6bcd7a3f659e42f96b5fd1c4830c4cf21d4f5ef45"}, - {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7269d9e5f1084a653d575c7ec012ff57f0c042258bf5db0954bf551c158466e7"}, - {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da802a19d6e15dffe4b0c24b38b3af68e6c1a68e6e1d8f30148c83864f3881db"}, - {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3aba7311af82e335dd1e36ffff68aaca609ca6290c2cb6d821a39aa075d8e3ff"}, - {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:763773d53f07244148ccac5b084da5adb90bfaee39c197554f01b286cf869228"}, - {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2270953c0d8cdab5d422bee7d2007f043473f9d2999631c86a223c9db56cbd16"}, - {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d099e745a512f7e3bbe7249ca835f4d357c586d78d79ae8f1dcd4d8adeb9bda9"}, - {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:74db36e14a7d1ce0986fa104f7d5637aea5c82ca6326ed0ec5694280942d1162"}, - {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:7e5bab140c309cb3a6ce373a9e71eb7e4873c70c2dda01df6820474f9889d6d4"}, - {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:0f114aa76dc1b8f636d077979c0ac22e7cd8f3493abbab152f20eb8d3cda71f3"}, - {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:88a2df29d4724b9237fc0c6eaf2a1adae0cdc0b3e9f4d8e7dc54b16812d2d81a"}, - {file = "kiwisolver-1.4.5-cp312-cp312-win32.whl", hash = "sha256:72d40b33e834371fd330fb1472ca19d9b8327acb79a5821d4008391db8e29f20"}, - {file = "kiwisolver-1.4.5-cp312-cp312-win_amd64.whl", hash = "sha256:2c5674c4e74d939b9d91dda0fae10597ac7521768fec9e399c70a1f27e2ea2d9"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3a2b053a0ab7a3960c98725cfb0bf5b48ba82f64ec95fe06f1d06c99b552e130"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cd32d6c13807e5c66a7cbb79f90b553642f296ae4518a60d8d76243b0ad2898"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59ec7b7c7e1a61061850d53aaf8e93db63dce0c936db1fda2658b70e4a1be709"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:da4cfb373035def307905d05041c1d06d8936452fe89d464743ae7fb8371078b"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2400873bccc260b6ae184b2b8a4fec0e4082d30648eadb7c3d9a13405d861e89"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1b04139c4236a0f3aff534479b58f6f849a8b351e1314826c2d230849ed48985"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:4e66e81a5779b65ac21764c295087de82235597a2293d18d943f8e9e32746265"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:7931d8f1f67c4be9ba1dd9c451fb0eeca1a25b89e4d3f89e828fe12a519b782a"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:b3f7e75f3015df442238cca659f8baa5f42ce2a8582727981cbfa15fee0ee205"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:bbf1d63eef84b2e8c89011b7f2235b1e0bf7dacc11cac9431fc6468e99ac77fb"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:4c380469bd3f970ef677bf2bcba2b6b0b4d5c75e7a020fb863ef75084efad66f"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-win32.whl", hash = "sha256:9408acf3270c4b6baad483865191e3e582b638b1654a007c62e3efe96f09a9a3"}, - {file = "kiwisolver-1.4.5-cp37-cp37m-win_amd64.whl", hash = "sha256:5b94529f9b2591b7af5f3e0e730a4e0a41ea174af35a4fd067775f9bdfeee01a"}, - {file = "kiwisolver-1.4.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:11c7de8f692fc99816e8ac50d1d1aef4f75126eefc33ac79aac02c099fd3db71"}, - {file = "kiwisolver-1.4.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:53abb58632235cd154176ced1ae8f0d29a6657aa1aa9decf50b899b755bc2b93"}, - {file = "kiwisolver-1.4.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:88b9f257ca61b838b6f8094a62418421f87ac2a1069f7e896c36a7d86b5d4c29"}, - {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3195782b26fc03aa9c6913d5bad5aeb864bdc372924c093b0f1cebad603dd712"}, - {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fc579bf0f502e54926519451b920e875f433aceb4624a3646b3252b5caa9e0b6"}, - {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a580c91d686376f0f7c295357595c5a026e6cbc3d77b7c36e290201e7c11ecb"}, - {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cfe6ab8da05c01ba6fbea630377b5da2cd9bcbc6338510116b01c1bc939a2c18"}, - {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:d2e5a98f0ec99beb3c10e13b387f8db39106d53993f498b295f0c914328b1333"}, - {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a51a263952b1429e429ff236d2f5a21c5125437861baeed77f5e1cc2d2c7c6da"}, - {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:3edd2fa14e68c9be82c5b16689e8d63d89fe927e56debd6e1dbce7a26a17f81b"}, - {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:74d1b44c6cfc897df648cc9fdaa09bc3e7679926e6f96df05775d4fb3946571c"}, - {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:76d9289ed3f7501012e05abb8358bbb129149dbd173f1f57a1bf1c22d19ab7cc"}, - {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:92dea1ffe3714fa8eb6a314d2b3c773208d865a0e0d35e713ec54eea08a66250"}, - {file = "kiwisolver-1.4.5-cp38-cp38-win32.whl", hash = "sha256:5c90ae8c8d32e472be041e76f9d2f2dbff4d0b0be8bd4041770eddb18cf49a4e"}, - {file = "kiwisolver-1.4.5-cp38-cp38-win_amd64.whl", hash = "sha256:c7940c1dc63eb37a67721b10d703247552416f719c4188c54e04334321351ced"}, - {file = "kiwisolver-1.4.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:9407b6a5f0d675e8a827ad8742e1d6b49d9c1a1da5d952a67d50ef5f4170b18d"}, - {file = "kiwisolver-1.4.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:15568384086b6df3c65353820a4473575dbad192e35010f622c6ce3eebd57af9"}, - {file = "kiwisolver-1.4.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0dc9db8e79f0036e8173c466d21ef18e1befc02de8bf8aa8dc0813a6dc8a7046"}, - {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:cdc8a402aaee9a798b50d8b827d7ecf75edc5fb35ea0f91f213ff927c15f4ff0"}, - {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6c3bd3cde54cafb87d74d8db50b909705c62b17c2099b8f2e25b461882e544ff"}, - {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:955e8513d07a283056b1396e9a57ceddbd272d9252c14f154d450d227606eb54"}, - {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:346f5343b9e3f00b8db8ba359350eb124b98c99efd0b408728ac6ebf38173958"}, - {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b9098e0049e88c6a24ff64545cdfc50807818ba6c1b739cae221bbbcbc58aad3"}, - {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:00bd361b903dc4bbf4eb165f24d1acbee754fce22ded24c3d56eec268658a5cf"}, - {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7b8b454bac16428b22560d0a1cf0a09875339cab69df61d7805bf48919415901"}, - {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:f1d072c2eb0ad60d4c183f3fb44ac6f73fb7a8f16a2694a91f988275cbf352f9"}, - {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:31a82d498054cac9f6d0b53d02bb85811185bcb477d4b60144f915f3b3126342"}, - {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6512cb89e334e4700febbffaaa52761b65b4f5a3cf33f960213d5656cea36a77"}, - {file = "kiwisolver-1.4.5-cp39-cp39-win32.whl", hash = "sha256:9db8ea4c388fdb0f780fe91346fd438657ea602d58348753d9fb265ce1bca67f"}, - {file = "kiwisolver-1.4.5-cp39-cp39-win_amd64.whl", hash = "sha256:59415f46a37f7f2efeec758353dd2eae1b07640d8ca0f0c42548ec4125492635"}, - {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5c7b3b3a728dc6faf3fc372ef24f21d1e3cee2ac3e9596691d746e5a536de920"}, - {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:620ced262a86244e2be10a676b646f29c34537d0d9cc8eb26c08f53d98013390"}, - {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:378a214a1e3bbf5ac4a8708304318b4f890da88c9e6a07699c4ae7174c09a68d"}, - {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaf7be1207676ac608a50cd08f102f6742dbfc70e8d60c4db1c6897f62f71523"}, - {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:ba55dce0a9b8ff59495ddd050a0225d58bd0983d09f87cfe2b6aec4f2c1234e4"}, - {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:fd32ea360bcbb92d28933fc05ed09bffcb1704ba3fc7942e81db0fd4f81a7892"}, - {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5e7139af55d1688f8b960ee9ad5adafc4ac17c1c473fe07133ac092310d76544"}, - {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:dced8146011d2bc2e883f9bd68618b8247387f4bbec46d7392b3c3b032640126"}, - {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9bf3325c47b11b2e51bca0824ea217c7cd84491d8ac4eefd1e409705ef092bd"}, - {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:5794cf59533bc3f1b1c821f7206a3617999db9fbefc345360aafe2e067514929"}, - {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e368f200bbc2e4f905b8e71eb38b3c04333bddaa6a2464a6355487b02bb7fb09"}, - {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5d706eba36b4c4d5bc6c6377bb6568098765e990cfc21ee16d13963fab7b3e7"}, - {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85267bd1aa8880a9c88a8cb71e18d3d64d2751a790e6ca6c27b8ccc724bcd5ad"}, - {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:210ef2c3a1f03272649aff1ef992df2e724748918c4bc2d5a90352849eb40bea"}, - {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:11d011a7574eb3b82bcc9c1a1d35c1d7075677fdd15de527d91b46bd35e935ee"}, - {file = "kiwisolver-1.4.5.tar.gz", hash = "sha256:e57e563a57fb22a142da34f38acc2fc1a5c864bc29ca1517a88abc963e60d6ec"}, -] - -[[package]] -name = "markupsafe" -version = "2.1.3" -description = "Safely add untrusted strings to HTML/XML markup." -optional = false -python-versions = ">=3.7" -files = [ - {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-win32.whl", hash = "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-win32.whl", hash = "sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-win32.whl", hash = "sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-win_amd64.whl", hash = "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-win32.whl", hash = "sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-win_amd64.whl", hash = "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-win32.whl", hash = "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-win_amd64.whl", hash = "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba"}, - {file = "MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad"}, -] - -[[package]] -name = "matplotlib" -version = "3.8.0" -description = "Python plotting package" -optional = false -python-versions = ">=3.9" -files = [ - {file = "matplotlib-3.8.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:c4940bad88a932ddc69734274f6fb047207e008389489f2b6f77d9ca485f0e7a"}, - {file = "matplotlib-3.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a33bd3045c7452ca1fa65676d88ba940867880e13e2546abb143035fa9072a9d"}, - {file = "matplotlib-3.8.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ea6886e93401c22e534bbfd39201ce8931b75502895cfb115cbdbbe2d31f287"}, - {file = "matplotlib-3.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d670b9348e712ec176de225d425f150dc8e37b13010d85233c539b547da0be39"}, - {file = "matplotlib-3.8.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7b37b74f00c4cb6af908cb9a00779d97d294e89fd2145ad43f0cdc23f635760c"}, - {file = "matplotlib-3.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:0e723f5b96f3cd4aad99103dc93e9e3cdc4f18afdcc76951f4857b46f8e39d2d"}, - {file = "matplotlib-3.8.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:5dc945a9cb2deb7d197ba23eb4c210e591d52d77bf0ba27c35fc82dec9fa78d4"}, - {file = "matplotlib-3.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f8b5a1bf27d078453aa7b5b27f52580e16360d02df6d3dc9504f3d2ce11f6309"}, - {file = "matplotlib-3.8.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f25ffb6ad972cdffa7df8e5be4b1e3cadd2f8d43fc72085feb1518006178394"}, - {file = "matplotlib-3.8.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eee482731c8c17d86d9ddb5194d38621f9b0f0d53c99006275a12523ab021732"}, - {file = "matplotlib-3.8.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:36eafe2128772195b373e1242df28d1b7ec6c04c15b090b8d9e335d55a323900"}, - {file = "matplotlib-3.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:061ee58facb3580cd2d046a6d227fb77e9295599c5ec6ad069f06b5821ad1cfc"}, - {file = "matplotlib-3.8.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:3cc3776836d0f4f22654a7f2d2ec2004618d5cf86b7185318381f73b80fd8a2d"}, - {file = "matplotlib-3.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6c49a2bd6981264bddcb8c317b6bd25febcece9e2ebfcbc34e7f4c0c867c09dc"}, - {file = "matplotlib-3.8.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23ed11654fc83cd6cfdf6170b453e437674a050a452133a064d47f2f1371f8d3"}, - {file = "matplotlib-3.8.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dae97fdd6996b3a25da8ee43e3fc734fff502f396801063c6b76c20b56683196"}, - {file = "matplotlib-3.8.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:87df75f528020a6299f76a1d986c0ed4406e3b2bd44bc5e306e46bca7d45e53e"}, - {file = "matplotlib-3.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:90d74a95fe055f73a6cd737beecc1b81c26f2893b7a3751d52b53ff06ca53f36"}, - {file = "matplotlib-3.8.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:c3499c312f5def8f362a2bf761d04fa2d452b333f3a9a3f58805273719bf20d9"}, - {file = "matplotlib-3.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:31e793c8bd4ea268cc5d3a695c27b30650ec35238626961d73085d5e94b6ab68"}, - {file = "matplotlib-3.8.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d5ee602ef517a89d1f2c508ca189cfc395dd0b4a08284fb1b97a78eec354644"}, - {file = "matplotlib-3.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5de39dc61ca35342cf409e031f70f18219f2c48380d3886c1cf5ad9f17898e06"}, - {file = "matplotlib-3.8.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:dd386c80a98b5f51571b9484bf6c6976de383cd2a8cd972b6a9562d85c6d2087"}, - {file = "matplotlib-3.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:f691b4ef47c7384d0936b2e8ebdeb5d526c81d004ad9403dfb9d4c76b9979a93"}, - {file = "matplotlib-3.8.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:0b11f354aae62a2aa53ec5bb09946f5f06fc41793e351a04ff60223ea9162955"}, - {file = "matplotlib-3.8.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f54b9fb87ca5acbcdd0f286021bedc162e1425fa5555ebf3b3dfc167b955ad9"}, - {file = "matplotlib-3.8.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:60a6e04dfd77c0d3bcfee61c3cd335fff1b917c2f303b32524cd1235e194ef99"}, - {file = "matplotlib-3.8.0.tar.gz", hash = "sha256:df8505e1c19d5c2c26aff3497a7cbd3ccfc2e97043d1e4db3e76afa399164b69"}, -] - -[package.dependencies] -contourpy = ">=1.0.1" -cycler = ">=0.10" -fonttools = ">=4.22.0" -kiwisolver = ">=1.0.1" -numpy = ">=1.21,<2" -packaging = ">=20.0" -pillow = ">=6.2.0" -pyparsing = ">=2.3.1" -python-dateutil = ">=2.7" -setuptools_scm = ">=7" - -[[package]] -name = "mpmath" -version = "1.3.0" -description = "Python library for arbitrary-precision floating-point arithmetic" -optional = false -python-versions = "*" -files = [ - {file = "mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c"}, - {file = "mpmath-1.3.0.tar.gz", hash = "sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f"}, -] - -[package.extras] -develop = ["codecov", "pycodestyle", "pytest (>=4.6)", "pytest-cov", "wheel"] -docs = ["sphinx"] -gmpy = ["gmpy2 (>=2.1.0a4)"] -tests = ["pytest (>=4.6)"] - -[[package]] -name = "networkx" -version = "3.2" -description = "Python package for creating and manipulating graphs and networks" -optional = false -python-versions = ">=3.9" -files = [ - {file = "networkx-3.2-py3-none-any.whl", hash = "sha256:8b25f564bd28f94ac821c58b04ae1a3109e73b001a7d476e4bb0d00d63706bf8"}, - {file = "networkx-3.2.tar.gz", hash = "sha256:bda29edf392d9bfa5602034c767d28549214ec45f620081f0b74dc036a1fbbc1"}, -] - -[package.extras] -default = ["matplotlib (>=3.5)", "numpy (>=1.22)", "pandas (>=1.4)", "scipy (>=1.9,!=1.11.0,!=1.11.1)"] -developer = ["changelist (==0.4)", "mypy (>=1.1)", "pre-commit (>=3.2)", "rtoml"] -doc = ["nb2plots (>=0.7)", "nbconvert (<7.9)", "numpydoc (>=1.6)", "pillow (>=9.4)", "pydata-sphinx-theme (>=0.14)", "sphinx (>=7)", "sphinx-gallery (>=0.14)", "texext (>=0.6.7)"] -extra = ["lxml (>=4.6)", "pydot (>=1.4.2)", "pygraphviz (>=1.11)", "sympy (>=1.10)"] -test = ["pytest (>=7.2)", "pytest-cov (>=4.0)"] - -[[package]] -name = "numpy" -version = "1.26.1" -description = "Fundamental package for array computing in Python" -optional = false -python-versions = "<3.13,>=3.9" -files = [ - {file = "numpy-1.26.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:82e871307a6331b5f09efda3c22e03c095d957f04bf6bc1804f30048d0e5e7af"}, - {file = "numpy-1.26.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cdd9ec98f0063d93baeb01aad472a1a0840dee302842a2746a7a8e92968f9575"}, - {file = "numpy-1.26.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d78f269e0c4fd365fc2992c00353e4530d274ba68f15e968d8bc3c69ce5f5244"}, - {file = "numpy-1.26.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8ab9163ca8aeb7fd32fe93866490654d2f7dda4e61bc6297bf72ce07fdc02f67"}, - {file = "numpy-1.26.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:78ca54b2f9daffa5f323f34cdf21e1d9779a54073f0018a3094ab907938331a2"}, - {file = "numpy-1.26.1-cp310-cp310-win32.whl", hash = "sha256:d1cfc92db6af1fd37a7bb58e55c8383b4aa1ba23d012bdbba26b4bcca45ac297"}, - {file = "numpy-1.26.1-cp310-cp310-win_amd64.whl", hash = "sha256:d2984cb6caaf05294b8466966627e80bf6c7afd273279077679cb010acb0e5ab"}, - {file = "numpy-1.26.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cd7837b2b734ca72959a1caf3309457a318c934abef7a43a14bb984e574bbb9a"}, - {file = "numpy-1.26.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1c59c046c31a43310ad0199d6299e59f57a289e22f0f36951ced1c9eac3665b9"}, - {file = "numpy-1.26.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d58e8c51a7cf43090d124d5073bc29ab2755822181fcad978b12e144e5e5a4b3"}, - {file = "numpy-1.26.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6081aed64714a18c72b168a9276095ef9155dd7888b9e74b5987808f0dd0a974"}, - {file = "numpy-1.26.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:97e5d6a9f0702c2863aaabf19f0d1b6c2628fbe476438ce0b5ce06e83085064c"}, - {file = "numpy-1.26.1-cp311-cp311-win32.whl", hash = "sha256:b9d45d1dbb9de84894cc50efece5b09939752a2d75aab3a8b0cef6f3a35ecd6b"}, - {file = "numpy-1.26.1-cp311-cp311-win_amd64.whl", hash = "sha256:3649d566e2fc067597125428db15d60eb42a4e0897fc48d28cb75dc2e0454e53"}, - {file = "numpy-1.26.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:1d1bd82d539607951cac963388534da3b7ea0e18b149a53cf883d8f699178c0f"}, - {file = "numpy-1.26.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:afd5ced4e5a96dac6725daeb5242a35494243f2239244fad10a90ce58b071d24"}, - {file = "numpy-1.26.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a03fb25610ef560a6201ff06df4f8105292ba56e7cdd196ea350d123fc32e24e"}, - {file = "numpy-1.26.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcfaf015b79d1f9f9c9fd0731a907407dc3e45769262d657d754c3a028586124"}, - {file = "numpy-1.26.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e509cbc488c735b43b5ffea175235cec24bbc57b227ef1acc691725beb230d1c"}, - {file = "numpy-1.26.1-cp312-cp312-win32.whl", hash = "sha256:af22f3d8e228d84d1c0c44c1fbdeb80f97a15a0abe4f080960393a00db733b66"}, - {file = "numpy-1.26.1-cp312-cp312-win_amd64.whl", hash = "sha256:9f42284ebf91bdf32fafac29d29d4c07e5e9d1af862ea73686581773ef9e73a7"}, - {file = "numpy-1.26.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bb894accfd16b867d8643fc2ba6c8617c78ba2828051e9a69511644ce86ce83e"}, - {file = "numpy-1.26.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e44ccb93f30c75dfc0c3aa3ce38f33486a75ec9abadabd4e59f114994a9c4617"}, - {file = "numpy-1.26.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9696aa2e35cc41e398a6d42d147cf326f8f9d81befcb399bc1ed7ffea339b64e"}, - {file = "numpy-1.26.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a5b411040beead47a228bde3b2241100454a6abde9df139ed087bd73fc0a4908"}, - {file = "numpy-1.26.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1e11668d6f756ca5ef534b5be8653d16c5352cbb210a5c2a79ff288e937010d5"}, - {file = "numpy-1.26.1-cp39-cp39-win32.whl", hash = "sha256:d1d2c6b7dd618c41e202c59c1413ef9b2c8e8a15f5039e344af64195459e3104"}, - {file = "numpy-1.26.1-cp39-cp39-win_amd64.whl", hash = "sha256:59227c981d43425ca5e5c01094d59eb14e8772ce6975d4b2fc1e106a833d5ae2"}, - {file = "numpy-1.26.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:06934e1a22c54636a059215d6da99e23286424f316fddd979f5071093b648668"}, - {file = "numpy-1.26.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76ff661a867d9272cd2a99eed002470f46dbe0943a5ffd140f49be84f68ffc42"}, - {file = "numpy-1.26.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:6965888d65d2848e8768824ca8288db0a81263c1efccec881cb35a0d805fcd2f"}, - {file = "numpy-1.26.1.tar.gz", hash = "sha256:c8c6c72d4a9f831f328efb1312642a1cafafaa88981d9ab76368d50d07d93cbe"}, -] - -[[package]] -name = "numpy-quaternion" -version = "2022.4.3" -description = "Add a quaternion dtype to NumPy" -optional = false -python-versions = "*" -files = [ - {file = "numpy-quaternion-2022.4.3.tar.gz", hash = "sha256:ca37256f544a7e587ab08c1841a30e34aa7b85c7c9663527c61d77fbcad9dda7"}, - {file = "numpy_quaternion-2022.4.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:c403eeddfc19cb3b400abbd6daabd9aec9843344e9b9c739f080d27291e3d75e"}, - {file = "numpy_quaternion-2022.4.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ca743f7ca7a86b555cfc7e9f72acb7eb50fd56ec28834432b54b00896ba6363a"}, - {file = "numpy_quaternion-2022.4.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a4db146a130d53cea5d74543950e5ebd01dd7603dfe5a42d4f3ebc76539551bb"}, - {file = "numpy_quaternion-2022.4.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9ebf377c7174f4b32e1078e4607afbb3c4e0d0365dc633d43654f01e3703e800"}, - {file = "numpy_quaternion-2022.4.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ce50c414e884d8d18615cb6b5c928929e9dcff2f98f4606b2cc7a5b4dd5f5fb4"}, - {file = "numpy_quaternion-2022.4.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca29e8f961673932d123a8b2520ef7ded9fee4e426aed628d90ced0749608285"}, - {file = "numpy_quaternion-2022.4.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:9a7fcf818691aec1250f53c99c7958f57e09489e5ce1371b3a5342b65439da9d"}, - {file = "numpy_quaternion-2022.4.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7cfec847bca62ff2ff50b190fb0e7c733a0f7f42ce6ac6385166bf6c814d5b15"}, - {file = "numpy_quaternion-2022.4.3-cp310-cp310-win32.whl", hash = "sha256:3c7de12e8270e6b4fa7da9da372134a56a85eebbb1b1d81e8419e8315cea7227"}, - {file = "numpy_quaternion-2022.4.3-cp310-cp310-win_amd64.whl", hash = "sha256:53bcaa3c0fb245623a092eb43224e30b883882b3460143487cccf9797fc865ae"}, - {file = "numpy_quaternion-2022.4.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5d9e6bec15afeba28022b7a44fdf28da27fd0422075b76be99c5be70969d52e6"}, - {file = "numpy_quaternion-2022.4.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7e7c36d949d09e07bd091bae1cb7c56b7dcedfb2c570f89e75be6de9f37d44a6"}, - {file = "numpy_quaternion-2022.4.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c521e6ee255c74f1ef604bd8ebdfdc32225d9ac7ce52c731562d4b4e01358793"}, - {file = "numpy_quaternion-2022.4.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5f13b7faa8b9859fba94f1425d9ac6478d74fa2b26f5cb0b8258a48365ee49b"}, - {file = "numpy_quaternion-2022.4.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:364c142af3ba8aac3ee6de9ab652a409133d23d81642c18fae150585b006cf85"}, - {file = "numpy_quaternion-2022.4.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a82205a785be37c1a2ae28dd13c02a6aaf43e7a1f3ac4cb57f6efc2d2e5d8a1"}, - {file = "numpy_quaternion-2022.4.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:accbe7758561a4bb3bd486b5f754b9983bc1be17ee517feb715d7e363833407f"}, - {file = "numpy_quaternion-2022.4.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7d97d22a082caa924f2ebd998563437884e1f578c5cdb8ba001abc60d2909922"}, - {file = "numpy_quaternion-2022.4.3-cp311-cp311-win32.whl", hash = "sha256:75c734f4b3f887f465da3571afeff924781f53dbf39c8da199fb860b9f4dc3ec"}, - {file = "numpy_quaternion-2022.4.3-cp311-cp311-win_amd64.whl", hash = "sha256:a0aaa74a13799e13bb9b6a65964401260f7a5482d2f7e50f5e564c8866f8b96f"}, - {file = "numpy_quaternion-2022.4.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:8761f80fc4f510147bf690d494668f0944a2d590e2c5ada9d7c62af6a46e81ad"}, - {file = "numpy_quaternion-2022.4.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e34ed9c325dcd631b67dcf30b6f493528228622bc8b8b9abfaf68166fc367151"}, - {file = "numpy_quaternion-2022.4.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4b685200964fd9e654c12cc298d5d086ef0a0313ee2b17d6b9ff29a3a880d803"}, - {file = "numpy_quaternion-2022.4.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d635131afbd49dafa9463c78bf1a298c9de35cc759e6008647c714780e68de7"}, - {file = "numpy_quaternion-2022.4.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:71a5f6fbf64001369f178168a46287dce33157947272073258d20e846b0f40a4"}, - {file = "numpy_quaternion-2022.4.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9b17ebddb0bd3fe646fc56b0e8693a92561e704be541bc3dcb4282988ebb01ed"}, - {file = "numpy_quaternion-2022.4.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ebd03fb341ae3f837d6d9d96df25b1c4bc0dafd9ffcb562eebdae29496f175e"}, - {file = "numpy_quaternion-2022.4.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:4f07823341642943d24cddc10f07cb4e32e10f5cc033fb42aa2f181e8bf0699f"}, - {file = "numpy_quaternion-2022.4.3-cp38-cp38-win32.whl", hash = "sha256:556c32f082bb97aab9f41f7154b4d7f004a22c3187f056e78d17bf818644804f"}, - {file = "numpy_quaternion-2022.4.3-cp38-cp38-win_amd64.whl", hash = "sha256:ccf9b0fc0e6b2a1f6c5a0bf2e5affbc588cc09d5ba585d176bd92e9f4bdfd7a1"}, - {file = "numpy_quaternion-2022.4.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:0fc5aed22a2170eb2c65aa3a0d10c08883ec9fdc35d10c110d38811f736d609a"}, - {file = "numpy_quaternion-2022.4.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d35e7bdc02025601d21830c6419e1317059083e1a3ccab68df5113b167e3fc61"}, - {file = "numpy_quaternion-2022.4.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f9a7ed1ee9954e06e81847600eefa11d162e9cbbd386a0c693f0f681ec731133"}, - {file = "numpy_quaternion-2022.4.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:334376b88dcede4263f1338b4ab40e1124c7a8fc8f81e3c3e1070cc0f5da10a7"}, - {file = "numpy_quaternion-2022.4.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4605a23c57fead0c20623e55b473fa233b082b5ed4d83553da6c2cb83541f428"}, - {file = "numpy_quaternion-2022.4.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a3b4ed4ca225c7f5965ddc18a8cba0f7ea8406a869872d18d1f9900420ebdd38"}, - {file = "numpy_quaternion-2022.4.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:ded4c4122481b465e46374d9087da280d712d7ea500b34fc03ae854cfc3c86b5"}, - {file = "numpy_quaternion-2022.4.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:e4b28a372b1362b75a23d3abf08fcc5a77c950aa554136137c5f2cd5d3a45edb"}, - {file = "numpy_quaternion-2022.4.3-cp39-cp39-win32.whl", hash = "sha256:158df059771f5c2baa2fa43f166be30c0507aacea7df1c6fd67eb4c404b3fae3"}, - {file = "numpy_quaternion-2022.4.3-cp39-cp39-win_amd64.whl", hash = "sha256:2ebb925346ee4a7c1ac3d9d00383950ad610d7cc672445b7b7f67e0a3a03df40"}, -] - -[package.dependencies] -numpy = ">=1.13" - -[package.extras] -docs = ["mkdocs", "mktheapidocs[plugin]", "pymdown-extensions"] -numba = ["llvmlite (<0.32.0)", "numba", "numba (<0.49.0)"] -scipy = ["scipy"] -testing = ["pytest", "pytest-cov"] - -[[package]] -name = "packaging" -version = "23.2" -description = "Core utilities for Python packages" -optional = false -python-versions = ">=3.7" -files = [ - {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, - {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, -] - -[[package]] -name = "pandas" -version = "2.1.1" -description = "Powerful data structures for data analysis, time series, and statistics" -optional = false -python-versions = ">=3.9" -files = [ - {file = "pandas-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:58d997dbee0d4b64f3cb881a24f918b5f25dd64ddf31f467bb9b67ae4c63a1e4"}, - {file = "pandas-2.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:02304e11582c5d090e5a52aec726f31fe3f42895d6bfc1f28738f9b64b6f0614"}, - {file = "pandas-2.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffa8f0966de2c22de408d0e322db2faed6f6e74265aa0856f3824813cf124363"}, - {file = "pandas-2.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c1f84c144dee086fe4f04a472b5cd51e680f061adf75c1ae4fc3a9275560f8f4"}, - {file = "pandas-2.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:75ce97667d06d69396d72be074f0556698c7f662029322027c226fd7a26965cb"}, - {file = "pandas-2.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:4c3f32fd7c4dccd035f71734df39231ac1a6ff95e8bdab8d891167197b7018d2"}, - {file = "pandas-2.1.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9e2959720b70e106bb1d8b6eadd8ecd7c8e99ccdbe03ee03260877184bb2877d"}, - {file = "pandas-2.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:25e8474a8eb258e391e30c288eecec565bfed3e026f312b0cbd709a63906b6f8"}, - {file = "pandas-2.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b8bd1685556f3374520466998929bade3076aeae77c3e67ada5ed2b90b4de7f0"}, - {file = "pandas-2.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc3657869c7902810f32bd072f0740487f9e030c1a3ab03e0af093db35a9d14e"}, - {file = "pandas-2.1.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:05674536bd477af36aa2effd4ec8f71b92234ce0cc174de34fd21e2ee99adbc2"}, - {file = "pandas-2.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:b407381258a667df49d58a1b637be33e514b07f9285feb27769cedb3ab3d0b3a"}, - {file = "pandas-2.1.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c747793c4e9dcece7bb20156179529898abf505fe32cb40c4052107a3c620b49"}, - {file = "pandas-2.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3bcad1e6fb34b727b016775bea407311f7721db87e5b409e6542f4546a4951ea"}, - {file = "pandas-2.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f5ec7740f9ccb90aec64edd71434711f58ee0ea7f5ed4ac48be11cfa9abf7317"}, - {file = "pandas-2.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:29deb61de5a8a93bdd033df328441a79fcf8dd3c12d5ed0b41a395eef9cd76f0"}, - {file = "pandas-2.1.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4f99bebf19b7e03cf80a4e770a3e65eee9dd4e2679039f542d7c1ace7b7b1daa"}, - {file = "pandas-2.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:84e7e910096416adec68075dc87b986ff202920fb8704e6d9c8c9897fe7332d6"}, - {file = "pandas-2.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:366da7b0e540d1b908886d4feb3d951f2f1e572e655c1160f5fde28ad4abb750"}, - {file = "pandas-2.1.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9e50e72b667415a816ac27dfcfe686dc5a0b02202e06196b943d54c4f9c7693e"}, - {file = "pandas-2.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc1ab6a25da197f03ebe6d8fa17273126120874386b4ac11c1d687df288542dd"}, - {file = "pandas-2.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0dbfea0dd3901ad4ce2306575c54348d98499c95be01b8d885a2737fe4d7a98"}, - {file = "pandas-2.1.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0489b0e6aa3d907e909aef92975edae89b1ee1654db5eafb9be633b0124abe97"}, - {file = "pandas-2.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:4cdb0fab0400c2cb46dafcf1a0fe084c8bb2480a1fa8d81e19d15e12e6d4ded2"}, - {file = "pandas-2.1.1.tar.gz", hash = "sha256:fecb198dc389429be557cde50a2d46da8434a17fe37d7d41ff102e3987fd947b"}, -] - -[package.dependencies] -numpy = [ - {version = ">=1.22.4", markers = "python_version < \"3.11\""}, - {version = ">=1.23.2", markers = "python_version == \"3.11\""}, - {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, -] -python-dateutil = ">=2.8.2" -pytz = ">=2020.1" -tzdata = ">=2022.1" - -[package.extras] -all = ["PyQt5 (>=5.15.6)", "SQLAlchemy (>=1.4.36)", "beautifulsoup4 (>=4.11.1)", "bottleneck (>=1.3.4)", "dataframe-api-compat (>=0.1.7)", "fastparquet (>=0.8.1)", "fsspec (>=2022.05.0)", "gcsfs (>=2022.05.0)", "html5lib (>=1.1)", "hypothesis (>=6.46.1)", "jinja2 (>=3.1.2)", "lxml (>=4.8.0)", "matplotlib (>=3.6.1)", "numba (>=0.55.2)", "numexpr (>=2.8.0)", "odfpy (>=1.4.1)", "openpyxl (>=3.0.10)", "pandas-gbq (>=0.17.5)", "psycopg2 (>=2.9.3)", "pyarrow (>=7.0.0)", "pymysql (>=1.0.2)", "pyreadstat (>=1.1.5)", "pytest (>=7.3.2)", "pytest-asyncio (>=0.17.0)", "pytest-xdist (>=2.2.0)", "pyxlsb (>=1.0.9)", "qtpy (>=2.2.0)", "s3fs (>=2022.05.0)", "scipy (>=1.8.1)", "tables (>=3.7.0)", "tabulate (>=0.8.10)", "xarray (>=2022.03.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.3)", "zstandard (>=0.17.0)"] -aws = ["s3fs (>=2022.05.0)"] -clipboard = ["PyQt5 (>=5.15.6)", "qtpy (>=2.2.0)"] -compression = ["zstandard (>=0.17.0)"] -computation = ["scipy (>=1.8.1)", "xarray (>=2022.03.0)"] -consortium-standard = ["dataframe-api-compat (>=0.1.7)"] -excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.0.10)", "pyxlsb (>=1.0.9)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.3)"] -feather = ["pyarrow (>=7.0.0)"] -fss = ["fsspec (>=2022.05.0)"] -gcp = ["gcsfs (>=2022.05.0)", "pandas-gbq (>=0.17.5)"] -hdf5 = ["tables (>=3.7.0)"] -html = ["beautifulsoup4 (>=4.11.1)", "html5lib (>=1.1)", "lxml (>=4.8.0)"] -mysql = ["SQLAlchemy (>=1.4.36)", "pymysql (>=1.0.2)"] -output-formatting = ["jinja2 (>=3.1.2)", "tabulate (>=0.8.10)"] -parquet = ["pyarrow (>=7.0.0)"] -performance = ["bottleneck (>=1.3.4)", "numba (>=0.55.2)", "numexpr (>=2.8.0)"] -plot = ["matplotlib (>=3.6.1)"] -postgresql = ["SQLAlchemy (>=1.4.36)", "psycopg2 (>=2.9.3)"] -spss = ["pyreadstat (>=1.1.5)"] -sql-other = ["SQLAlchemy (>=1.4.36)"] -test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-asyncio (>=0.17.0)", "pytest-xdist (>=2.2.0)"] -xml = ["lxml (>=4.8.0)"] - -[[package]] -name = "parameterized" -version = "0.9.0" -description = "Parameterized testing with any Python test framework" -optional = false -python-versions = ">=3.7" -files = [ - {file = "parameterized-0.9.0-py2.py3-none-any.whl", hash = "sha256:4e0758e3d41bea3bbd05ec14fc2c24736723f243b28d702081aef438c9372b1b"}, - {file = "parameterized-0.9.0.tar.gz", hash = "sha256:7fc905272cefa4f364c1a3429cbbe9c0f98b793988efb5bf90aac80f08db09b1"}, -] - -[package.extras] -dev = ["jinja2"] - -[[package]] -name = "pillow" -version = "10.1.0" -description = "Python Imaging Library (Fork)" -optional = false -python-versions = ">=3.8" -files = [ - {file = "Pillow-10.1.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:1ab05f3db77e98f93964697c8efc49c7954b08dd61cff526b7f2531a22410106"}, - {file = "Pillow-10.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6932a7652464746fcb484f7fc3618e6503d2066d853f68a4bd97193a3996e273"}, - {file = "Pillow-10.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5f63b5a68daedc54c7c3464508d8c12075e56dcfbd42f8c1bf40169061ae666"}, - {file = "Pillow-10.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0949b55eb607898e28eaccb525ab104b2d86542a85c74baf3a6dc24002edec2"}, - {file = "Pillow-10.1.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:ae88931f93214777c7a3aa0a8f92a683f83ecde27f65a45f95f22d289a69e593"}, - {file = "Pillow-10.1.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:b0eb01ca85b2361b09480784a7931fc648ed8b7836f01fb9241141b968feb1db"}, - {file = "Pillow-10.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d27b5997bdd2eb9fb199982bb7eb6164db0426904020dc38c10203187ae2ff2f"}, - {file = "Pillow-10.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7df5608bc38bd37ef585ae9c38c9cd46d7c81498f086915b0f97255ea60c2818"}, - {file = "Pillow-10.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:41f67248d92a5e0a2076d3517d8d4b1e41a97e2df10eb8f93106c89107f38b57"}, - {file = "Pillow-10.1.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:1fb29c07478e6c06a46b867e43b0bcdb241b44cc52be9bc25ce5944eed4648e7"}, - {file = "Pillow-10.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2cdc65a46e74514ce742c2013cd4a2d12e8553e3a2563c64879f7c7e4d28bce7"}, - {file = "Pillow-10.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50d08cd0a2ecd2a8657bd3d82c71efd5a58edb04d9308185d66c3a5a5bed9610"}, - {file = "Pillow-10.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:062a1610e3bc258bff2328ec43f34244fcec972ee0717200cb1425214fe5b839"}, - {file = "Pillow-10.1.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:61f1a9d247317fa08a308daaa8ee7b3f760ab1809ca2da14ecc88ae4257d6172"}, - {file = "Pillow-10.1.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:a646e48de237d860c36e0db37ecaecaa3619e6f3e9d5319e527ccbc8151df061"}, - {file = "Pillow-10.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:47e5bf85b80abc03be7455c95b6d6e4896a62f6541c1f2ce77a7d2bb832af262"}, - {file = "Pillow-10.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a92386125e9ee90381c3369f57a2a50fa9e6aa8b1cf1d9c4b200d41a7dd8e992"}, - {file = "Pillow-10.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:0f7c276c05a9767e877a0b4c5050c8bee6a6d960d7f0c11ebda6b99746068c2a"}, - {file = "Pillow-10.1.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:a89b8312d51715b510a4fe9fc13686283f376cfd5abca8cd1c65e4c76e21081b"}, - {file = "Pillow-10.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:00f438bb841382b15d7deb9a05cc946ee0f2c352653c7aa659e75e592f6fa17d"}, - {file = "Pillow-10.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3d929a19f5469b3f4df33a3df2983db070ebb2088a1e145e18facbc28cae5b27"}, - {file = "Pillow-10.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a92109192b360634a4489c0c756364c0c3a2992906752165ecb50544c251312"}, - {file = "Pillow-10.1.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:0248f86b3ea061e67817c47ecbe82c23f9dd5d5226200eb9090b3873d3ca32de"}, - {file = "Pillow-10.1.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:9882a7451c680c12f232a422730f986a1fcd808da0fd428f08b671237237d651"}, - {file = "Pillow-10.1.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1c3ac5423c8c1da5928aa12c6e258921956757d976405e9467c5f39d1d577a4b"}, - {file = "Pillow-10.1.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:806abdd8249ba3953c33742506fe414880bad78ac25cc9a9b1c6ae97bedd573f"}, - {file = "Pillow-10.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:eaed6977fa73408b7b8a24e8b14e59e1668cfc0f4c40193ea7ced8e210adf996"}, - {file = "Pillow-10.1.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:fe1e26e1ffc38be097f0ba1d0d07fcade2bcfd1d023cda5b29935ae8052bd793"}, - {file = "Pillow-10.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7a7e3daa202beb61821c06d2517428e8e7c1aab08943e92ec9e5755c2fc9ba5e"}, - {file = "Pillow-10.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:24fadc71218ad2b8ffe437b54876c9382b4a29e030a05a9879f615091f42ffc2"}, - {file = "Pillow-10.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa1d323703cfdac2036af05191b969b910d8f115cf53093125e4058f62012c9a"}, - {file = "Pillow-10.1.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:912e3812a1dbbc834da2b32299b124b5ddcb664ed354916fd1ed6f193f0e2d01"}, - {file = "Pillow-10.1.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:7dbaa3c7de82ef37e7708521be41db5565004258ca76945ad74a8e998c30af8d"}, - {file = "Pillow-10.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9d7bc666bd8c5a4225e7ac71f2f9d12466ec555e89092728ea0f5c0c2422ea80"}, - {file = "Pillow-10.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:baada14941c83079bf84c037e2d8b7506ce201e92e3d2fa0d1303507a8538212"}, - {file = "Pillow-10.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:2ef6721c97894a7aa77723740a09547197533146fba8355e86d6d9a4a1056b14"}, - {file = "Pillow-10.1.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:0a026c188be3b443916179f5d04548092e253beb0c3e2ee0a4e2cdad72f66099"}, - {file = "Pillow-10.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:04f6f6149f266a100374ca3cc368b67fb27c4af9f1cc8cb6306d849dcdf12616"}, - {file = "Pillow-10.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb40c011447712d2e19cc261c82655f75f32cb724788df315ed992a4d65696bb"}, - {file = "Pillow-10.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a8413794b4ad9719346cd9306118450b7b00d9a15846451549314a58ac42219"}, - {file = "Pillow-10.1.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:c9aeea7b63edb7884b031a35305629a7593272b54f429a9869a4f63a1bf04c34"}, - {file = "Pillow-10.1.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:b4005fee46ed9be0b8fb42be0c20e79411533d1fd58edabebc0dd24626882cfd"}, - {file = "Pillow-10.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4d0152565c6aa6ebbfb1e5d8624140a440f2b99bf7afaafbdbf6430426497f28"}, - {file = "Pillow-10.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d921bc90b1defa55c9917ca6b6b71430e4286fc9e44c55ead78ca1a9f9eba5f2"}, - {file = "Pillow-10.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:cfe96560c6ce2f4c07d6647af2d0f3c54cc33289894ebd88cfbb3bcd5391e256"}, - {file = "Pillow-10.1.0-pp310-pypy310_pp73-macosx_10_10_x86_64.whl", hash = "sha256:937bdc5a7f5343d1c97dc98149a0be7eb9704e937fe3dc7140e229ae4fc572a7"}, - {file = "Pillow-10.1.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1c25762197144e211efb5f4e8ad656f36c8d214d390585d1d21281f46d556ba"}, - {file = "Pillow-10.1.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:afc8eef765d948543a4775f00b7b8c079b3321d6b675dde0d02afa2ee23000b4"}, - {file = "Pillow-10.1.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:883f216eac8712b83a63f41b76ddfb7b2afab1b74abbb413c5df6680f071a6b9"}, - {file = "Pillow-10.1.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:b920e4d028f6442bea9a75b7491c063f0b9a3972520731ed26c83e254302eb1e"}, - {file = "Pillow-10.1.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c41d960babf951e01a49c9746f92c5a7e0d939d1652d7ba30f6b3090f27e412"}, - {file = "Pillow-10.1.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:1fafabe50a6977ac70dfe829b2d5735fd54e190ab55259ec8aea4aaea412fa0b"}, - {file = "Pillow-10.1.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:3b834f4b16173e5b92ab6566f0473bfb09f939ba14b23b8da1f54fa63e4b623f"}, - {file = "Pillow-10.1.0.tar.gz", hash = "sha256:e6bf8de6c36ed96c86ea3b6e1d5273c53f46ef518a062464cd7ef5dd2cf92e38"}, -] - -[package.extras] -docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-removed-in", "sphinxext-opengraph"] -tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] - -[[package]] -name = "platformdirs" -version = "3.11.0" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." -optional = false -python-versions = ">=3.7" -files = [ - {file = "platformdirs-3.11.0-py3-none-any.whl", hash = "sha256:e9d171d00af68be50e9202731309c4e658fd8bc76f55c11c7dd760d023bda68e"}, - {file = "platformdirs-3.11.0.tar.gz", hash = "sha256:cf8ee52a3afdb965072dcc652433e0c7e3e40cf5ea1477cd4b3b1d2eb75495b3"}, -] - -[package.extras] -docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.1)", "sphinx-autodoc-typehints (>=1.24)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)"] - -[[package]] -name = "pluggy" -version = "1.3.0" -description = "plugin and hook calling mechanisms for python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pluggy-1.3.0-py3-none-any.whl", hash = "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7"}, - {file = "pluggy-1.3.0.tar.gz", hash = "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12"}, -] - -[package.extras] -dev = ["pre-commit", "tox"] -testing = ["pytest", "pytest-benchmark"] - -[[package]] -name = "pooch" -version = "1.7.0" -description = "\"Pooch manages your Python library's sample data files: it automatically downloads and stores them in a local directory, with support for versioning and corruption checks.\"" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pooch-1.7.0-py3-none-any.whl", hash = "sha256:74258224fc33d58f53113cf955e8d51bf01386b91492927d0d1b6b341a765ad7"}, - {file = "pooch-1.7.0.tar.gz", hash = "sha256:f174a1041b6447f0eef8860f76d17f60ed2f857dc0efa387a7f08228af05d998"}, -] - -[package.dependencies] -packaging = ">=20.0" -platformdirs = ">=2.5.0" -requests = ">=2.19.0" - -[package.extras] -progress = ["tqdm (>=4.41.0,<5.0.0)"] -sftp = ["paramiko (>=2.7.0)"] -xxhash = ["xxhash (>=1.4.3)"] - -[[package]] -name = "pycodestyle" -version = "2.11.1" -description = "Python style guide checker" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pycodestyle-2.11.1-py2.py3-none-any.whl", hash = "sha256:44fe31000b2d866f2e41841b18528a505fbd7fef9017b04eff4e2648a0fadc67"}, - {file = "pycodestyle-2.11.1.tar.gz", hash = "sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f"}, -] - -[[package]] -name = "pyerfa" -version = "2.0.1.1" -description = "Python bindings for ERFA" -optional = false -python-versions = ">=3.9" -files = [ - {file = "pyerfa-2.0.1.1-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:1ce322ac30673c2aeb0ee22ced4938c1e9e26db0cbe175912a213aaff42383df"}, - {file = "pyerfa-2.0.1.1-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:67dfc00dcdea87a9b3c0bb4596fb0cfb54ee9c1c75fdcf19411d1029a18f6eec"}, - {file = "pyerfa-2.0.1.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:34ee545780246fb0d1d3f7e46a6daa152be06a26b2d27fbfe309cab9ab488ea7"}, - {file = "pyerfa-2.0.1.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1db85db72ab352da6ffc790e41209d8f41feb5b175d682cf1f0e3e60e9e5cdf8"}, - {file = "pyerfa-2.0.1.1-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:c50b7cdb005632931b7b56a679cf25361ed6b3aa7c21e491e65cc89cb337e66a"}, - {file = "pyerfa-2.0.1.1-cp39-abi3-win32.whl", hash = "sha256:30649047b7a8ce19f43e4d18a26b8a44405a6bb406df16c687330a3b937723b2"}, - {file = "pyerfa-2.0.1.1-cp39-abi3-win_amd64.whl", hash = "sha256:94df7566ce5a5abb14e2dd1fe879204390639e9a76383ec27f10598eb24be760"}, - {file = "pyerfa-2.0.1.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0e95cf3d11f76f473bf011980e9ea367ca7e68ca675d8b32499814fb6e387d4c"}, - {file = "pyerfa-2.0.1.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08b5abb90b34e819c1fca69047a76c0d344cb0c8fe4f7c8773f032d8afd623b4"}, - {file = "pyerfa-2.0.1.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:1c0c1efa701cab986aa58d03c58f77e47ea1898bff2684377d29580a055f836a"}, - {file = "pyerfa-2.0.1.1.tar.gz", hash = "sha256:dbac74ef8d3d3b0f22ef0ad3bbbdb30b2a9e10570b1fa5a98be34c7be36c9a6b"}, -] - -[package.dependencies] -numpy = ">=1.19" - -[package.extras] -docs = ["sphinx-astropy (>=1.3)"] -test = ["pytest", "pytest-doctestplus (>=0.7)"] - -[[package]] -name = "pyparsing" -version = "3.1.1" -description = "pyparsing module - Classes and methods to define and execute parsing grammars" -optional = false -python-versions = ">=3.6.8" -files = [ - {file = "pyparsing-3.1.1-py3-none-any.whl", hash = "sha256:32c7c0b711493c72ff18a981d24f28aaf9c1fb7ed5e9667c9e84e3db623bdbfb"}, - {file = "pyparsing-3.1.1.tar.gz", hash = "sha256:ede28a1a32462f5a9705e07aea48001a08f7cf81a021585011deba701581a0db"}, -] - -[package.extras] -diagrams = ["jinja2", "railroad-diagrams"] - -[[package]] -name = "pyshtools" -version = "4.10.4" -description = "SHTOOLS - Spherical Harmonic Tools" -optional = false -python-versions = ">=3.6" -files = [ - {file = "pyshtools-4.10.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d49f8c963295019fa8a080e97f5ac1ab4c11632f5756553bdc57709c86fee5f4"}, - {file = "pyshtools-4.10.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e3cfcbbde9fb2d896688f6c8ed92279337d8415cd1476c48ea46eb18f8a96ec"}, - {file = "pyshtools-4.10.4-cp310-cp310-win_amd64.whl", hash = "sha256:fe1892d9dfeef323ab14432ee0994fb8799da1755667e0a7dab1f91c30507c4c"}, - {file = "pyshtools-4.10.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3a10e57ded0e948051094d49048c2ce553d28b0d3b63075077a0fdcab30a50f7"}, - {file = "pyshtools-4.10.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:565df0dbf7ec705952d88be1e3fe3a7cc054dcb0d7b663e8debccfa7deab2bdc"}, - {file = "pyshtools-4.10.4-cp311-cp311-win_amd64.whl", hash = "sha256:404f63b9f333c8a0da655d81a5440aa9a29edf68cf8f73e2ab70a933ebb0d350"}, - {file = "pyshtools-4.10.4-cp37-cp37m-win_amd64.whl", hash = "sha256:981ecfcc405c6899eb97a5629e6259f804203ac624cd37a924f06684a17f6955"}, - {file = "pyshtools-4.10.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8609b347ed08a68efa0aab52efad194dbe25da17579ca2536906a8caedb1a4d9"}, - {file = "pyshtools-4.10.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17dc43427107c75649c8a5b0dc626325d6418f5ce48ba322c8cb9a35ea3c0bb0"}, - {file = "pyshtools-4.10.4-cp38-cp38-win_amd64.whl", hash = "sha256:6a14591517f100ebbe70159ccec140ea90c0d90cca1ac24d6c4ca3f15b423449"}, - {file = "pyshtools-4.10.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6d4eb629f425928764f246f9f68ffa39674d3bb89dbeb11e34643920b6ebe3e9"}, - {file = "pyshtools-4.10.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9abcdd31978df9eca944b264242d6891fdc1c7a86a0761a2ebbf2eef78d68184"}, - {file = "pyshtools-4.10.4-cp39-cp39-win_amd64.whl", hash = "sha256:4f5adcb5925c533091711f8ec41a5951b108117203e9f707947eea7ac81d3ef4"}, - {file = "pyshtools-4.10.4.tar.gz", hash = "sha256:4edbee572990603c40f25daf1c8ff5d3429ec1c52343e0118fc2ae28f1d5588a"}, -] - -[package.dependencies] -astropy = ">=4.0" -matplotlib = ">=3.3" -numpy = ">=1.25.2" -pooch = ">=1.1" -requests = "*" -scipy = ">=0.14.0" -tqdm = "*" -xarray = "*" - -[package.extras] -cartopy = ["cartopy (>=0.18.0)", "cython", "pyshp", "shapely", "six"] -ducc = ["ducc0 (>=0.15)"] -palettable = ["palettable (>=3.3)"] -pygmt = ["pygmt (>=0.3)"] - -[[package]] -name = "pytest" -version = "7.4.2" -description = "pytest: simple powerful testing with Python" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pytest-7.4.2-py3-none-any.whl", hash = "sha256:1d881c6124e08ff0a1bb75ba3ec0bfd8b5354a01c194ddd5a0a870a48d99b002"}, - {file = "pytest-7.4.2.tar.gz", hash = "sha256:a766259cfab564a2ad52cb1aae1b881a75c3eb7e34ca3779697c23ed47c47069"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "sys_platform == \"win32\""} -exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} -iniconfig = "*" -packaging = "*" -pluggy = ">=0.12,<2.0" -tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} - -[package.extras] -testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] - -[[package]] -name = "python-dateutil" -version = "2.8.2" -description = "Extensions to the standard Python datetime module" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -files = [ - {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, - {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, -] - -[package.dependencies] -six = ">=1.5" - -[[package]] -name = "pytz" -version = "2023.3.post1" -description = "World timezone definitions, modern and historical" -optional = false -python-versions = "*" -files = [ - {file = "pytz-2023.3.post1-py2.py3-none-any.whl", hash = "sha256:ce42d816b81b68506614c11e8937d3aa9e41007ceb50bfdcb0749b921bf646c7"}, - {file = "pytz-2023.3.post1.tar.gz", hash = "sha256:7b4fddbeb94a1eba4b557da24f19fdf9db575192544270a9101d8509f9f43d7b"}, -] - -[[package]] -name = "pyyaml" -version = "6.0.1" -description = "YAML parser and emitter for Python" -optional = false -python-versions = ">=3.6" -files = [ - {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, - {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, - {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, - {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, - {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, - {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, - {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, - {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, - {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, - {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, - {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, - {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, - {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, - {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, - {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, - {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, - {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, - {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, - {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, - {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, - {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, - {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, - {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, - {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, - {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, - {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, - {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, - {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, - {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, -] - -[[package]] -name = "requests" -version = "2.31.0" -description = "Python HTTP for Humans." -optional = false -python-versions = ">=3.7" -files = [ - {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, - {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, -] - -[package.dependencies] -certifi = ">=2017.4.17" -charset-normalizer = ">=2,<4" -idna = ">=2.5,<4" -urllib3 = ">=1.21.1,<3" - -[package.extras] -socks = ["PySocks (>=1.5.6,!=1.5.7)"] -use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] - -[[package]] -name = "scipy" -version = "1.11.3" -description = "Fundamental algorithms for scientific computing in Python" -optional = false -python-versions = "<3.13,>=3.9" -files = [ - {file = "scipy-1.11.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:370f569c57e1d888304052c18e58f4a927338eafdaef78613c685ca2ea0d1fa0"}, - {file = "scipy-1.11.3-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:9885e3e4f13b2bd44aaf2a1a6390a11add9f48d5295f7a592393ceb8991577a3"}, - {file = "scipy-1.11.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e04aa19acc324a1a076abb4035dabe9b64badb19f76ad9c798bde39d41025cdc"}, - {file = "scipy-1.11.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e1a8a4657673bfae1e05e1e1d6e94b0cabe5ed0c7c144c8aa7b7dbb774ce5c1"}, - {file = "scipy-1.11.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7abda0e62ef00cde826d441485e2e32fe737bdddee3324e35c0e01dee65e2a88"}, - {file = "scipy-1.11.3-cp310-cp310-win_amd64.whl", hash = "sha256:033c3fd95d55012dd1148b201b72ae854d5086d25e7c316ec9850de4fe776929"}, - {file = "scipy-1.11.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:925c6f09d0053b1c0f90b2d92d03b261e889b20d1c9b08a3a51f61afc5f58165"}, - {file = "scipy-1.11.3-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:5664e364f90be8219283eeb844323ff8cd79d7acbd64e15eb9c46b9bc7f6a42a"}, - {file = "scipy-1.11.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00f325434b6424952fbb636506f0567898dca7b0f7654d48f1c382ea338ce9a3"}, - {file = "scipy-1.11.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f290cf561a4b4edfe8d1001ee4be6da60c1c4ea712985b58bf6bc62badee221"}, - {file = "scipy-1.11.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:91770cb3b1e81ae19463b3c235bf1e0e330767dca9eb4cd73ba3ded6c4151e4d"}, - {file = "scipy-1.11.3-cp311-cp311-win_amd64.whl", hash = "sha256:e1f97cd89c0fe1a0685f8f89d85fa305deb3067d0668151571ba50913e445820"}, - {file = "scipy-1.11.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:dfcc1552add7cb7c13fb70efcb2389d0624d571aaf2c80b04117e2755a0c5d15"}, - {file = "scipy-1.11.3-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:0d3a136ae1ff0883fffbb1b05b0b2fea251cb1046a5077d0b435a1839b3e52b7"}, - {file = "scipy-1.11.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bae66a2d7d5768eaa33008fa5a974389f167183c87bf39160d3fefe6664f8ddc"}, - {file = "scipy-1.11.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2f6dee6cbb0e263b8142ed587bc93e3ed5e777f1f75448d24fb923d9fd4dce6"}, - {file = "scipy-1.11.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:74e89dc5e00201e71dd94f5f382ab1c6a9f3ff806c7d24e4e90928bb1aafb280"}, - {file = "scipy-1.11.3-cp312-cp312-win_amd64.whl", hash = "sha256:90271dbde4be191522b3903fc97334e3956d7cfb9cce3f0718d0ab4fd7d8bfd6"}, - {file = "scipy-1.11.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a63d1ec9cadecce838467ce0631c17c15c7197ae61e49429434ba01d618caa83"}, - {file = "scipy-1.11.3-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:5305792c7110e32ff155aed0df46aa60a60fc6e52cd4ee02cdeb67eaccd5356e"}, - {file = "scipy-1.11.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9ea7f579182d83d00fed0e5c11a4aa5ffe01460444219dedc448a36adf0c3917"}, - {file = "scipy-1.11.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c77da50c9a91e23beb63c2a711ef9e9ca9a2060442757dffee34ea41847d8156"}, - {file = "scipy-1.11.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:15f237e890c24aef6891c7d008f9ff7e758c6ef39a2b5df264650eb7900403c0"}, - {file = "scipy-1.11.3-cp39-cp39-win_amd64.whl", hash = "sha256:4b4bb134c7aa457e26cc6ea482b016fef45db71417d55cc6d8f43d799cdf9ef2"}, - {file = "scipy-1.11.3.tar.gz", hash = "sha256:bba4d955f54edd61899776bad459bf7326e14b9fa1c552181f0479cc60a568cd"}, -] - -[package.dependencies] -numpy = ">=1.21.6,<1.28.0" - -[package.extras] -dev = ["click", "cython-lint (>=0.12.2)", "doit (>=0.36.0)", "mypy", "pycodestyle", "pydevtool", "rich-click", "ruff", "types-psutil", "typing_extensions"] -doc = ["jupytext", "matplotlib (>2)", "myst-nb", "numpydoc", "pooch", "pydata-sphinx-theme (==0.9.0)", "sphinx (!=4.1.0)", "sphinx-design (>=0.2.0)"] -test = ["asv", "gmpy2", "mpmath", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] - -[[package]] -name = "setuptools" -version = "68.2.2" -description = "Easily download, build, install, upgrade, and uninstall Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "setuptools-68.2.2-py3-none-any.whl", hash = "sha256:b454a35605876da60632df1a60f736524eb73cc47bbc9f3f1ef1b644de74fd2a"}, - {file = "setuptools-68.2.2.tar.gz", hash = "sha256:4ac1475276d2f1c48684874089fefcd83bd7162ddaafb81fac866ba0db282a87"}, -] - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] -testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.1)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] - -[[package]] -name = "setuptools-scm" -version = "8.0.4" -description = "the blessed package to manage your versions by scm tags" -optional = false -python-versions = ">=3.8" -files = [ - {file = "setuptools-scm-8.0.4.tar.gz", hash = "sha256:b5f43ff6800669595193fd09891564ee9d1d7dcb196cab4b2506d53a2e1c95c7"}, - {file = "setuptools_scm-8.0.4-py3-none-any.whl", hash = "sha256:b47844cd2a84b83b3187a5782c71128c28b4c94cad8bfb871da2784a5cb54c4f"}, -] - -[package.dependencies] -packaging = ">=20" -setuptools = "*" -tomli = {version = ">=1", markers = "python_version < \"3.11\""} -typing-extensions = "*" - -[package.extras] -docs = ["entangled-cli[rich]", "mkdocs", "mkdocs-entangled-plugin", "mkdocs-material", "mkdocstrings[python]", "pygments"] -rich = ["rich"] -test = ["build", "pytest", "rich", "wheel"] - -[[package]] -name = "shapely" -version = "2.0.2" -description = "Manipulation and analysis of geometric objects" -optional = false -python-versions = ">=3.7" -files = [ - {file = "shapely-2.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6ca8cffbe84ddde8f52b297b53f8e0687bd31141abb2c373fd8a9f032df415d6"}, - {file = "shapely-2.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:baa14fc27771e180c06b499a0a7ba697c7988c7b2b6cba9a929a19a4d2762de3"}, - {file = "shapely-2.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:36480e32c434d168cdf2f5e9862c84aaf4d714a43a8465ae3ce8ff327f0affb7"}, - {file = "shapely-2.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ef753200cbffd4f652efb2c528c5474e5a14341a473994d90ad0606522a46a2"}, - {file = "shapely-2.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9a41ff4323fc9d6257759c26eb1cf3a61ebc7e611e024e6091f42977303fd3a"}, - {file = "shapely-2.0.2-cp310-cp310-win32.whl", hash = "sha256:72b5997272ae8c25f0fd5b3b967b3237e87fab7978b8d6cd5fa748770f0c5d68"}, - {file = "shapely-2.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:34eac2337cbd67650248761b140d2535855d21b969d76d76123317882d3a0c1a"}, - {file = "shapely-2.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5b0c052709c8a257c93b0d4943b0b7a3035f87e2d6a8ac9407b6a992d206422f"}, - {file = "shapely-2.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2d217e56ae067e87b4e1731d0dc62eebe887ced729ba5c2d4590e9e3e9fdbd88"}, - {file = "shapely-2.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:94ac128ae2ab4edd0bffcd4e566411ea7bdc738aeaf92c32a8a836abad725f9f"}, - {file = "shapely-2.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fa3ee28f5e63a130ec5af4dc3c4cb9c21c5788bb13c15e89190d163b14f9fb89"}, - {file = "shapely-2.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:737dba15011e5a9b54a8302f1748b62daa207c9bc06f820cd0ad32a041f1c6f2"}, - {file = "shapely-2.0.2-cp311-cp311-win32.whl", hash = "sha256:45ac6906cff0765455a7b49c1670af6e230c419507c13e2f75db638c8fc6f3bd"}, - {file = "shapely-2.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:dc9342fc82e374130db86a955c3c4525bfbf315a248af8277a913f30911bed9e"}, - {file = "shapely-2.0.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:06f193091a7c6112fc08dfd195a1e3846a64306f890b151fa8c63b3e3624202c"}, - {file = "shapely-2.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:eebe544df5c018134f3c23b6515877f7e4cd72851f88a8d0c18464f414d141a2"}, - {file = "shapely-2.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7e92e7c255f89f5cdf777690313311f422aa8ada9a3205b187113274e0135cd8"}, - {file = "shapely-2.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be46d5509b9251dd9087768eaf35a71360de6afac82ce87c636990a0871aa18b"}, - {file = "shapely-2.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a5533a925d8e211d07636ffc2fdd9a7f9f13d54686d00577eeb11d16f00be9c4"}, - {file = "shapely-2.0.2-cp312-cp312-win32.whl", hash = "sha256:084b023dae8ad3d5b98acee9d3bf098fdf688eb0bb9b1401e8b075f6a627b611"}, - {file = "shapely-2.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:ea84d1cdbcf31e619d672b53c4532f06253894185ee7acb8ceb78f5f33cbe033"}, - {file = "shapely-2.0.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:ed1e99702125e7baccf401830a3b94d810d5c70b329b765fe93451fe14cf565b"}, - {file = "shapely-2.0.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e7d897e6bdc6bc64f7f65155dbbb30e49acaabbd0d9266b9b4041f87d6e52b3a"}, - {file = "shapely-2.0.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0521d76d1e8af01e712db71da9096b484f081e539d4f4a8c97342e7971d5e1b4"}, - {file = "shapely-2.0.2-cp37-cp37m-win32.whl", hash = "sha256:5324be299d4c533ecfcfd43424dfd12f9428fd6f12cda38a4316da001d6ef0ea"}, - {file = "shapely-2.0.2-cp37-cp37m-win_amd64.whl", hash = "sha256:78128357a0cee573257a0c2c388d4b7bf13cb7dbe5b3fe5d26d45ebbe2a39e25"}, - {file = "shapely-2.0.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:87dc2be34ac3a3a4a319b963c507ac06682978a5e6c93d71917618b14f13066e"}, - {file = "shapely-2.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:42997ac806e4583dad51c80a32d38570fd9a3d4778f5e2c98f9090aa7db0fe91"}, - {file = "shapely-2.0.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ccfd5fa10a37e67dbafc601c1ddbcbbfef70d34c3f6b0efc866ddbdb55893a6c"}, - {file = "shapely-2.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e7c95d3379ae3abb74058938a9fcbc478c6b2e28d20dace38f8b5c587dde90aa"}, - {file = "shapely-2.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6a21353d28209fb0d8cc083e08ca53c52666e0d8a1f9bbe23b6063967d89ed24"}, - {file = "shapely-2.0.2-cp38-cp38-win32.whl", hash = "sha256:03e63a99dfe6bd3beb8d5f41ec2086585bb969991d603f9aeac335ad396a06d4"}, - {file = "shapely-2.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:c6fd29fbd9cd76350bd5cc14c49de394a31770aed02d74203e23b928f3d2f1aa"}, - {file = "shapely-2.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:1f217d28ecb48e593beae20a0082a95bd9898d82d14b8fcb497edf6bff9a44d7"}, - {file = "shapely-2.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:394e5085b49334fd5b94fa89c086edfb39c3ecab7f669e8b2a4298b9d523b3a5"}, - {file = "shapely-2.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fd3ad17b64466a033848c26cb5b509625c87d07dcf39a1541461cacdb8f7e91c"}, - {file = "shapely-2.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d41a116fcad58048d7143ddb01285e1a8780df6dc1f56c3b1e1b7f12ed296651"}, - {file = "shapely-2.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dea9a0651333cf96ef5bb2035044e3ad6a54f87d90e50fe4c2636debf1b77abc"}, - {file = "shapely-2.0.2-cp39-cp39-win32.whl", hash = "sha256:b8eb0a92f7b8c74f9d8fdd1b40d395113f59bd8132ca1348ebcc1f5aece94b96"}, - {file = "shapely-2.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:794affd80ca0f2c536fc948a3afa90bd8fb61ebe37fe873483ae818e7f21def4"}, - {file = "shapely-2.0.2.tar.gz", hash = "sha256:1713cc04c171baffc5b259ba8531c58acc2a301707b7f021d88a15ed090649e7"}, -] - -[package.dependencies] -numpy = ">=1.14" - -[package.extras] -docs = ["matplotlib", "numpydoc (==1.1.*)", "sphinx", "sphinx-book-theme", "sphinx-remove-toctrees"] -test = ["pytest", "pytest-cov"] - -[[package]] -name = "six" -version = "1.16.0" -description = "Python 2 and 3 compatibility utilities" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, -] - -[[package]] -name = "sympy" -version = "1.12" -description = "Computer algebra system (CAS) in Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "sympy-1.12-py3-none-any.whl", hash = "sha256:c3588cd4295d0c0f603d0f2ae780587e64e2efeedb3521e46b9bb1d08d184fa5"}, - {file = "sympy-1.12.tar.gz", hash = "sha256:ebf595c8dac3e0fdc4152c51878b498396ec7f30e7a914d6071e674d49420fb8"}, -] - -[package.dependencies] -mpmath = ">=0.19" - -[[package]] -name = "tomli" -version = "2.0.1" -description = "A lil' TOML parser" -optional = false -python-versions = ">=3.7" -files = [ - {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, - {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, -] - -[[package]] -name = "torch" -version = "2.1.0" -description = "Tensors and Dynamic neural networks in Python with strong GPU acceleration" -optional = false -python-versions = ">=3.8.0" -files = [ - {file = "torch-2.1.0-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:bf57f8184b2c317ef81fb33dc233ce4d850cd98ef3f4a38be59c7c1572d175db"}, - {file = "torch-2.1.0-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:a04a0296d47f28960f51c18c5489a8c3472f624ec3b5bcc8e2096314df8c3342"}, - {file = "torch-2.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:0bd691efea319b14ef239ede16d8a45c246916456fa3ed4f217d8af679433cc6"}, - {file = "torch-2.1.0-cp310-none-macosx_10_9_x86_64.whl", hash = "sha256:101c139152959cb20ab370fc192672c50093747906ee4ceace44d8dd703f29af"}, - {file = "torch-2.1.0-cp310-none-macosx_11_0_arm64.whl", hash = "sha256:a6b7438a90a870e4cdeb15301519ae6c043c883fcd224d303c5b118082814767"}, - {file = "torch-2.1.0-cp311-cp311-manylinux1_x86_64.whl", hash = "sha256:2224622407ca52611cbc5b628106fde22ed8e679031f5a99ce286629fc696128"}, - {file = "torch-2.1.0-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:8132efb782cd181cc2dcca5e58effbe4217cdb2581206ac71466d535bf778867"}, - {file = "torch-2.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:5c3bfa91ce25ba10116c224c59d5b64cdcce07161321d978bd5a1f15e1ebce72"}, - {file = "torch-2.1.0-cp311-none-macosx_10_9_x86_64.whl", hash = "sha256:601b0a2a9d9233fb4b81f7d47dca9680d4f3a78ca3f781078b6ad1ced8a90523"}, - {file = "torch-2.1.0-cp311-none-macosx_11_0_arm64.whl", hash = "sha256:3cd1dedff13884d890f18eea620184fb4cd8fd3c68ce3300498f427ae93aa962"}, - {file = "torch-2.1.0-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:fb7bf0cc1a3db484eb5d713942a93172f3bac026fcb377a0cd107093d2eba777"}, - {file = "torch-2.1.0-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:761822761fffaa1c18a62c5deb13abaa780862577d3eadc428f1daa632536905"}, - {file = "torch-2.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:458a6d6d8f7d2ccc348ac4d62ea661b39a3592ad15be385bebd0a31ced7e00f4"}, - {file = "torch-2.1.0-cp38-none-macosx_10_9_x86_64.whl", hash = "sha256:c8bf7eaf9514465e5d9101e05195183470a6215bb50295c61b52302a04edb690"}, - {file = "torch-2.1.0-cp38-none-macosx_11_0_arm64.whl", hash = "sha256:05661c32ec14bc3a157193d0f19a7b19d8e61eb787b33353cad30202c295e83b"}, - {file = "torch-2.1.0-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:556d8dd3e0c290ed9d4d7de598a213fb9f7c59135b4fee144364a8a887016a55"}, - {file = "torch-2.1.0-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:de7d63c6ecece118684415a3dbd4805af4a4c1ee1490cccf7405d8c240a481b4"}, - {file = "torch-2.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:2419cf49aaf3b2336c7aa7a54a1b949fa295b1ae36f77e2aecb3a74e3a947255"}, - {file = "torch-2.1.0-cp39-none-macosx_10_9_x86_64.whl", hash = "sha256:6ad491e70dbe4288d17fdbfc7fbfa766d66cbe219bc4871c7a8096f4a37c98df"}, - {file = "torch-2.1.0-cp39-none-macosx_11_0_arm64.whl", hash = "sha256:421739685eba5e0beba42cb649740b15d44b0d565c04e6ed667b41148734a75b"}, -] - -[package.dependencies] -filelock = "*" -fsspec = "*" -jinja2 = "*" -networkx = "*" -sympy = "*" -typing-extensions = "*" - -[package.extras] -opt-einsum = ["opt-einsum (>=3.3)"] - -[[package]] -name = "tqdm" -version = "4.66.1" -description = "Fast, Extensible Progress Meter" -optional = false -python-versions = ">=3.7" -files = [ - {file = "tqdm-4.66.1-py3-none-any.whl", hash = "sha256:d302b3c5b53d47bce91fea46679d9c3c6508cf6332229aa1e7d8653723793386"}, - {file = "tqdm-4.66.1.tar.gz", hash = "sha256:d88e651f9db8d8551a62556d3cff9e3034274ca5d66e93197cf2490e2dcb69c7"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "platform_system == \"Windows\""} - -[package.extras] -dev = ["pytest (>=6)", "pytest-cov", "pytest-timeout", "pytest-xdist"] -notebook = ["ipywidgets (>=6)"] -slack = ["slack-sdk"] -telegram = ["requests"] - -[[package]] -name = "typing-extensions" -version = "4.8.0" -description = "Backported and Experimental Type Hints for Python 3.8+" -optional = false -python-versions = ">=3.8" -files = [ - {file = "typing_extensions-4.8.0-py3-none-any.whl", hash = "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0"}, - {file = "typing_extensions-4.8.0.tar.gz", hash = "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef"}, -] - -[[package]] -name = "tzdata" -version = "2023.3" -description = "Provider of IANA time zone data" -optional = false -python-versions = ">=2" -files = [ - {file = "tzdata-2023.3-py2.py3-none-any.whl", hash = "sha256:7e65763eef3120314099b6939b5546db7adce1e7d6f2e179e3df563c70511eda"}, - {file = "tzdata-2023.3.tar.gz", hash = "sha256:11ef1e08e54acb0d4f95bdb1be05da659673de4acbd21bf9c69e94cc5e907a3a"}, -] - -[[package]] -name = "urllib3" -version = "2.0.7" -description = "HTTP library with thread-safe connection pooling, file post, and more." -optional = false -python-versions = ">=3.7" -files = [ - {file = "urllib3-2.0.7-py3-none-any.whl", hash = "sha256:fdb6d215c776278489906c2f8916e6e7d4f5a9b602ccbcfdf7f016fc8da0596e"}, - {file = "urllib3-2.0.7.tar.gz", hash = "sha256:c97dfde1f7bd43a71c8d2a58e369e9b2bf692d1334ea9f9cae55add7d0dd0f84"}, -] - -[package.extras] -brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] -secure = ["certifi", "cryptography (>=1.9)", "idna (>=2.0.0)", "pyopenssl (>=17.1.0)", "urllib3-secure-extra"] -socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] -zstd = ["zstandard (>=0.18.0)"] - -[[package]] -name = "xarray" -version = "2023.10.1" -description = "N-D labeled arrays and datasets in Python" -optional = false -python-versions = ">=3.9" -files = [ - {file = "xarray-2023.10.1-py3-none-any.whl", hash = "sha256:71ea549e9be6dfeab19c2736acf659967b861aad2397691a80e5fad0c61db2ad"}, - {file = "xarray-2023.10.1.tar.gz", hash = "sha256:9eeee170c3fc2f3321eb6ba40c17ffe4d8c98d49d55e4a3fba66a75bdc7dd9e5"}, -] - -[package.dependencies] -numpy = ">=1.22" -packaging = ">=21.3" -pandas = ">=1.4" - -[package.extras] -accel = ["bottleneck", "flox", "numbagg", "scipy"] -complete = ["xarray[accel,io,parallel,viz]"] -io = ["cftime", "fsspec", "h5netcdf", "netCDF4", "pooch", "pydap", "scipy", "zarr"] -parallel = ["dask[complete]"] -viz = ["matplotlib", "nc-time-axis", "seaborn"] - -[extras] -healpy-support = [] -pytorch-support = [] - -[metadata] -lock-version = "2.0" -python-versions = ">=3.10,<3.13" -content-hash = "0999488f2868769e363292457227ed356e9167576ec5163ca347b800776d1b4d" From f148d18f64a27f5b93c30bda00f17c9b4910f431 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 23 Oct 2023 18:05:33 +0100 Subject: [PATCH 136/232] Test --- pyproject.toml | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index e93c3a90..3897706a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,17 +16,15 @@ pyshtools = "*" beartype = "*" numpy-quaternion = "*" shapely = "*" -torch = { version = "*", optional = true, markers = "extra == 'torch-cpu'" } -torchvision = { version = "*", optional = true, markers = "extra == 'torch-cpu'" } -torchaudio = { version = "*", optional = true, markers = "extra == 'torch-cpu'" } +torch = { version = "2.1.0+cpu", optional = true, markers = "extra == 'pytorch_cpu_support'" } +torchvision = { version = "*", optional = true, markers = "extra == 'pytorch_cpu_support'" } +torchaudio = { version = "2.1.0+cpu", optional = true, markers = "extra == 'pytorch_cpu_support'" } [tool.poetry.extras] healpy_support = ["healpy"] pytorch_support = ["torch", "torchvision", "torchaudio"] -pytorch_cpu_support = ["torch-cpu"] +pytorch_cpu_support = [] [tool.poetry.group.dev.dependencies] healpy = "*" -autopep8 = "^2.0.2" -pytest = "*" -parameterized = "*" \ No newline at end of file +autopep8 = "^2.0 From 26280eac86b6dbb3d2d914cfb5683ec7e8922cc3 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 23 Oct 2023 18:10:09 +0100 Subject: [PATCH 137/232] Try --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 3897706a..ac583be0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,8 +22,8 @@ torchaudio = { version = "2.1.0+cpu", optional = true, markers = "extra == 'pyto [tool.poetry.extras] healpy_support = ["healpy"] -pytorch_support = ["torch", "torchvision", "torchaudio"] -pytorch_cpu_support = [] +pytorch_cpu_support = ["torch", "torchvision", "torchaudio"] +pytorch_support = [] [tool.poetry.group.dev.dependencies] healpy = "*" From 30e1ada54298419890d966cab8d4f0d709d5ce40 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 23 Oct 2023 18:10:41 +0100 Subject: [PATCH 138/232] Try --- pyproject.toml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index ac583be0..6fdef7de 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,4 +27,6 @@ pytorch_support = [] [tool.poetry.group.dev.dependencies] healpy = "*" -autopep8 = "^2.0 +autopep8 = "^2.0.2" +pytest = "*" +parameterized = "*" \ No newline at end of file From 8fdb2185e2bbc49ad292f59e144a37c9c3380dc4 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 23 Oct 2023 18:11:07 +0100 Subject: [PATCH 139/232] Try with pytorch_support = ["torch", "torchvision", "torchaudio"] --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 6fdef7de..13244d9b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,7 +23,7 @@ torchaudio = { version = "2.1.0+cpu", optional = true, markers = "extra == 'pyto [tool.poetry.extras] healpy_support = ["healpy"] pytorch_cpu_support = ["torch", "torchvision", "torchaudio"] -pytorch_support = [] +pytorch_cpu_support = [] [tool.poetry.group.dev.dependencies] healpy = "*" From 2240d4cede7331e120792b027750625f94fdf837 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 23 Oct 2023 18:19:50 +0100 Subject: [PATCH 140/232] Next try for toml --- pyproject.toml | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 13244d9b..885bfe65 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,17 +16,22 @@ pyshtools = "*" beartype = "*" numpy-quaternion = "*" shapely = "*" -torch = { version = "2.1.0+cpu", optional = true, markers = "extra == 'pytorch_cpu_support'" } -torchvision = { version = "*", optional = true, markers = "extra == 'pytorch_cpu_support'" } -torchaudio = { version = "2.1.0+cpu", optional = true, markers = "extra == 'pytorch_cpu_support'" } [tool.poetry.extras] healpy_support = ["healpy"] -pytorch_cpu_support = ["torch", "torchvision", "torchaudio"] -pytorch_cpu_support = [] + +[tool.poetry.group.pytorch_cpu.dependencies] +torch = "2.1.0+cpu" +torchvision = "*" +torchaudio = "2.1.0+cpu" + +[tool.poetry.group.pytorch.dependencies] +torch = "*" +torchvision = "*" +torchaudio = "*" [tool.poetry.group.dev.dependencies] healpy = "*" autopep8 = "^2.0.2" pytest = "*" -parameterized = "*" \ No newline at end of file +parameterized = "*" From 9d6bfca925b2523d084fbb14cf8f1bc36d010e57 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 23 Oct 2023 18:20:53 +0100 Subject: [PATCH 141/232] Next try --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index a9e6865c..639fc06e 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -33,7 +33,7 @@ jobs: poetry env use python # poetry install --extras healpy_support --no-root # skip the project root package # poetry run python -m pip install torch==2.1.0+cpu torchvision torchaudio -f https://download.pytorch.org/whl/cpu - poetry install --extras healpy_support --extras "pytorch_cpu_support" + poetry install --extras "healpy_support" --group pytorch_cpu - name: List files and check Python and package versions run: | From f53861cd54960e6f8473a6a6ccd9476e29edf2af Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 23 Oct 2023 18:34:15 +0100 Subject: [PATCH 142/232] Try --- .github/workflows/tests.yml | 3 ++- pyproject.toml | 14 +++----------- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 639fc06e..00d143e3 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -33,7 +33,8 @@ jobs: poetry env use python # poetry install --extras healpy_support --no-root # skip the project root package # poetry run python -m pip install torch==2.1.0+cpu torchvision torchaudio -f https://download.pytorch.org/whl/cpu - poetry install --extras "healpy_support" --group pytorch_cpu + poetry install --extras "healpy_support" --extras "pytorch_support" + poetry run python -m pip install torch==2.1.0+cpu torchaudio==2.1.0+cpu -f https://download.pytorch.org/whl/torch_stable.html - name: List files and check Python and package versions run: | diff --git a/pyproject.toml b/pyproject.toml index 885bfe65..be9d86b7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ description = "Framework for recursive Bayesian estimation in Python." readme = "README.md" authors = ["Florian Pfaff "] version = "0.5.0" - + [tool.poetry.dependencies] python = ">=3.10,<3.13" numpy = "*" @@ -19,19 +19,11 @@ shapely = "*" [tool.poetry.extras] healpy_support = ["healpy"] - -[tool.poetry.group.pytorch_cpu.dependencies] -torch = "2.1.0+cpu" -torchvision = "*" -torchaudio = "2.1.0+cpu" - -[tool.poetry.group.pytorch.dependencies] -torch = "*" -torchvision = "*" -torchaudio = "*" +pytorch_support = ["torch"] [tool.poetry.group.dev.dependencies] healpy = "*" +torch = "*" autopep8 = "^2.0.2" pytest = "*" parameterized = "*" From a47417e6773ce5bdc9ac33ba33054b8b5af696c8 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 23 Oct 2023 18:41:48 +0100 Subject: [PATCH 143/232] Linter fixes --- .github/workflows/mega-linter.yml | 445 +++++++++--------- .../abstract_dirac_distribution.py | 3 +- .../abstract_orthogonal_basis_distribution.py | 2 +- .../abstract_se3_distribution.py | 1 + ...stom_lin_bounded_cart_prod_distribution.py | 1 - .../abstract_hypercylindrical_distribution.py | 26 +- ...ypersphere_cart_prod_dirac_distribution.py | 2 +- .../circle/circular_dirac_distribution.py | 1 - .../circle/circular_fourier_distribution.py | 1 + .../custom_hyperrectangular_distribution.py | 1 - ...stract_spherical_harmonics_distribution.py | 10 +- .../bingham_distribution.py | 2 +- .../custom_hemispherical_distribution.py | 1 - .../hyperhemispherical_watson_distribution.py | 2 +- .../hyperspherical_dirac_distribution.py | 1 + .../hyperspherical_mixture.py | 1 - ...pherical_harmonics_distribution_complex.py | 1 + .../von_mises_fisher_distribution.py | 1 + .../hypersphere_subset/watson_distribution.py | 1 - .../abstract_hypertoroidal_distribution.py | 1 + .../abstract_linear_distribution.py | 1 + .../nonperiodic/gaussian_mixture.py | 1 - .../nonperiodic/linear_mixture.py | 1 - .../evaluation/determine_all_deviations.py | 1 + .../evaluation/iterate_configs_and_runs.py | 4 +- pyrecest/evaluation/plot_results.py | 1 + pyrecest/filters/global_nearest_neighbor.py | 2 +- pyrecest/filters/wrapped_normal_filter.py | 2 +- pyrecest/sampling/hyperspherical_sampler.py | 47 +- pyrecest/sampling/hypertoroidal_sampler.py | 7 +- ..._abstract_hypercylindrical_distribution.py | 10 +- ...bstract_hyperhemispherical_distribution.py | 1 + ...st_custom_hyperrectangular_distribution.py | 9 +- ...est_hypercylindrical_dirac_distribution.py | 1 + ...hyperhemispherical_uniform_distribution.py | 4 +- .../test_hyperspherical_dirac_distribution.py | 1 + .../test_hyperspherical_mixture.py | 1 + .../test_hypertoroidal_dirac_distribution.py | 11 +- ...pherical_harmonics_distribution_complex.py | 1 + .../test_toroidal_uniform_distribution.py | 1 + .../test_wrapped_normal_distribution.py | 11 +- .../filters/test_global_nearest_neighbor.py | 3 +- pyrecest/tests/test_evaluation_basic.py | 48 +- pyrecest/tests/test_hypertoroidal_sampler.py | 1 + 44 files changed, 324 insertions(+), 350 deletions(-) diff --git a/.github/workflows/mega-linter.yml b/.github/workflows/mega-linter.yml index 2853f1aa..169bd38b 100644 --- a/.github/workflows/mega-linter.yml +++ b/.github/workflows/mega-linter.yml @@ -1,224 +1,223 @@ - --- - # MegaLinter GitHub Action configuration file - # More info at https://megalinter.io - name: MegaLinter - - permissions: - checks: write - pull-requests: write - contents: write - - on: # yamllint disable-line rule:truthy - # Trigger mega-linter at every push. Action will also be visible from Pull Requests to main - push: # Comment this line to trigger action only on pull-requests (not recommended if you don't pay for GH Actions) - pull_request: - branches: [master, main] - - env: # Comment env block if you do not want to apply fixes - # Apply linter fixes configuration - APPLY_FIXES: all # When active, APPLY_FIXES must also be defined as environment variable (in github/workflows/mega-linter.yml or other CI tool) - APPLY_FIXES_EVENT: push # Decide which event triggers application of fixes in a commit or a PR (pull_request, push, all) - # I tried around a lot to make the test workflow run on pull_request events, - # but it it only worked when creating a new PR. By default, this would target the branch of the PR - # and not the main branch. Instead of trying around to cherry-pick the commits from the PR - # etc. I decided to just run the workflow on push events to the main branch and then create - # a PR targeting the main branch. - APPLY_FIXES_MODE: pull_request # If APPLY_FIXES is used, defines if the fixes are directly committed (commit) or posted in a PR (pull_request) - - concurrency: - group: ${{ github.ref }}-${{ github.workflow }} - cancel-in-progress: true - - jobs: - build: - name: MegaLinter - runs-on: ubuntu-latest - permissions: - # Give the default GITHUB_TOKEN write permission to commit and push, comment issues & post new PR - # Remove the ones you do not need - contents: write - issues: write - pull-requests: write - steps: - - name: Checkout Code - uses: actions/checkout@v4 - with: - ref: ${{ github.head_ref }} - fetch-depth: 0 - - - name: Create alpine-wheels folder - run: mkdir alpine-wheels - - - name: Cache wheel directory - id: cache-wheels - uses: actions/cache@v3 - with: - path: ${{ github.workspace }}/alpine-wheels - key: ${{ runner.os }}-alpine-wheels-${{ hashFiles('requirements-dev.txt') }} - restore-keys: | - ${{ runner.os }}-alpine-wheels-${{ hashFiles('requirements-dev.txt') }} - - name: Set up Alpine Linux - if: steps.cache-wheels.outputs.cache-hit != 'true' - uses: jirutka/setup-alpine@v1 - with: # cfitsio, py3-pkgconfig, curl-dev, and zlib for healpy - packages: > - build-base - python3-dev - py3-pip - gfortran - fftw-dev - git - openblas-dev - cmake - geos-dev - cfitsio - py3-pkgconfig - curl-dev - zlib-dev - - name: List workspace - run: ls -l . - - - name: Upgrade pip and install requirements for building - if: steps.cache-wheels.outputs.cache-hit != 'true' - run: | - python -m pip install --upgrade pip - python -m pip install meson-python meson ninja wheel build - shell: alpine.sh {0} - - - name: Remove version settings - if: steps.cache-wheels.outputs.cache-hit != 'true' - run: | - sed 's/==.*//' requirements-dev.txt > requirements-dev_no_version.txt - shell: alpine.sh {0} - - - name: Remove torch entry (unsupported by alpine) - if: steps.cache-wheels.outputs.cache-hit != 'true' - run: | - sed -i '/^torch/d' requirements-dev_no_version.txt - shell: alpine.sh {0} - - - name: Run CMake to find LAPACK - if: steps.cache-wheels.outputs.cache-hit != 'true' - run: | - echo "find_package(LAPACK)" > CMakeLists.txt - echo "if(LAPACK_FOUND)" >> CMakeLists.txt - echo ' message("LAPACK found")' >> CMakeLists.txt - echo ' message("LAPACK include dirs: ${LAPACK_INCLUDE_DIRS}")' >> CMakeLists.txt - echo ' message("LAPACK libraries: ${LAPACK_LIBRARIES}")' >> CMakeLists.txt - echo "else()" >> CMakeLists.txt - echo ' message(FATAL_ERROR "LAPACK not found")' >> CMakeLists.txt - echo "endif()" >> CMakeLists.txt - cmake . - shell: alpine.sh {0} - - - name: Run pkg-config to find LAPACK - if: steps.cache-wheels.outputs.cache-hit != 'true' - run: | - pkg-config --libs --cflags lapack || true - shell: alpine.sh {0} - - - name: Build wheel for pyshtools - if: steps.cache-wheels.outputs.cache-hit != 'true' - run: | - git clone https://github.com/FlorianPfaff/SHTOOLS.git - cd SHTOOLS - git checkout meson - python -m build - cd .. - mv SHTOOLS/dist/*.whl ./alpine-wheels/ - rm -rf SHTOOLS - shell: alpine.sh {0} - - - name: Install required packages and dependencies - if: steps.cache-wheels.outputs.cache-hit != 'true' - run: python -m pip install --find-links=./alpine-wheels -r requirements-dev_no_version.txt - shell: alpine.sh {0} - - - name: Print requirements-dev_no_version.txt - if: steps.cache-wheels.outputs.cache-hit != 'true' - run: cat requirements-dev_no_version.txt - shell: alpine.sh {0} - - - name: Freeze requirements - if: steps.cache-wheels.outputs.cache-hit != 'true' - run: python -m pip freeze > requirements-tmp.txt - shell: alpine.sh {0} - - - name: Download compatible packages - if: steps.cache-wheels.outputs.cache-hit != 'true' - run: | - python -m pip download --find-links=./alpine-wheels -r requirements-tmp.txt -d ./alpine-wheels - shell: alpine.sh {0} - - - name: Build wheels - if: steps.cache-wheels.outputs.cache-hit != 'true' - run: | - cd ./alpine-wheels - for src in *.tar.gz; do - python -m pip wheel "$src" --no-deps --wheel-dir=./ - rm "$src" - done - cd .. - shell: alpine.sh {0} - - - name: List available wheels - run: ls -l ./alpine-wheels - - - name: Clean up temporary files (in case they are generated) - run: rm -rf myenv CMakeFiles CMakeCache.txt cmake_install.cmake Makefile - - # MegaLinter - - name: MegaLinter - id: ml - # You can override MegaLinter flavor used to have faster performances - # More info at https://megalinter.io/latest/configuration/#shared-variables - uses: oxsecurity/megalinter/flavors/python@v7.4.0 - env: - # All available variables are described in documentation - # https://megalinter.io/latest/configuration/#shared-variables - # ADD YOUR CUSTOM ENV VARIABLES HERE OR DEFINE THEM IN A FILE .mega-linter.yml AT THE ROOT OF YOUR REPOSITORY - VALIDATE_ALL_CODEBASE: true # ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} # Validates all source when push on main, else just the git diff with main. Override with true if you always want to lint all sources - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - EMAIL_REPORTER_SMTP_PASSWORD: ${{ secrets.SMTP_PASSWORD }} - - # Upload MegaLinter artifacts - - name: Archive production artifacts - if: always() - uses: actions/upload-artifact@v3 - with: - name: MegaLinter reports - path: | - megalinter-reports - mega-linter.log - # Create Pull Request step - - name: Create Pull Request with applied fixes - id: cpr - if: github.ref == 'refs/heads/main' && steps.ml.outputs.has_updated_sources == 1 && (env.APPLY_FIXES_EVENT == 'all' || env.APPLY_FIXES_EVENT == github.event_name) && env.APPLY_FIXES_MODE == 'pull_request' && (github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository) && !contains(github.event.head_commit.message, 'skip fix') - uses: peter-evans/create-pull-request@v5 - with: - token: ${{ secrets.PAT || secrets.GITHUB_TOKEN }} - commit-message: "[MegaLinter] Apply linters automatic fixes" - title: "[MegaLinter] Apply linters automatic fixes" - branch: megalinter-fixes - labels: bot - base: main - - # Output PR details - - name: Create PR output - if: github.ref == 'refs/heads/main' && steps.ml.outputs.has_updated_sources == 1 && (env.APPLY_FIXES_EVENT == 'all' || env.APPLY_FIXES_EVENT == github.event_name) && env.APPLY_FIXES_MODE == 'pull_request' && (github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository) && !contains(github.event.head_commit.message, 'skip fix') - run: | - echo "Pull Request Number - ${{ steps.cpr.outputs.pull-request-number }}" - echo "Pull Request URL - ${{ steps.cpr.outputs.pull-request-url }}" - # Push new commit if applicable (for now works only on PR from same repository, not from forks) - - name: Prepare commit - if: steps.ml.outputs.has_updated_sources == 1 && (env.APPLY_FIXES_EVENT == 'all' || env.APPLY_FIXES_EVENT == github.event_name) && env.APPLY_FIXES_MODE == 'commit' && github.ref != 'refs/heads/main' && (github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository) && !contains(github.event.head_commit.message, 'skip fix') - run: sudo chown -Rc $UID .git/ - - name: Commit and push applied linter fixes - if: steps.ml.outputs.has_updated_sources == 1 && (env.APPLY_FIXES_EVENT == 'all' || env.APPLY_FIXES_EVENT == github.event_name) && env.APPLY_FIXES_MODE == 'commit' && github.ref != 'refs/heads/main' && (github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository) && !contains(github.event.head_commit.message, 'skip fix') - uses: stefanzweifel/git-auto-commit-action@v4 - with: - branch: ${{ github.event.pull_request.head.ref || github.head_ref || github.ref }} - commit_message: "[MegaLinter] Apply linters fixes" - commit_user_name: megalinter-bot - commit_user_email: megalinter-bot@iar.kit.edu \ No newline at end of file +# MegaLinter GitHub Action configuration file +# More info at https://megalinter.io +name: MegaLinter + +permissions: + checks: write + pull-requests: write + contents: write + +on: # yamllint disable-line rule:truthy + # Trigger mega-linter at every push. Action will also be visible from Pull Requests to main + push: # Comment this line to trigger action only on pull-requests (not recommended if you don't pay for GH Actions) + pull_request: + branches: [master, main] + +env: # Comment env block if you do not want to apply fixes + # Apply linter fixes configuration + APPLY_FIXES: all # When active, APPLY_FIXES must also be defined as environment variable (in github/workflows/mega-linter.yml or other CI tool) + APPLY_FIXES_EVENT: push # Decide which event triggers application of fixes in a commit or a PR (pull_request, push, all) + # I tried around a lot to make the test workflow run on pull_request events, + # but it it only worked when creating a new PR. By default, this would target the branch of the PR + # and not the main branch. Instead of trying around to cherry-pick the commits from the PR + # etc. I decided to just run the workflow on push events to the main branch and then create + # a PR targeting the main branch. + APPLY_FIXES_MODE: pull_request # If APPLY_FIXES is used, defines if the fixes are directly committed (commit) or posted in a PR (pull_request) + +concurrency: + group: ${{ github.ref }}-${{ github.workflow }} + cancel-in-progress: true + +jobs: + build: + name: MegaLinter + runs-on: ubuntu-latest + permissions: + # Give the default GITHUB_TOKEN write permission to commit and push, comment issues & post new PR + # Remove the ones you do not need + contents: write + issues: write + pull-requests: write + steps: + - name: Checkout Code + uses: actions/checkout@v4 + with: + ref: ${{ github.head_ref }} + fetch-depth: 0 + + - name: Create alpine-wheels folder + run: mkdir alpine-wheels + + - name: Cache wheel directory + id: cache-wheels + uses: actions/cache@v3 + with: + path: ${{ github.workspace }}/alpine-wheels + key: ${{ runner.os }}-alpine-wheels-${{ hashFiles('requirements-dev.txt') }} + restore-keys: | + ${{ runner.os }}-alpine-wheels-${{ hashFiles('requirements-dev.txt') }} + - name: Set up Alpine Linux + if: steps.cache-wheels.outputs.cache-hit != 'true' + uses: jirutka/setup-alpine@v1 + with: # cfitsio, py3-pkgconfig, curl-dev, and zlib for healpy + packages: > + build-base + python3-dev + py3-pip + gfortran + fftw-dev + git + openblas-dev + cmake + geos-dev + cfitsio + py3-pkgconfig + curl-dev + zlib-dev + - name: List workspace + run: ls -l . + + - name: Upgrade pip and install requirements for building + if: steps.cache-wheels.outputs.cache-hit != 'true' + run: | + python -m pip install --upgrade pip + python -m pip install meson-python meson ninja wheel build + shell: alpine.sh {0} + + - name: Remove version settings + if: steps.cache-wheels.outputs.cache-hit != 'true' + run: | + sed 's/==.*//' requirements-dev.txt > requirements-dev_no_version.txt + shell: alpine.sh {0} + + - name: Remove torch entry (unsupported by alpine) + if: steps.cache-wheels.outputs.cache-hit != 'true' + run: | + sed -i '/^torch/d' requirements-dev_no_version.txt + shell: alpine.sh {0} + + - name: Run CMake to find LAPACK + if: steps.cache-wheels.outputs.cache-hit != 'true' + run: | + echo "find_package(LAPACK)" > CMakeLists.txt + echo "if(LAPACK_FOUND)" >> CMakeLists.txt + echo ' message("LAPACK found")' >> CMakeLists.txt + echo ' message("LAPACK include dirs: ${LAPACK_INCLUDE_DIRS}")' >> CMakeLists.txt + echo ' message("LAPACK libraries: ${LAPACK_LIBRARIES}")' >> CMakeLists.txt + echo "else()" >> CMakeLists.txt + echo ' message(FATAL_ERROR "LAPACK not found")' >> CMakeLists.txt + echo "endif()" >> CMakeLists.txt + cmake . + shell: alpine.sh {0} + + - name: Run pkg-config to find LAPACK + if: steps.cache-wheels.outputs.cache-hit != 'true' + run: | + pkg-config --libs --cflags lapack || true + shell: alpine.sh {0} + + - name: Build wheel for pyshtools + if: steps.cache-wheels.outputs.cache-hit != 'true' + run: | + git clone https://github.com/FlorianPfaff/SHTOOLS.git + cd SHTOOLS + git checkout meson + python -m build + cd .. + mv SHTOOLS/dist/*.whl ./alpine-wheels/ + rm -rf SHTOOLS + shell: alpine.sh {0} + + - name: Install required packages and dependencies + if: steps.cache-wheels.outputs.cache-hit != 'true' + run: python -m pip install --find-links=./alpine-wheels -r requirements-dev_no_version.txt + shell: alpine.sh {0} + + - name: Print requirements-dev_no_version.txt + if: steps.cache-wheels.outputs.cache-hit != 'true' + run: cat requirements-dev_no_version.txt + shell: alpine.sh {0} + + - name: Freeze requirements + if: steps.cache-wheels.outputs.cache-hit != 'true' + run: python -m pip freeze > requirements-tmp.txt + shell: alpine.sh {0} + + - name: Download compatible packages + if: steps.cache-wheels.outputs.cache-hit != 'true' + run: | + python -m pip download --find-links=./alpine-wheels -r requirements-tmp.txt -d ./alpine-wheels + shell: alpine.sh {0} + + - name: Build wheels + if: steps.cache-wheels.outputs.cache-hit != 'true' + run: | + cd ./alpine-wheels + for src in *.tar.gz; do + python -m pip wheel "$src" --no-deps --wheel-dir=./ + rm "$src" + done + cd .. + shell: alpine.sh {0} + + - name: List available wheels + run: ls -l ./alpine-wheels + + - name: Clean up temporary files (in case they are generated) + run: rm -rf myenv CMakeFiles CMakeCache.txt cmake_install.cmake Makefile + + # MegaLinter + - name: MegaLinter + id: ml + # You can override MegaLinter flavor used to have faster performances + # More info at https://megalinter.io/latest/configuration/#shared-variables + uses: oxsecurity/megalinter/flavors/python@v7.4.0 + env: + # All available variables are described in documentation + # https://megalinter.io/latest/configuration/#shared-variables + # ADD YOUR CUSTOM ENV VARIABLES HERE OR DEFINE THEM IN A FILE .mega-linter.yml AT THE ROOT OF YOUR REPOSITORY + VALIDATE_ALL_CODEBASE: true # ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} # Validates all source when push on main, else just the git diff with main. Override with true if you always want to lint all sources + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + EMAIL_REPORTER_SMTP_PASSWORD: ${{ secrets.SMTP_PASSWORD }} + + # Upload MegaLinter artifacts + - name: Archive production artifacts + if: always() + uses: actions/upload-artifact@v3 + with: + name: MegaLinter reports + path: | + megalinter-reports + mega-linter.log + # Create Pull Request step + - name: Create Pull Request with applied fixes + id: cpr + if: github.ref == 'refs/heads/main' && steps.ml.outputs.has_updated_sources == 1 && (env.APPLY_FIXES_EVENT == 'all' || env.APPLY_FIXES_EVENT == github.event_name) && env.APPLY_FIXES_MODE == 'pull_request' && (github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository) && !contains(github.event.head_commit.message, 'skip fix') + uses: peter-evans/create-pull-request@v5 + with: + token: ${{ secrets.PAT || secrets.GITHUB_TOKEN }} + commit-message: "[MegaLinter] Apply linters automatic fixes" + title: "[MegaLinter] Apply linters automatic fixes" + branch: megalinter-fixes + labels: bot + base: main + + # Output PR details + - name: Create PR output + if: github.ref == 'refs/heads/main' && steps.ml.outputs.has_updated_sources == 1 && (env.APPLY_FIXES_EVENT == 'all' || env.APPLY_FIXES_EVENT == github.event_name) && env.APPLY_FIXES_MODE == 'pull_request' && (github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository) && !contains(github.event.head_commit.message, 'skip fix') + run: | + echo "Pull Request Number - ${{ steps.cpr.outputs.pull-request-number }}" + echo "Pull Request URL - ${{ steps.cpr.outputs.pull-request-url }}" + # Push new commit if applicable (for now works only on PR from same repository, not from forks) + - name: Prepare commit + if: steps.ml.outputs.has_updated_sources == 1 && (env.APPLY_FIXES_EVENT == 'all' || env.APPLY_FIXES_EVENT == github.event_name) && env.APPLY_FIXES_MODE == 'commit' && github.ref != 'refs/heads/main' && (github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository) && !contains(github.event.head_commit.message, 'skip fix') + run: sudo chown -Rc $UID .git/ + - name: Commit and push applied linter fixes + if: steps.ml.outputs.has_updated_sources == 1 && (env.APPLY_FIXES_EVENT == 'all' || env.APPLY_FIXES_EVENT == github.event_name) && env.APPLY_FIXES_MODE == 'commit' && github.ref != 'refs/heads/main' && (github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository) && !contains(github.event.head_commit.message, 'skip fix') + uses: stefanzweifel/git-auto-commit-action@v4 + with: + branch: ${{ github.event.pull_request.head.ref || github.head_ref || github.ref }} + commit_message: "[MegaLinter] Apply linters fixes" + commit_user_name: megalinter-bot + commit_user_email: megalinter-bot@iar.kit.edu diff --git a/pyrecest/distributions/abstract_dirac_distribution.py b/pyrecest/distributions/abstract_dirac_distribution.py index a6fe7f56..62011770 100644 --- a/pyrecest/distributions/abstract_dirac_distribution.py +++ b/pyrecest/distributions/abstract_dirac_distribution.py @@ -5,7 +5,7 @@ # pylint: disable=redefined-builtin from pyrecest.backend import ( - amax, + all, apply_along_axis, int32, int64, @@ -14,7 +14,6 @@ ones, random, sum, - all, ) from .abstract_distribution_type import AbstractDistributionType diff --git a/pyrecest/distributions/abstract_orthogonal_basis_distribution.py b/pyrecest/distributions/abstract_orthogonal_basis_distribution.py index 15aba14c..48f236f5 100644 --- a/pyrecest/distributions/abstract_orthogonal_basis_distribution.py +++ b/pyrecest/distributions/abstract_orthogonal_basis_distribution.py @@ -3,7 +3,7 @@ from abc import abstractmethod # pylint: disable=redefined-builtin -from pyrecest.backend import exp, imag, real, all +from pyrecest.backend import all, exp, imag, real from .abstract_distribution_type import AbstractDistributionType diff --git a/pyrecest/distributions/abstract_se3_distribution.py b/pyrecest/distributions/abstract_se3_distribution.py index 92304847..a5ff92a7 100644 --- a/pyrecest/distributions/abstract_se3_distribution.py +++ b/pyrecest/distributions/abstract_se3_distribution.py @@ -53,6 +53,7 @@ def plot_state( @staticmethod def plot_point(se3point): # pylint: disable=too-many-locals import numpy as _np + """Visualize just a point in the SE(3) domain (no uncertainties are considered)""" q = _np.quaternion(*se3point[:4]) rotMat = quaternion.as_rotation_matrix(q) diff --git a/pyrecest/distributions/cart_prod/abstract_custom_lin_bounded_cart_prod_distribution.py b/pyrecest/distributions/cart_prod/abstract_custom_lin_bounded_cart_prod_distribution.py index e881967f..d51a8bff 100644 --- a/pyrecest/distributions/cart_prod/abstract_custom_lin_bounded_cart_prod_distribution.py +++ b/pyrecest/distributions/cart_prod/abstract_custom_lin_bounded_cart_prod_distribution.py @@ -1,6 +1,5 @@ from typing import Callable - from ..abstract_custom_distribution import AbstractCustomDistribution from .abstract_lin_periodic_cart_prod_distribution import ( AbstractLinPeriodicCartProdDistribution, diff --git a/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py b/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py index 4efc6a8c..cd833cc2 100644 --- a/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py +++ b/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py @@ -4,6 +4,7 @@ import scipy.integrate import scipy.optimize + # pylint: disable=redefined-builtin from pyrecest.backend import ( allclose, @@ -130,17 +131,26 @@ def linear_covariance_numerical(self, approximate_mean=None): ) elif self.bound_dim == 1 and self.lin_dim == 2: range_list = [ - [0.0, 2.0 * pi], - [-float("inf"), float("inf")], - [-float("inf"), float("inf")], + [0.0, 2.0 * pi], + [-float("inf"), float("inf")], + [-float("inf"), float("inf")], ] C = empty((2, 2)) - C[0, 0], _ = nquad(lambda x, y, z: (y - approximate_mean[0]) ** 2 * self.pdf([x, y, z]), range_list) - C[0, 1], _ = nquad(lambda x, y, z: (y - approximate_mean[0]) - * (z - approximate_mean[1]) - * self.pdf([x, y, z]), range_list) + C[0, 0], _ = nquad( + lambda x, y, z: (y - approximate_mean[0]) ** 2 * self.pdf([x, y, z]), + range_list, + ) + C[0, 1], _ = nquad( + lambda x, y, z: (y - approximate_mean[0]) + * (z - approximate_mean[1]) + * self.pdf([x, y, z]), + range_list, + ) C[1, 0] = C[0, 1] - C[1, 1], _ = nquad(lambda x, y, z: (z - approximate_mean[1]) ** 2 * self.pdf([x, y, z]), range_list) + C[1, 1], _ = nquad( + lambda x, y, z: (z - approximate_mean[1]) ** 2 * self.pdf([x, y, z]), + range_list, + ) else: raise ValueError("Cannot determine linear covariance for this dimension.") diff --git a/pyrecest/distributions/cart_prod/lin_hypersphere_cart_prod_dirac_distribution.py b/pyrecest/distributions/cart_prod/lin_hypersphere_cart_prod_dirac_distribution.py index 5857a1c2..8611b7fb 100644 --- a/pyrecest/distributions/cart_prod/lin_hypersphere_cart_prod_dirac_distribution.py +++ b/pyrecest/distributions/cart_prod/lin_hypersphere_cart_prod_dirac_distribution.py @@ -1,4 +1,4 @@ -from pyrecest.backend import abs, max, linalg +from pyrecest.backend import abs, linalg, max from ..abstract_se3_distribution import AbstractSE3Distribution from .lin_bounded_cart_prod_dirac_distribution import ( diff --git a/pyrecest/distributions/circle/circular_dirac_distribution.py b/pyrecest/distributions/circle/circular_dirac_distribution.py index 494d85d1..79859ae3 100644 --- a/pyrecest/distributions/circle/circular_dirac_distribution.py +++ b/pyrecest/distributions/circle/circular_dirac_distribution.py @@ -1,4 +1,3 @@ - from ..hypertorus.hypertoroidal_dirac_distribution import HypertoroidalDiracDistribution from .abstract_circular_distribution import AbstractCircularDistribution diff --git a/pyrecest/distributions/circle/circular_fourier_distribution.py b/pyrecest/distributions/circle/circular_fourier_distribution.py index 3f4aa914..ad59a7ab 100644 --- a/pyrecest/distributions/circle/circular_fourier_distribution.py +++ b/pyrecest/distributions/circle/circular_fourier_distribution.py @@ -3,6 +3,7 @@ from typing import Union import matplotlib.pyplot as plt + # pylint: disable=redefined-builtin from pyrecest.backend import ( arange, diff --git a/pyrecest/distributions/custom_hyperrectangular_distribution.py b/pyrecest/distributions/custom_hyperrectangular_distribution.py index ffe0de5c..21e5c7ee 100644 --- a/pyrecest/distributions/custom_hyperrectangular_distribution.py +++ b/pyrecest/distributions/custom_hyperrectangular_distribution.py @@ -1,6 +1,5 @@ from collections.abc import Callable - from .abstract_custom_nonperiodic_distribution import ( AbstractCustomNonPeriodicDistribution, ) diff --git a/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py index e9371a8e..503dac6c 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py @@ -2,15 +2,7 @@ import warnings from math import pi -from pyrecest.backend import ( - abs, - atleast_2d, - imag, - isnan, - real, - sqrt, - zeros, -) +from pyrecest.backend import abs, atleast_2d, imag, isnan, real, sqrt, zeros from scipy.linalg import norm from ..abstract_orthogonal_basis_distribution import AbstractOrthogonalBasisDistribution diff --git a/pyrecest/distributions/hypersphere_subset/bingham_distribution.py b/pyrecest/distributions/hypersphere_subset/bingham_distribution.py index 5f4dc1da..eed9ed96 100644 --- a/pyrecest/distributions/hypersphere_subset/bingham_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/bingham_distribution.py @@ -1,7 +1,7 @@ from math import pi # pylint: disable=redefined-builtin -from pyrecest.backend import all, abs, max, diag, exp, eye, linalg, sum, zeros, argsort +from pyrecest.backend import abs, all, argsort, diag, exp, eye, linalg, max, sum, zeros from scipy.integrate import quad from scipy.special import iv diff --git a/pyrecest/distributions/hypersphere_subset/custom_hemispherical_distribution.py b/pyrecest/distributions/hypersphere_subset/custom_hemispherical_distribution.py index e8ef0b1a..fb691191 100644 --- a/pyrecest/distributions/hypersphere_subset/custom_hemispherical_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/custom_hemispherical_distribution.py @@ -1,7 +1,6 @@ import warnings from collections.abc import Callable - from .abstract_hemispherical_distribution import AbstractHemisphericalDistribution from .abstract_hyperhemispherical_distribution import ( AbstractHyperhemisphericalDistribution, diff --git a/pyrecest/distributions/hypersphere_subset/hyperhemispherical_watson_distribution.py b/pyrecest/distributions/hypersphere_subset/hyperhemispherical_watson_distribution.py index c4b1f83e..fd87f85d 100644 --- a/pyrecest/distributions/hypersphere_subset/hyperhemispherical_watson_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/hyperhemispherical_watson_distribution.py @@ -1,6 +1,6 @@ from typing import Union -from pyrecest.backend import allclose, int32, int64, zeros, concatenate, array +from pyrecest.backend import allclose, array, concatenate, int32, int64, zeros from .abstract_hyperhemispherical_distribution import ( AbstractHyperhemisphericalDistribution, diff --git a/pyrecest/distributions/hypersphere_subset/hyperspherical_dirac_distribution.py b/pyrecest/distributions/hypersphere_subset/hyperspherical_dirac_distribution.py index 4ac972d7..b4511732 100644 --- a/pyrecest/distributions/hypersphere_subset/hyperspherical_dirac_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/hyperspherical_dirac_distribution.py @@ -1,4 +1,5 @@ import matplotlib.pyplot as plt + # pylint: disable=redefined-builtin from pyrecest.backend import linalg, reshape, sum diff --git a/pyrecest/distributions/hypersphere_subset/hyperspherical_mixture.py b/pyrecest/distributions/hypersphere_subset/hyperspherical_mixture.py index 82e0bcfc..f5177f92 100644 --- a/pyrecest/distributions/hypersphere_subset/hyperspherical_mixture.py +++ b/pyrecest/distributions/hypersphere_subset/hyperspherical_mixture.py @@ -1,4 +1,3 @@ - from ..abstract_mixture import AbstractMixture from .abstract_hyperspherical_distribution import AbstractHypersphericalDistribution diff --git a/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py b/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py index 577cc315..79d121f9 100644 --- a/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py +++ b/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py @@ -1,6 +1,7 @@ from math import pi import scipy + # pylint: disable=redefined-builtin from pyrecest.backend import ( abs, diff --git a/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py b/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py index deeda7bb..a55065c3 100644 --- a/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py @@ -2,6 +2,7 @@ from typing import Union import pyrecest.backend + # pylint: disable=redefined-builtin from pyrecest.backend import ( abs, diff --git a/pyrecest/distributions/hypersphere_subset/watson_distribution.py b/pyrecest/distributions/hypersphere_subset/watson_distribution.py index 4118004c..3c61a100 100644 --- a/pyrecest/distributions/hypersphere_subset/watson_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/watson_distribution.py @@ -1,4 +1,3 @@ - import mpmath import numpy.testing as npt from pyrecest.backend import ( diff --git a/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py b/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py index d95a3274..4d9e2ccc 100644 --- a/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py +++ b/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py @@ -4,6 +4,7 @@ import matplotlib.pyplot as plt import pyrecest.backend + # pylint: disable=redefined-builtin from pyrecest.backend import ( abs, diff --git a/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py b/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py index 8e15210c..307fe477 100644 --- a/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py +++ b/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py @@ -3,6 +3,7 @@ import matplotlib.pyplot as plt import pyrecest.backend + # pylint: disable=redefined-builtin from pyrecest.backend import ( array, diff --git a/pyrecest/distributions/nonperiodic/gaussian_mixture.py b/pyrecest/distributions/nonperiodic/gaussian_mixture.py index fa5a3bb9..8a5413e9 100644 --- a/pyrecest/distributions/nonperiodic/gaussian_mixture.py +++ b/pyrecest/distributions/nonperiodic/gaussian_mixture.py @@ -1,4 +1,3 @@ - # pylint: disable=redefined-builtin from pyrecest.backend import array, dot, ones, stack, sum diff --git a/pyrecest/distributions/nonperiodic/linear_mixture.py b/pyrecest/distributions/nonperiodic/linear_mixture.py index 68898780..b083bc6f 100644 --- a/pyrecest/distributions/nonperiodic/linear_mixture.py +++ b/pyrecest/distributions/nonperiodic/linear_mixture.py @@ -1,6 +1,5 @@ import warnings - from ..abstract_mixture import AbstractMixture from .abstract_linear_distribution import AbstractLinearDistribution from .gaussian_distribution import GaussianDistribution diff --git a/pyrecest/evaluation/determine_all_deviations.py b/pyrecest/evaluation/determine_all_deviations.py index 22f53637..70218901 100644 --- a/pyrecest/evaluation/determine_all_deviations.py +++ b/pyrecest/evaluation/determine_all_deviations.py @@ -2,6 +2,7 @@ from typing import Callable import numpy as np + # pylint: disable=redefined-builtin from pyrecest.backend import any, empty, isinf, ndim, sum diff --git a/pyrecest/evaluation/iterate_configs_and_runs.py b/pyrecest/evaluation/iterate_configs_and_runs.py index 387a2b0c..36cc0f4d 100644 --- a/pyrecest/evaluation/iterate_configs_and_runs.py +++ b/pyrecest/evaluation/iterate_configs_and_runs.py @@ -1,9 +1,7 @@ -from pyrecest.backend import empty -from pyrecest.backend import zeros import warnings from typing import Any, Dict - +from pyrecest.backend import empty, zeros from .perform_predict_update_cycles import perform_predict_update_cycles diff --git a/pyrecest/evaluation/plot_results.py b/pyrecest/evaluation/plot_results.py index 7fe35f8f..49996f46 100644 --- a/pyrecest/evaluation/plot_results.py +++ b/pyrecest/evaluation/plot_results.py @@ -1,6 +1,7 @@ import warnings import matplotlib.pyplot as plt + # pylint: disable=redefined-builtin from pyrecest.backend import any, array, isnan, ones, shape diff --git a/pyrecest/filters/global_nearest_neighbor.py b/pyrecest/filters/global_nearest_neighbor.py index 8962d465..945edf8c 100644 --- a/pyrecest/filters/global_nearest_neighbor.py +++ b/pyrecest/filters/global_nearest_neighbor.py @@ -1,5 +1,5 @@ # pylint: disable=redefined-builtin -from pyrecest.backend import empty, full, repeat, squeeze, stack, all +from pyrecest.backend import all, empty, full, repeat, squeeze, stack from scipy.optimize import linear_sum_assignment from scipy.spatial.distance import cdist from scipy.stats import chi2 diff --git a/pyrecest/filters/wrapped_normal_filter.py b/pyrecest/filters/wrapped_normal_filter.py index 021cd902..742fd9db 100644 --- a/pyrecest/filters/wrapped_normal_filter.py +++ b/pyrecest/filters/wrapped_normal_filter.py @@ -2,7 +2,7 @@ from functools import partial from math import pi -from pyrecest.backend import max, min, array, log, mod +from pyrecest.backend import array, log, max, min, mod from pyrecest.distributions import CircularDiracDistribution, WrappedNormalDistribution from pyrecest.filters.abstract_circular_filter import AbstractCircularFilter diff --git a/pyrecest/sampling/hyperspherical_sampler.py b/pyrecest/sampling/hyperspherical_sampler.py index 82169240..cbc45f97 100644 --- a/pyrecest/sampling/hyperspherical_sampler.py +++ b/pyrecest/sampling/hyperspherical_sampler.py @@ -1,20 +1,20 @@ -from math import pi -from pyrecest.backend import vstack -from pyrecest.backend import sqrt -from pyrecest.backend import sin -from pyrecest.backend import cos -from pyrecest.backend import array -from pyrecest.backend import arctan2 -from pyrecest.backend import arccos -from pyrecest.backend import arange -from pyrecest.backend import empty -from pyrecest.backend import column_stack -from pyrecest.backend import deg2rad import itertools from abc import abstractmethod +from math import pi - -from beartype import beartype +from pyrecest.backend import ( + arange, + arccos, + arctan2, + array, + column_stack, + cos, + deg2rad, + empty, + sin, + sqrt, + vstack, +) from pyrecest.distributions import ( AbstractSphericalDistribution, HypersphericalUniformDistribution, @@ -70,12 +70,15 @@ def sample_stochastic( class AbstractSphericalCoordinatesBasedSampler(AbstractSphericalUniformSampler): @abstractmethod def get_grid_spherical_coordinates( - self, grid_density_parameter: int, + self, + grid_density_parameter: int, ): raise NotImplementedError() def get_grid(self, grid_density_parameter: int, dim: int = 2): - assert dim == 2, "AbstractSphericalCoordinatesBasedSampler is supposed to be used for the circle (which is one-dimensional) only." + assert ( + dim == 2 + ), "AbstractSphericalCoordinatesBasedSampler is supposed to be used for the circle (which is one-dimensional) only." phi, theta, grid_specific_description = self.get_grid_spherical_coordinates( grid_density_parameter ) @@ -103,9 +106,7 @@ def get_grid(self, grid_density_parameter: int): class DriscollHealySampler(AbstractSphericalCoordinatesBasedSampler): - def get_grid_spherical_coordinates( - self, grid_density_parameter: int - ): + def get_grid_spherical_coordinates(self, grid_density_parameter: int): import pyshtools as pysh grid = pysh.SHGrid.from_zeros(grid_density_parameter) @@ -133,9 +134,7 @@ def get_grid_spherical_coordinates( class SphericalFibonacciSampler(AbstractSphericalCoordinatesBasedSampler): - def get_grid_spherical_coordinates( - self, grid_density_parameter: int - ): + def get_grid_spherical_coordinates(self, grid_density_parameter: int): indices = arange(0, grid_density_parameter, dtype=float) + 0.5 phi = pi * (1 + 5**0.5) * indices theta = arccos(1 - 2 * indices / grid_density_parameter) @@ -240,9 +239,7 @@ def get_grid(self, grid_density_parameter: int | list[int]): phi, theta, _ = spherical_sampler.get_grid_spherical_coordinates( grid_density_parameter[0] ) - spherical_points = column_stack( - (theta, phi) - ) # stack to match expected shape + spherical_points = column_stack((theta, phi)) # stack to match expected shape # Step 2: Discretize the unit circle using the circular grid circular_sampler = CircularUniformSampler() diff --git a/pyrecest/sampling/hypertoroidal_sampler.py b/pyrecest/sampling/hypertoroidal_sampler.py index 8f358451..df38309b 100644 --- a/pyrecest/sampling/hypertoroidal_sampler.py +++ b/pyrecest/sampling/hypertoroidal_sampler.py @@ -1,7 +1,6 @@ from math import pi -from pyrecest.backend import linspace -from beartype import beartype +from pyrecest.backend import linspace from pyrecest.distributions import CircularUniformDistribution from .abstract_sampler import AbstractSampler @@ -17,7 +16,9 @@ class AbstractCircularSampler(AbstractHypertoroidalSampler): class CircularUniformSampler(AbstractCircularSampler): def sample_stochastic(self, n_samples: int, dim: int): - assert dim == 1, "CircularUniformSampler is supposed to be used for the circle (which is one-dimensional) only." + assert ( + dim == 1 + ), "CircularUniformSampler is supposed to be used for the circle (which is one-dimensional) only." return CircularUniformDistribution().sample(n_samples) def get_grid(self, grid_density_parameter: int): diff --git a/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py b/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py index 177b6631..68248b84 100644 --- a/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py @@ -3,15 +3,7 @@ import numpy.testing as npt import pyrecest.backend -from pyrecest.backend import ( - allclose, - arange, - array, - column_stack, - diff, - ones, - zeros, -) +from pyrecest.backend import allclose, arange, array, column_stack, diff, ones, zeros from pyrecest.distributions.cart_prod.partially_wrapped_normal_distribution import ( PartiallyWrappedNormalDistribution, ) diff --git a/pyrecest/tests/distributions/test_abstract_hyperhemispherical_distribution.py b/pyrecest/tests/distributions/test_abstract_hyperhemispherical_distribution.py index 2fb2288d..34cdcc0c 100644 --- a/pyrecest/tests/distributions/test_abstract_hyperhemispherical_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hyperhemispherical_distribution.py @@ -2,6 +2,7 @@ from math import pi import numpy.testing as npt + # pylint: disable=redefined-builtin from pyrecest.backend import array, linalg, ones, sum from pyrecest.distributions import ( diff --git a/pyrecest/tests/distributions/test_custom_hyperrectangular_distribution.py b/pyrecest/tests/distributions/test_custom_hyperrectangular_distribution.py index 95001bd0..911cb4ed 100644 --- a/pyrecest/tests/distributions/test_custom_hyperrectangular_distribution.py +++ b/pyrecest/tests/distributions/test_custom_hyperrectangular_distribution.py @@ -1,13 +1,6 @@ import unittest -from pyrecest.backend import ( - allclose, - array, - column_stack, - linspace, - meshgrid, - ones, -) +from pyrecest.backend import allclose, array, column_stack, linspace, meshgrid, ones from pyrecest.distributions.custom_hyperrectangular_distribution import ( CustomHyperrectangularDistribution, ) diff --git a/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py b/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py index 1050fcc2..e4fe2010 100644 --- a/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py @@ -2,6 +2,7 @@ from math import pi import numpy.testing as npt + # pylint: disable=redefined-builtin from pyrecest.backend import ( array, diff --git a/pyrecest/tests/distributions/test_hyperhemispherical_uniform_distribution.py b/pyrecest/tests/distributions/test_hyperhemispherical_uniform_distribution.py index bae17123..e7c9c054 100644 --- a/pyrecest/tests/distributions/test_hyperhemispherical_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_hyperhemispherical_uniform_distribution.py @@ -1,10 +1,8 @@ """ Test for uniform distribution for hyperhemispheres """ +import unittest from math import pi from pyrecest.backend import allclose, linalg, ones, random, reshape - -import unittest - from pyrecest.distributions import HyperhemisphericalUniformDistribution diff --git a/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py b/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py index c108af98..db054af2 100644 --- a/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py @@ -3,6 +3,7 @@ import numpy.testing as npt import pyrecest.backend + # pylint: disable=redefined-builtin from pyrecest.backend import array, linalg, mod, ones, random, sqrt, sum from pyrecest.distributions import VonMisesFisherDistribution diff --git a/pyrecest/tests/distributions/test_hyperspherical_mixture.py b/pyrecest/tests/distributions/test_hyperspherical_mixture.py index 6a0f9a34..b00beb0a 100644 --- a/pyrecest/tests/distributions/test_hyperspherical_mixture.py +++ b/pyrecest/tests/distributions/test_hyperspherical_mixture.py @@ -2,6 +2,7 @@ from math import pi from numpy.testing import assert_allclose + # pylint: disable=redefined-builtin from pyrecest.backend import arange, array, linspace, meshgrid, sqrt, stack, sum from pyrecest.distributions import ( diff --git a/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py b/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py index 8acdd78e..828c4dcf 100644 --- a/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py @@ -3,16 +3,9 @@ from math import pi import numpy.testing as npt + # pylint: disable=redefined-builtin -from pyrecest.backend import ( - array, - exp, - mod, - ones_like, - outer, - random, - sum, -) +from pyrecest.backend import array, exp, mod, ones_like, outer, random, sum from pyrecest.distributions import ( HypertoroidalDiracDistribution, ToroidalDiracDistribution, diff --git a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py index 6e82c913..8945798c 100644 --- a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py +++ b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py @@ -3,6 +3,7 @@ import numpy.testing as npt from parameterized import parameterized + # pylint: disable=redefined-builtin from pyrecest.backend import ( all, diff --git a/pyrecest/tests/distributions/test_toroidal_uniform_distribution.py b/pyrecest/tests/distributions/test_toroidal_uniform_distribution.py index e9e21472..f207b2ad 100644 --- a/pyrecest/tests/distributions/test_toroidal_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_toroidal_uniform_distribution.py @@ -2,6 +2,7 @@ from math import pi import pyrecest.backend + # pylint: disable=redefined-builtin from pyrecest.backend import all, allclose, array, ones, tile, zeros from pyrecest.distributions.hypertorus.toroidal_uniform_distribution import ( diff --git a/pyrecest/tests/distributions/test_wrapped_normal_distribution.py b/pyrecest/tests/distributions/test_wrapped_normal_distribution.py index d6f0c12b..c7ec38e8 100644 --- a/pyrecest/tests/distributions/test_wrapped_normal_distribution.py +++ b/pyrecest/tests/distributions/test_wrapped_normal_distribution.py @@ -2,16 +2,9 @@ from math import pi import numpy.testing as npt + # pylint: disable=redefined-builtin -from pyrecest.backend import ( - allclose, - arange, - array, - exp, - ones_like, - sqrt, - sum, -) +from pyrecest.backend import allclose, arange, array, exp, ones_like, sqrt, sum from pyrecest.distributions import WrappedNormalDistribution diff --git a/pyrecest/tests/filters/test_global_nearest_neighbor.py b/pyrecest/tests/filters/test_global_nearest_neighbor.py index 2c1bf59b..fcb3918f 100644 --- a/pyrecest/tests/filters/test_global_nearest_neighbor.py +++ b/pyrecest/tests/filters/test_global_nearest_neighbor.py @@ -4,6 +4,7 @@ import pyrecest.backend import scipy from parameterized import parameterized + # pylint: disable=redefined-builtin from pyrecest.backend import ( all, @@ -14,9 +15,9 @@ dstack, eye, real, + roll, sort, zeros, - roll, ) from pyrecest.distributions import GaussianDistribution from pyrecest.filters import KalmanFilter diff --git a/pyrecest/tests/test_evaluation_basic.py b/pyrecest/tests/test_evaluation_basic.py index 8bd4215c..c025b1b7 100644 --- a/pyrecest/tests/test_evaluation_basic.py +++ b/pyrecest/tests/test_evaluation_basic.py @@ -1,25 +1,28 @@ -from pyrecest.backend import atleast_2d -from pyrecest.backend import linalg -from pyrecest.backend import random -from pyrecest.backend import sqrt -from pyrecest.backend import shape -from pyrecest.backend import ones -from pyrecest.backend import ndim -from pyrecest.backend import eye -from pyrecest.backend import array -# pylint: disable=redefined-builtin -from pyrecest.backend import any -# pylint: disable=redefined-builtin -from pyrecest.backend import all -from pyrecest.backend import zeros -import numpy as np import os import tempfile import unittest from typing import Optional - +import numpy as np +import numpy.testing as npt from parameterized import parameterized + +# pylint: disable=redefined-builtin +# pylint: disable=redefined-builtin +from pyrecest.backend import ( + all, + any, + array, + atleast_2d, + eye, + linalg, + ndim, + ones, + random, + shape, + sqrt, + zeros, +) from pyrecest.distributions import ( GaussianDistribution, HypertoroidalWrappedNormalDistribution, @@ -43,7 +46,6 @@ ) from pyrecest.filters import HypertoroidalParticleFilter, KalmanFilter from shapely.geometry import Polygon -import numpy.testing as npt class TestEvalationBase(unittest.TestCase): @@ -175,7 +177,7 @@ def test_generate_simulated_scenario(self): def test_determine_all_deviations(self): import numpy as _np - + def dummy_extract_mean(x): return x @@ -277,15 +279,13 @@ def test_perform_predict_update_cycles(self): scenario_param, {"name": "kf", "parameter": None}, zeros((self.n_timesteps_default, 2)), - generate_measurements( - zeros((self.n_timesteps_default, 2)), scenario_param - ), + generate_measurements(zeros((self.n_timesteps_default, 2)), scenario_param), ) self.assertIsInstance(time_elapsed, float) self.assertGreater(time_elapsed, 0) self.assertIsNotNone(last_filter_state) - #self.assertIsInstance(last_estimate, ) + # self.assertIsInstance(last_estimate, ) self.assertEqual(last_estimate.shape, (2,)) self.assertIsNone(all_estimates) @@ -380,11 +380,11 @@ def _validate_eval_data( self.assertTrue(not any(run_failed)) self.assertEqual(ndim(groundtruths), 2) - #self.assertIsInstance(groundtruths[0, 0], ) + # self.assertIsInstance(groundtruths[0, 0], ) self.assertIn(ndim(groundtruths[0, 0]), (1, 2)) self.assertEqual(ndim(measurements), 2) - #self.assertIsInstance(measurements[0, 0], ) + # self.assertIsInstance(measurements[0, 0], ) self.assertIn(ndim(measurements[0, 0]), (1, 2)) def test_evaluate_for_simulation_config_R2_random_walk(self): diff --git a/pyrecest/tests/test_hypertoroidal_sampler.py b/pyrecest/tests/test_hypertoroidal_sampler.py index a0134ef5..562c4932 100644 --- a/pyrecest/tests/test_hypertoroidal_sampler.py +++ b/pyrecest/tests/test_hypertoroidal_sampler.py @@ -2,6 +2,7 @@ from math import pi import numpy.testing as npt + # pylint: disable=redefined-builtin from pyrecest.backend import all, diff, std from pyrecest.sampling.hypertoroidal_sampler import CircularUniformSampler From f1a0cb163d9364c42940c8862d6fb432f220d06b Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 23 Oct 2023 19:01:06 +0100 Subject: [PATCH 144/232] Trying to ignore some pylint directives --- pyrecest/distributions/abstract_custom_distribution.py | 1 + pyrecest/distributions/abstract_dirac_distribution.py | 2 +- pyrecest/distributions/abstract_disk_distribution.py | 1 + .../distributions/abstract_ellipsoidal_ball_distribution.py | 1 + .../distributions/abstract_manifold_specific_distribution.py | 1 + pyrecest/distributions/abstract_mixture.py | 3 ++- .../distributions/abstract_orthogonal_basis_distribution.py | 3 ++- pyrecest/distributions/abstract_periodic_distribution.py | 1 + pyrecest/distributions/abstract_se3_distribution.py | 1 + pyrecest/distributions/abstract_uniform_distribution.py | 1 + .../cart_prod/abstract_hypercylindrical_distribution.py | 3 ++- .../cart_prod/abstract_lin_bounded_cart_prod_distribution.py | 1 + .../cart_prod/cart_prod_stacked_distribution.py | 1 + .../cart_prod/hypercylindrical_dirac_distribution.py | 3 ++- .../cart_prod/lin_bounded_cart_prod_dirac_distribution.py | 1 + .../lin_hypersphere_cart_prod_dirac_distribution.py | 1 + .../cart_prod/lin_hypersphere_subset_dirac_distribution.py | 1 + .../cart_prod/partially_wrapped_normal_distribution.py | 3 ++- .../distributions/circle/abstract_circular_distribution.py | 1 + .../distributions/circle/circular_fourier_distribution.py | 3 ++- pyrecest/distributions/circle/circular_mixture.py | 3 ++- .../distributions/circle/custom_circular_distribution.py | 1 + pyrecest/distributions/circle/von_mises_distribution.py | 1 + pyrecest/distributions/circle/wrapped_cauchy_distribution.py | 1 + .../distributions/circle/wrapped_laplace_distribution.py | 1 + pyrecest/distributions/circle/wrapped_normal_distribution.py | 1 + pyrecest/distributions/disk_uniform_distribution.py | 1 + .../distributions/ellipsoidal_ball_uniform_distribution.py | 1 + .../abstract_hyperhemispherical_distribution.py | 1 + .../abstract_hypersphere_subset_dirac_distribution.py | 3 ++- .../abstract_hypersphere_subset_distribution.py | 3 ++- .../abstract_hypersphere_subset_uniform_distribution.py | 1 + .../abstract_hyperspherical_distribution.py | 1 + .../abstract_sphere_subset_distribution.py | 1 + .../abstract_spherical_harmonics_distribution.py | 1 + .../distributions/hypersphere_subset/bingham_distribution.py | 3 ++- .../custom_hyperhemispherical_distribution.py | 1 + .../hyperhemispherical_uniform_distribution.py | 1 + .../hyperhemispherical_watson_distribution.py | 1 + .../hypersphere_subset/hyperspherical_dirac_distribution.py | 3 ++- .../hyperspherical_uniform_distribution.py | 1 + .../spherical_harmonics_distribution_complex.py | 3 ++- .../spherical_harmonics_distribution_real.py | 3 ++- .../hypersphere_subset/von_mises_fisher_distribution.py | 4 +++- .../distributions/hypersphere_subset/watson_distribution.py | 1 + .../hypertorus/abstract_hypertoroidal_distribution.py | 4 +++- .../hypertorus/abstract_toroidal_distribution.py | 1 + .../hypertorus/custom_hypertoroidal_distribution.py | 1 + .../hypertorus/hypertoroidal_dirac_distribution.py | 3 ++- pyrecest/distributions/hypertorus/hypertoroidal_mixture.py | 1 + .../hypertorus/hypertoroidal_uniform_distribution.py | 1 + .../hypertorus/hypertoroidal_wrapped_normal_distribution.py | 3 ++- .../distributions/hypertorus/toroidal_dirac_distribution.py | 3 ++- .../hypertorus/toroidal_von_mises_sine_distribution.py | 3 ++- .../hypertorus/toroidal_wrapped_normal_distribution.py | 1 + .../nonperiodic/abstract_hyperrectangular_distribution.py | 1 + .../nonperiodic/abstract_linear_distribution.py | 4 +++- .../distributions/nonperiodic/custom_linear_distribution.py | 1 + pyrecest/distributions/nonperiodic/gaussian_distribution.py | 1 + pyrecest/distributions/nonperiodic/gaussian_mixture.py | 3 ++- .../distributions/nonperiodic/linear_dirac_distribution.py | 1 + pyrecest/distributions/se3_dirac_distribution.py | 1 + pyrecest/evaluation/determine_all_deviations.py | 3 ++- pyrecest/evaluation/eot_shape_database.py | 1 + pyrecest/evaluation/get_distance_function.py | 1 + pyrecest/evaluation/iterate_configs_and_runs.py | 1 + pyrecest/evaluation/perform_predict_update_cycles.py | 1 + pyrecest/evaluation/plot_results.py | 3 ++- pyrecest/evaluation/simulation_database.py | 1 + pyrecest/evaluation/summarize_filter_results.py | 3 ++- pyrecest/filters/abstract_nearest_neighbor_tracker.py | 1 + pyrecest/filters/abstract_particle_filter.py | 3 ++- pyrecest/filters/abstract_tracker_with_logging.py | 1 + pyrecest/filters/circular_particle_filter.py | 3 ++- pyrecest/filters/euclidean_particle_filter.py | 1 + pyrecest/filters/global_nearest_neighbor.py | 3 ++- pyrecest/filters/hypertoroidal_particle_filter.py | 3 ++- pyrecest/filters/kalman_filter.py | 2 ++ pyrecest/filters/random_matrix_tracker.py | 1 + pyrecest/filters/toroidal_particle_filter.py | 1 + pyrecest/filters/toroidal_wrapped_normal_filter.py | 1 + pyrecest/filters/von_mises_filter.py | 1 + pyrecest/filters/von_mises_fisher_filter.py | 1 + pyrecest/filters/wrapped_normal_filter.py | 1 + pyrecest/sampling/euclidean_sampler.py | 1 + pyrecest/sampling/hyperspherical_sampler.py | 1 + pyrecest/sampling/hypertoroidal_sampler.py | 1 + .../distributions/test_abstract_circular_distribution.py | 2 ++ .../test_abstract_hypercylindrical_distribution.py | 2 ++ .../test_abstract_hyperhemispherical_distribution.py | 3 ++- .../test_abstract_hypersphere_subset_distribution.py | 1 + .../test_abstract_hyperspherical_distribution.py | 1 + .../test_abstract_hypertoroidal_distribution.py | 1 + .../tests/distributions/test_abstract_linear_distribution.py | 2 ++ pyrecest/tests/distributions/test_abstract_mixture.py | 2 ++ pyrecest/tests/distributions/test_bingham_distribution.py | 1 + .../distributions/test_circular_fourier_distribution.py | 2 ++ .../distributions/test_circular_uniform_distribution.py | 2 ++ .../distributions/test_custom_hemispherical_distribution.py | 1 + .../test_custom_hypercylindrical_distribution.py | 2 ++ .../test_custom_hyperrectangular_distribution.py | 1 + .../distributions/test_custom_hyperspherical_distribution.py | 1 + .../tests/distributions/test_custom_linear_distribution.py | 1 + .../tests/distributions/test_disk_uniform_distribution.py | 1 + .../test_ellipsoidal_ball_uniform_distribution.py | 1 + pyrecest/tests/distributions/test_gaussian_distribution.py | 1 + .../distributions/test_hemispherical_uniform_distribution.py | 1 + .../test_hypercylindrical_dirac_distribution.py | 3 ++- .../test_hyperhemispherical_uniform_distribution.py | 1 + .../distributions/test_hyperspherical_dirac_distribution.py | 4 +++- pyrecest/tests/distributions/test_hyperspherical_mixture.py | 3 ++- .../test_hyperspherical_uniform_distribution.py | 1 + .../distributions/test_hypertoroidal_dirac_distribution.py | 3 ++- .../test_hypertoroidal_wrapped_normal_distribution.py | 1 + .../tests/distributions/test_linear_dirac_distribution.py | 1 + pyrecest/tests/distributions/test_linear_mixture.py | 1 + .../test_partially_wrapped_normal_distribution.py | 1 + pyrecest/tests/distributions/test_se3_dirac_distribution.py | 3 ++- .../tests/distributions/test_sphere_subset_distribution.py | 1 + .../test_spherical_harmonics_distribution_complex.py | 3 ++- .../test_spherical_harmonics_distribution_real.py | 1 + .../distributions/test_toroidal_uniform_distribution.py | 4 +++- .../test_toroidal_von_mises_sine_distribution.py | 2 ++ .../test_toroidal_wrapped_normal_distribution.py | 2 ++ pyrecest/tests/distributions/test_von_mises_distribution.py | 1 + .../distributions/test_von_mises_fisher_distribution.py | 1 + pyrecest/tests/distributions/test_watson_distribution.py | 1 + .../tests/distributions/test_wrapped_cauchy_distribution.py | 2 ++ .../tests/distributions/test_wrapped_laplace_distribution.py | 2 ++ .../tests/distributions/test_wrapped_normal_distribution.py | 3 ++- pyrecest/tests/filters/test_circular_particle_filter.py | 1 + pyrecest/tests/filters/test_euclidean_particle_filter.py | 1 + pyrecest/tests/filters/test_global_nearest_neighbor.py | 4 +++- pyrecest/tests/filters/test_hypertoroidal_particle_filter.py | 1 + pyrecest/tests/filters/test_kalman_filter.py | 2 ++ pyrecest/tests/filters/test_random_matrix_tracker.py | 2 ++ pyrecest/tests/filters/test_toroidal_particle_filter.py | 1 + .../tests/filters/test_toroidal_wrapped_normal_filter.py | 1 + pyrecest/tests/filters/test_von_mises_filter.py | 1 + pyrecest/tests/filters/test_von_mises_fisher_filter.py | 1 + pyrecest/tests/filters/test_wrapped_normal_filter.py | 1 + pyrecest/tests/test_euclidean_sampler.py | 1 + pyrecest/tests/test_evaluation_basic.py | 5 +++-- pyrecest/tests/test_hyperspherical_sampler.py | 1 + pyrecest/tests/test_hypertoroidal_sampler.py | 3 ++- pyrecest/tests/test_metrics.py | 1 + pyrecest/utils/metrics.py | 1 + pyrecest/utils/plotting.py | 1 + 148 files changed, 209 insertions(+), 42 deletions(-) diff --git a/pyrecest/distributions/abstract_custom_distribution.py b/pyrecest/distributions/abstract_custom_distribution.py index 47758f9c..601d6a94 100644 --- a/pyrecest/distributions/abstract_custom_distribution.py +++ b/pyrecest/distributions/abstract_custom_distribution.py @@ -2,6 +2,7 @@ import warnings from abc import abstractmethod +# pylint: disable=no-name-in-module,no-member import pyrecest.backend from .abstract_distribution_type import AbstractDistributionType diff --git a/pyrecest/distributions/abstract_dirac_distribution.py b/pyrecest/distributions/abstract_dirac_distribution.py index 62011770..e1d8997d 100644 --- a/pyrecest/distributions/abstract_dirac_distribution.py +++ b/pyrecest/distributions/abstract_dirac_distribution.py @@ -3,7 +3,7 @@ from collections.abc import Callable from typing import Union -# pylint: disable=redefined-builtin +# pylint: disable=redefined-builtin,no-name-in-module,no-member from pyrecest.backend import ( all, apply_along_axis, diff --git a/pyrecest/distributions/abstract_disk_distribution.py b/pyrecest/distributions/abstract_disk_distribution.py index 17b98f3a..f2c62e4e 100644 --- a/pyrecest/distributions/abstract_disk_distribution.py +++ b/pyrecest/distributions/abstract_disk_distribution.py @@ -1,3 +1,4 @@ +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, eye from .abstract_ellipsoidal_ball_distribution import AbstractEllipsoidalBallDistribution diff --git a/pyrecest/distributions/abstract_ellipsoidal_ball_distribution.py b/pyrecest/distributions/abstract_ellipsoidal_ball_distribution.py index 19e5fd55..4edebc61 100644 --- a/pyrecest/distributions/abstract_ellipsoidal_ball_distribution.py +++ b/pyrecest/distributions/abstract_ellipsoidal_ball_distribution.py @@ -1,5 +1,6 @@ from math import pi +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import linalg, sqrt from scipy.special import gamma diff --git a/pyrecest/distributions/abstract_manifold_specific_distribution.py b/pyrecest/distributions/abstract_manifold_specific_distribution.py index a137403e..86f6cfd6 100644 --- a/pyrecest/distributions/abstract_manifold_specific_distribution.py +++ b/pyrecest/distributions/abstract_manifold_specific_distribution.py @@ -2,6 +2,7 @@ from collections.abc import Callable from typing import Union +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import empty, int32, int64, random, squeeze diff --git a/pyrecest/distributions/abstract_mixture.py b/pyrecest/distributions/abstract_mixture.py index d8c219d9..452a4c59 100644 --- a/pyrecest/distributions/abstract_mixture.py +++ b/pyrecest/distributions/abstract_mixture.py @@ -3,7 +3,8 @@ import warnings from typing import Union -# pylint: disable=redefined-builtin +# pylint: disable=redefined-builtin,no-name-in-module,no-member +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import ( count_nonzero, empty, diff --git a/pyrecest/distributions/abstract_orthogonal_basis_distribution.py b/pyrecest/distributions/abstract_orthogonal_basis_distribution.py index 48f236f5..b61ee7e5 100644 --- a/pyrecest/distributions/abstract_orthogonal_basis_distribution.py +++ b/pyrecest/distributions/abstract_orthogonal_basis_distribution.py @@ -2,7 +2,8 @@ import warnings from abc import abstractmethod -# pylint: disable=redefined-builtin +# pylint: disable=redefined-builtin,no-name-in-module,no-member +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import all, exp, imag, real from .abstract_distribution_type import AbstractDistributionType diff --git a/pyrecest/distributions/abstract_periodic_distribution.py b/pyrecest/distributions/abstract_periodic_distribution.py index c4a1fe8e..6b57153a 100644 --- a/pyrecest/distributions/abstract_periodic_distribution.py +++ b/pyrecest/distributions/abstract_periodic_distribution.py @@ -1,6 +1,7 @@ from abc import abstractmethod from typing import Union +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import int32, int64 from .abstract_bounded_domain_distribution import AbstractBoundedDomainDistribution diff --git a/pyrecest/distributions/abstract_se3_distribution.py b/pyrecest/distributions/abstract_se3_distribution.py index a5ff92a7..9af55729 100644 --- a/pyrecest/distributions/abstract_se3_distribution.py +++ b/pyrecest/distributions/abstract_se3_distribution.py @@ -4,6 +4,7 @@ import matplotlib.pyplot as plt import quaternion +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import column_stack, concatenate, int32, int64 from .cart_prod.abstract_lin_bounded_cart_prod_distribution import ( diff --git a/pyrecest/distributions/abstract_uniform_distribution.py b/pyrecest/distributions/abstract_uniform_distribution.py index 54ba39c6..0d5b5c4c 100644 --- a/pyrecest/distributions/abstract_uniform_distribution.py +++ b/pyrecest/distributions/abstract_uniform_distribution.py @@ -1,5 +1,6 @@ from abc import abstractmethod +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import ones from .abstract_distribution_type import AbstractDistributionType diff --git a/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py b/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py index cd833cc2..8a2257e8 100644 --- a/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py +++ b/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py @@ -5,7 +5,8 @@ import scipy.integrate import scipy.optimize -# pylint: disable=redefined-builtin +# pylint: disable=redefined-builtin,no-name-in-module,no-member +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import ( allclose, any, diff --git a/pyrecest/distributions/cart_prod/abstract_lin_bounded_cart_prod_distribution.py b/pyrecest/distributions/cart_prod/abstract_lin_bounded_cart_prod_distribution.py index f713f27c..5915a982 100644 --- a/pyrecest/distributions/cart_prod/abstract_lin_bounded_cart_prod_distribution.py +++ b/pyrecest/distributions/cart_prod/abstract_lin_bounded_cart_prod_distribution.py @@ -1,6 +1,7 @@ from abc import abstractmethod from typing import Union +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import int32, int64 from .abstract_cart_prod_distribution import AbstractCartProdDistribution diff --git a/pyrecest/distributions/cart_prod/cart_prod_stacked_distribution.py b/pyrecest/distributions/cart_prod/cart_prod_stacked_distribution.py index 7dc5f509..c8be9319 100644 --- a/pyrecest/distributions/cart_prod/cart_prod_stacked_distribution.py +++ b/pyrecest/distributions/cart_prod/cart_prod_stacked_distribution.py @@ -1,3 +1,4 @@ +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import concatenate, empty, hstack, prod from .abstract_cart_prod_distribution import AbstractCartProdDistribution diff --git a/pyrecest/distributions/cart_prod/hypercylindrical_dirac_distribution.py b/pyrecest/distributions/cart_prod/hypercylindrical_dirac_distribution.py index 2927e01a..29ab04a6 100644 --- a/pyrecest/distributions/cart_prod/hypercylindrical_dirac_distribution.py +++ b/pyrecest/distributions/cart_prod/hypercylindrical_dirac_distribution.py @@ -1,6 +1,7 @@ from typing import Union -# pylint: disable=redefined-builtin +# pylint: disable=redefined-builtin,no-name-in-module,no-member +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import cos, full, int32, int64, sin, sum, tile from ..hypertorus.hypertoroidal_dirac_distribution import HypertoroidalDiracDistribution diff --git a/pyrecest/distributions/cart_prod/lin_bounded_cart_prod_dirac_distribution.py b/pyrecest/distributions/cart_prod/lin_bounded_cart_prod_dirac_distribution.py index d656215c..91ebab29 100644 --- a/pyrecest/distributions/cart_prod/lin_bounded_cart_prod_dirac_distribution.py +++ b/pyrecest/distributions/cart_prod/lin_bounded_cart_prod_dirac_distribution.py @@ -1,6 +1,7 @@ import warnings from abc import abstractmethod +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import concatenate from ..abstract_dirac_distribution import AbstractDiracDistribution diff --git a/pyrecest/distributions/cart_prod/lin_hypersphere_cart_prod_dirac_distribution.py b/pyrecest/distributions/cart_prod/lin_hypersphere_cart_prod_dirac_distribution.py index 8611b7fb..6260a05e 100644 --- a/pyrecest/distributions/cart_prod/lin_hypersphere_cart_prod_dirac_distribution.py +++ b/pyrecest/distributions/cart_prod/lin_hypersphere_cart_prod_dirac_distribution.py @@ -1,3 +1,4 @@ +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import abs, linalg, max from ..abstract_se3_distribution import AbstractSE3Distribution diff --git a/pyrecest/distributions/cart_prod/lin_hypersphere_subset_dirac_distribution.py b/pyrecest/distributions/cart_prod/lin_hypersphere_subset_dirac_distribution.py index 6f172ba1..5973c452 100644 --- a/pyrecest/distributions/cart_prod/lin_hypersphere_subset_dirac_distribution.py +++ b/pyrecest/distributions/cart_prod/lin_hypersphere_subset_dirac_distribution.py @@ -1,5 +1,6 @@ from typing import Union +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import int32, int64 from .abstract_lin_hyperhemisphere_cart_prod_distribution import ( diff --git a/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py b/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py index ba9e7fca..647cada1 100644 --- a/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py +++ b/pyrecest/distributions/cart_prod/partially_wrapped_normal_distribution.py @@ -2,7 +2,8 @@ from math import pi from typing import Union -# pylint: disable=redefined-builtin +# pylint: disable=redefined-builtin,no-name-in-module,no-member +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import ( allclose, array, diff --git a/pyrecest/distributions/circle/abstract_circular_distribution.py b/pyrecest/distributions/circle/abstract_circular_distribution.py index eaa7b924..f0230093 100644 --- a/pyrecest/distributions/circle/abstract_circular_distribution.py +++ b/pyrecest/distributions/circle/abstract_circular_distribution.py @@ -1,6 +1,7 @@ from math import pi import matplotlib.pyplot as plt +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, cos, linspace, mod, sin from ..hypertorus.abstract_hypertoroidal_distribution import ( diff --git a/pyrecest/distributions/circle/circular_fourier_distribution.py b/pyrecest/distributions/circle/circular_fourier_distribution.py index ad59a7ab..9abe0ed3 100644 --- a/pyrecest/distributions/circle/circular_fourier_distribution.py +++ b/pyrecest/distributions/circle/circular_fourier_distribution.py @@ -4,7 +4,8 @@ import matplotlib.pyplot as plt -# pylint: disable=redefined-builtin +# pylint: disable=redefined-builtin,no-name-in-module,no-member +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import ( arange, array, diff --git a/pyrecest/distributions/circle/circular_mixture.py b/pyrecest/distributions/circle/circular_mixture.py index f716ff38..f5453d08 100644 --- a/pyrecest/distributions/circle/circular_mixture.py +++ b/pyrecest/distributions/circle/circular_mixture.py @@ -1,7 +1,8 @@ import collections import warnings -# pylint: disable=redefined-builtin +# pylint: disable=redefined-builtin,no-name-in-module,no-member +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import shape, sum from ..hypertorus.hypertoroidal_mixture import HypertoroidalMixture diff --git a/pyrecest/distributions/circle/custom_circular_distribution.py b/pyrecest/distributions/circle/custom_circular_distribution.py index c83e3a6e..7b02d047 100644 --- a/pyrecest/distributions/circle/custom_circular_distribution.py +++ b/pyrecest/distributions/circle/custom_circular_distribution.py @@ -1,6 +1,7 @@ from collections.abc import Callable from math import pi +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, mod from ..abstract_custom_distribution import AbstractCustomDistribution diff --git a/pyrecest/distributions/circle/von_mises_distribution.py b/pyrecest/distributions/circle/von_mises_distribution.py index 9146f9a5..5ba9e867 100644 --- a/pyrecest/distributions/circle/von_mises_distribution.py +++ b/pyrecest/distributions/circle/von_mises_distribution.py @@ -1,5 +1,6 @@ from math import pi +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import ( abs, arctan2, diff --git a/pyrecest/distributions/circle/wrapped_cauchy_distribution.py b/pyrecest/distributions/circle/wrapped_cauchy_distribution.py index 787446d4..74b4442d 100644 --- a/pyrecest/distributions/circle/wrapped_cauchy_distribution.py +++ b/pyrecest/distributions/circle/wrapped_cauchy_distribution.py @@ -1,5 +1,6 @@ from math import pi +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import arctan, cos, cosh, exp, mod, sinh, tan, tanh from .abstract_circular_distribution import AbstractCircularDistribution diff --git a/pyrecest/distributions/circle/wrapped_laplace_distribution.py b/pyrecest/distributions/circle/wrapped_laplace_distribution.py index 7da024fa..d46baba9 100644 --- a/pyrecest/distributions/circle/wrapped_laplace_distribution.py +++ b/pyrecest/distributions/circle/wrapped_laplace_distribution.py @@ -1,5 +1,6 @@ from math import pi +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import exp, mod, ndim from .abstract_circular_distribution import AbstractCircularDistribution diff --git a/pyrecest/distributions/circle/wrapped_normal_distribution.py b/pyrecest/distributions/circle/wrapped_normal_distribution.py index e32972d4..f669917a 100644 --- a/pyrecest/distributions/circle/wrapped_normal_distribution.py +++ b/pyrecest/distributions/circle/wrapped_normal_distribution.py @@ -1,6 +1,7 @@ from math import pi from typing import Union +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import ( abs, angle, diff --git a/pyrecest/distributions/disk_uniform_distribution.py b/pyrecest/distributions/disk_uniform_distribution.py index edd24e4b..968437ec 100644 --- a/pyrecest/distributions/disk_uniform_distribution.py +++ b/pyrecest/distributions/disk_uniform_distribution.py @@ -1,3 +1,4 @@ +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, eye from .abstract_disk_distribution import AbstractDiskDistribution diff --git a/pyrecest/distributions/ellipsoidal_ball_uniform_distribution.py b/pyrecest/distributions/ellipsoidal_ball_uniform_distribution.py index 24ba17f6..e66c4a5e 100644 --- a/pyrecest/distributions/ellipsoidal_ball_uniform_distribution.py +++ b/pyrecest/distributions/ellipsoidal_ball_uniform_distribution.py @@ -1,5 +1,6 @@ from typing import Union +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import dot, int32, int64, linalg, random, zeros from .abstract_ellipsoidal_ball_distribution import AbstractEllipsoidalBallDistribution diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py index 594285ab..4e33093f 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py @@ -4,6 +4,7 @@ from typing import Union import matplotlib.pyplot as plt +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import ( array, concatenate, diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_dirac_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_dirac_distribution.py index a675c6c6..24d753a8 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_dirac_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_dirac_distribution.py @@ -1,4 +1,5 @@ -# pylint: disable=redefined-builtin +# pylint: disable=redefined-builtin,no-name-in-module,no-member +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import log, sum from ..abstract_dirac_distribution import AbstractDiracDistribution diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py index 188de10d..1fb770b8 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py @@ -3,7 +3,8 @@ from math import pi from typing import Union -# pylint: disable=redefined-builtin +# pylint: disable=redefined-builtin,no-name-in-module,no-member +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import ( abs, array, diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_uniform_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_uniform_distribution.py index 8bef3347..839bd12e 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_uniform_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_uniform_distribution.py @@ -1,3 +1,4 @@ +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import ones from ..abstract_uniform_distribution import AbstractUniformDistribution diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py index b27c76f0..cf94168c 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py @@ -3,6 +3,7 @@ from typing import Union import matplotlib.pyplot as plt +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import ( array, concatenate, diff --git a/pyrecest/distributions/hypersphere_subset/abstract_sphere_subset_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_sphere_subset_distribution.py index 88f1028e..9fa55a53 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_sphere_subset_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_sphere_subset_distribution.py @@ -1,5 +1,6 @@ from math import pi +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import arccos, arctan2, cos, ndim, sin, where from .abstract_hypersphere_subset_distribution import ( diff --git a/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py index 503dac6c..f13f7a91 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py @@ -2,6 +2,7 @@ import warnings from math import pi +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import abs, atleast_2d, imag, isnan, real, sqrt, zeros from scipy.linalg import norm diff --git a/pyrecest/distributions/hypersphere_subset/bingham_distribution.py b/pyrecest/distributions/hypersphere_subset/bingham_distribution.py index eed9ed96..7de8892e 100644 --- a/pyrecest/distributions/hypersphere_subset/bingham_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/bingham_distribution.py @@ -1,6 +1,7 @@ from math import pi -# pylint: disable=redefined-builtin +# pylint: disable=redefined-builtin,no-name-in-module,no-member +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import abs, all, argsort, diag, exp, eye, linalg, max, sum, zeros from scipy.integrate import quad from scipy.special import iv diff --git a/pyrecest/distributions/hypersphere_subset/custom_hyperhemispherical_distribution.py b/pyrecest/distributions/hypersphere_subset/custom_hyperhemispherical_distribution.py index ed996d87..f4627392 100644 --- a/pyrecest/distributions/hypersphere_subset/custom_hyperhemispherical_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/custom_hyperhemispherical_distribution.py @@ -1,6 +1,7 @@ from collections.abc import Callable from typing import Union +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import int32, int64 from ..abstract_custom_distribution import AbstractCustomDistribution diff --git a/pyrecest/distributions/hypersphere_subset/hyperhemispherical_uniform_distribution.py b/pyrecest/distributions/hypersphere_subset/hyperhemispherical_uniform_distribution.py index 49c3beb5..3961bf6b 100644 --- a/pyrecest/distributions/hypersphere_subset/hyperhemispherical_uniform_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/hyperhemispherical_uniform_distribution.py @@ -1,5 +1,6 @@ from typing import Union +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import int32, int64 from .abstract_hyperhemispherical_distribution import ( diff --git a/pyrecest/distributions/hypersphere_subset/hyperhemispherical_watson_distribution.py b/pyrecest/distributions/hypersphere_subset/hyperhemispherical_watson_distribution.py index fd87f85d..a726a5ec 100644 --- a/pyrecest/distributions/hypersphere_subset/hyperhemispherical_watson_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/hyperhemispherical_watson_distribution.py @@ -1,5 +1,6 @@ from typing import Union +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import allclose, array, concatenate, int32, int64, zeros from .abstract_hyperhemispherical_distribution import ( diff --git a/pyrecest/distributions/hypersphere_subset/hyperspherical_dirac_distribution.py b/pyrecest/distributions/hypersphere_subset/hyperspherical_dirac_distribution.py index b4511732..fc587887 100644 --- a/pyrecest/distributions/hypersphere_subset/hyperspherical_dirac_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/hyperspherical_dirac_distribution.py @@ -1,6 +1,7 @@ import matplotlib.pyplot as plt -# pylint: disable=redefined-builtin +# pylint: disable=redefined-builtin,no-name-in-module,no-member +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import linalg, reshape, sum from ..circle.circular_dirac_distribution import CircularDiracDistribution diff --git a/pyrecest/distributions/hypersphere_subset/hyperspherical_uniform_distribution.py b/pyrecest/distributions/hypersphere_subset/hyperspherical_uniform_distribution.py index f466e2a9..49060aac 100644 --- a/pyrecest/distributions/hypersphere_subset/hyperspherical_uniform_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/hyperspherical_uniform_distribution.py @@ -1,6 +1,7 @@ from math import pi from typing import Union +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import cos, empty, int32, int64, linalg, random, sin, sqrt from .abstract_hypersphere_subset_uniform_distribution import ( diff --git a/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py b/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py index 79d121f9..24da30a0 100644 --- a/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py +++ b/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py @@ -2,7 +2,8 @@ import scipy -# pylint: disable=redefined-builtin +# pylint: disable=redefined-builtin,no-name-in-module,no-member +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import ( abs, all, diff --git a/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_real.py b/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_real.py index dbdbf4a1..37d0e727 100644 --- a/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_real.py +++ b/pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_real.py @@ -1,4 +1,5 @@ -# pylint: disable=redefined-builtin +# pylint: disable=redefined-builtin,no-name-in-module,no-member +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import ( all, atleast_2d, diff --git a/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py b/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py index a55065c3..c584a2f9 100644 --- a/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/von_mises_fisher_distribution.py @@ -1,9 +1,11 @@ from math import pi from typing import Union +# pylint: disable=no-name-in-module,no-member import pyrecest.backend -# pylint: disable=redefined-builtin +# pylint: disable=redefined-builtin,no-name-in-module,no-member +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import ( abs, all, diff --git a/pyrecest/distributions/hypersphere_subset/watson_distribution.py b/pyrecest/distributions/hypersphere_subset/watson_distribution.py index 3c61a100..f6b2e724 100644 --- a/pyrecest/distributions/hypersphere_subset/watson_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/watson_distribution.py @@ -1,5 +1,6 @@ import mpmath import numpy.testing as npt +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import ( abs, array, diff --git a/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py b/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py index 4d9e2ccc..bc79d426 100644 --- a/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py +++ b/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py @@ -3,9 +3,11 @@ from typing import Union import matplotlib.pyplot as plt +# pylint: disable=no-name-in-module,no-member import pyrecest.backend -# pylint: disable=redefined-builtin +# pylint: disable=redefined-builtin,no-name-in-module,no-member +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import ( abs, angle, diff --git a/pyrecest/distributions/hypertorus/abstract_toroidal_distribution.py b/pyrecest/distributions/hypertorus/abstract_toroidal_distribution.py index b9f3db3d..44cb8183 100644 --- a/pyrecest/distributions/hypertorus/abstract_toroidal_distribution.py +++ b/pyrecest/distributions/hypertorus/abstract_toroidal_distribution.py @@ -1,6 +1,7 @@ from math import pi from typing import Union +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, cos, int32, int64, sin, sqrt, zeros from scipy.integrate import dblquad diff --git a/pyrecest/distributions/hypertorus/custom_hypertoroidal_distribution.py b/pyrecest/distributions/hypertorus/custom_hypertoroidal_distribution.py index 69b9f3bf..55f1d953 100644 --- a/pyrecest/distributions/hypertorus/custom_hypertoroidal_distribution.py +++ b/pyrecest/distributions/hypertorus/custom_hypertoroidal_distribution.py @@ -1,5 +1,6 @@ from math import pi +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import mod, zeros from ..abstract_custom_distribution import AbstractCustomDistribution diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py b/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py index e54567ce..74b70f77 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py @@ -3,7 +3,8 @@ from math import pi from typing import Union -# pylint: disable=redefined-builtin +# pylint: disable=redefined-builtin,no-name-in-module,no-member +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import ( arctan2, atleast_1d, diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_mixture.py b/pyrecest/distributions/hypertorus/hypertoroidal_mixture.py index 38c71760..525ebddc 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_mixture.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_mixture.py @@ -2,6 +2,7 @@ import copy from typing import Union +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import complex128, int32, int64, zeros from ..abstract_mixture import AbstractMixture diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_uniform_distribution.py b/pyrecest/distributions/hypertorus/hypertoroidal_uniform_distribution.py index 05b676bd..40c9d56d 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_uniform_distribution.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_uniform_distribution.py @@ -1,6 +1,7 @@ from math import pi from typing import Union +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import int32, int64, log, ndim, ones, prod, random, zeros from ..abstract_uniform_distribution import AbstractUniformDistribution diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py b/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py index 3bee59b6..46ee2fcb 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py @@ -2,7 +2,8 @@ from math import pi from typing import Union -# pylint: disable=redefined-builtin +# pylint: disable=redefined-builtin,no-name-in-module,no-member +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import ( allclose, arange, diff --git a/pyrecest/distributions/hypertorus/toroidal_dirac_distribution.py b/pyrecest/distributions/hypertorus/toroidal_dirac_distribution.py index ed60c465..ea844c69 100644 --- a/pyrecest/distributions/hypertorus/toroidal_dirac_distribution.py +++ b/pyrecest/distributions/hypertorus/toroidal_dirac_distribution.py @@ -1,4 +1,5 @@ -# pylint: disable=redefined-builtin +# pylint: disable=redefined-builtin,no-name-in-module,no-member +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import column_stack, cos, diag, dot, sin, sqrt, sum, tile from .abstract_toroidal_distribution import AbstractToroidalDistribution diff --git a/pyrecest/distributions/hypertorus/toroidal_von_mises_sine_distribution.py b/pyrecest/distributions/hypertorus/toroidal_von_mises_sine_distribution.py index 95329c01..05c47f5d 100644 --- a/pyrecest/distributions/hypertorus/toroidal_von_mises_sine_distribution.py +++ b/pyrecest/distributions/hypertorus/toroidal_von_mises_sine_distribution.py @@ -1,6 +1,7 @@ from math import pi -# pylint: disable=redefined-builtin +# pylint: disable=redefined-builtin,no-name-in-module,no-member +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import all, array, cos, exp, mod, sin, sum from scipy.special import comb, iv diff --git a/pyrecest/distributions/hypertorus/toroidal_wrapped_normal_distribution.py b/pyrecest/distributions/hypertorus/toroidal_wrapped_normal_distribution.py index d8b9f09f..51e2c773 100644 --- a/pyrecest/distributions/hypertorus/toroidal_wrapped_normal_distribution.py +++ b/pyrecest/distributions/hypertorus/toroidal_wrapped_normal_distribution.py @@ -1,4 +1,5 @@ from numpy import cos, exp, sin +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import array from .abstract_toroidal_distribution import AbstractToroidalDistribution diff --git a/pyrecest/distributions/nonperiodic/abstract_hyperrectangular_distribution.py b/pyrecest/distributions/nonperiodic/abstract_hyperrectangular_distribution.py index d8edd0a4..b147305c 100644 --- a/pyrecest/distributions/nonperiodic/abstract_hyperrectangular_distribution.py +++ b/pyrecest/distributions/nonperiodic/abstract_hyperrectangular_distribution.py @@ -1,3 +1,4 @@ +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, diff, prod, reshape from scipy.integrate import nquad diff --git a/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py b/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py index 307fe477..6057f851 100644 --- a/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py +++ b/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py @@ -2,9 +2,11 @@ from typing import Union import matplotlib.pyplot as plt +# pylint: disable=no-name-in-module,no-member import pyrecest.backend -# pylint: disable=redefined-builtin +# pylint: disable=redefined-builtin,no-name-in-module,no-member +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import ( array, atleast_1d, diff --git a/pyrecest/distributions/nonperiodic/custom_linear_distribution.py b/pyrecest/distributions/nonperiodic/custom_linear_distribution.py index 625c4619..079695f0 100644 --- a/pyrecest/distributions/nonperiodic/custom_linear_distribution.py +++ b/pyrecest/distributions/nonperiodic/custom_linear_distribution.py @@ -1,5 +1,6 @@ import copy +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import ndim, reshape, zeros from ..abstract_custom_nonperiodic_distribution import ( diff --git a/pyrecest/distributions/nonperiodic/gaussian_distribution.py b/pyrecest/distributions/nonperiodic/gaussian_distribution.py index 741c3038..49096af4 100644 --- a/pyrecest/distributions/nonperiodic/gaussian_distribution.py +++ b/pyrecest/distributions/nonperiodic/gaussian_distribution.py @@ -1,5 +1,6 @@ import copy +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import dot, linalg, ndim, random from scipy.linalg import cholesky from scipy.stats import multivariate_normal as mvn diff --git a/pyrecest/distributions/nonperiodic/gaussian_mixture.py b/pyrecest/distributions/nonperiodic/gaussian_mixture.py index 8a5413e9..89be400e 100644 --- a/pyrecest/distributions/nonperiodic/gaussian_mixture.py +++ b/pyrecest/distributions/nonperiodic/gaussian_mixture.py @@ -1,4 +1,5 @@ -# pylint: disable=redefined-builtin +# pylint: disable=redefined-builtin,no-name-in-module,no-member +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, dot, ones, stack, sum from .abstract_linear_distribution import AbstractLinearDistribution diff --git a/pyrecest/distributions/nonperiodic/linear_dirac_distribution.py b/pyrecest/distributions/nonperiodic/linear_dirac_distribution.py index d647645d..e610fb29 100644 --- a/pyrecest/distributions/nonperiodic/linear_dirac_distribution.py +++ b/pyrecest/distributions/nonperiodic/linear_dirac_distribution.py @@ -1,4 +1,5 @@ import matplotlib.pyplot as plt +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import cov, ones, reshape from ..abstract_dirac_distribution import AbstractDiracDistribution diff --git a/pyrecest/distributions/se3_dirac_distribution.py b/pyrecest/distributions/se3_dirac_distribution.py index 7c9530eb..5ce41390 100644 --- a/pyrecest/distributions/se3_dirac_distribution.py +++ b/pyrecest/distributions/se3_dirac_distribution.py @@ -1,3 +1,4 @@ +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import ones from .abstract_se3_distribution import AbstractSE3Distribution diff --git a/pyrecest/evaluation/determine_all_deviations.py b/pyrecest/evaluation/determine_all_deviations.py index 70218901..c82898b2 100644 --- a/pyrecest/evaluation/determine_all_deviations.py +++ b/pyrecest/evaluation/determine_all_deviations.py @@ -3,7 +3,8 @@ import numpy as np -# pylint: disable=redefined-builtin +# pylint: disable=redefined-builtin,no-name-in-module,no-member +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import any, empty, isinf, ndim, sum diff --git a/pyrecest/evaluation/eot_shape_database.py b/pyrecest/evaluation/eot_shape_database.py index 7c47c402..4b39a68f 100644 --- a/pyrecest/evaluation/eot_shape_database.py +++ b/pyrecest/evaluation/eot_shape_database.py @@ -1,5 +1,6 @@ from math import pi +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, cos, empty, linspace, random, sin from shapely.geometry import LineString, MultiLineString, Point, Polygon from shapely.ops import unary_union diff --git a/pyrecest/evaluation/get_distance_function.py b/pyrecest/evaluation/get_distance_function.py index 5cd9b0b8..54eec690 100644 --- a/pyrecest/evaluation/get_distance_function.py +++ b/pyrecest/evaluation/get_distance_function.py @@ -1,4 +1,5 @@ from numpy.linalg import norm +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import arccos, dot from pyrecest.distributions import AbstractHypertoroidalDistribution diff --git a/pyrecest/evaluation/iterate_configs_and_runs.py b/pyrecest/evaluation/iterate_configs_and_runs.py index 36cc0f4d..76364707 100644 --- a/pyrecest/evaluation/iterate_configs_and_runs.py +++ b/pyrecest/evaluation/iterate_configs_and_runs.py @@ -1,6 +1,7 @@ import warnings from typing import Any, Dict +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import empty, zeros from .perform_predict_update_cycles import perform_predict_update_cycles diff --git a/pyrecest/evaluation/perform_predict_update_cycles.py b/pyrecest/evaluation/perform_predict_update_cycles.py index d2e48576..7b3df706 100644 --- a/pyrecest/evaluation/perform_predict_update_cycles.py +++ b/pyrecest/evaluation/perform_predict_update_cycles.py @@ -1,6 +1,7 @@ import time import warnings +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, atleast_2d, squeeze from .configure_for_filter import configure_for_filter diff --git a/pyrecest/evaluation/plot_results.py b/pyrecest/evaluation/plot_results.py index 49996f46..3a14950b 100644 --- a/pyrecest/evaluation/plot_results.py +++ b/pyrecest/evaluation/plot_results.py @@ -2,7 +2,8 @@ import matplotlib.pyplot as plt -# pylint: disable=redefined-builtin +# pylint: disable=redefined-builtin,no-name-in-module,no-member +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import any, array, isnan, ones, shape from .get_axis_label import get_axis_label diff --git a/pyrecest/evaluation/simulation_database.py b/pyrecest/evaluation/simulation_database.py index b682a592..6ac9e89a 100644 --- a/pyrecest/evaluation/simulation_database.py +++ b/pyrecest/evaluation/simulation_database.py @@ -1,6 +1,7 @@ import warnings from typing import Optional +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import eye, zeros from pyrecest.distributions import GaussianDistribution diff --git a/pyrecest/evaluation/summarize_filter_results.py b/pyrecest/evaluation/summarize_filter_results.py index 67ab3d57..335f270a 100644 --- a/pyrecest/evaluation/summarize_filter_results.py +++ b/pyrecest/evaluation/summarize_filter_results.py @@ -1,6 +1,7 @@ import warnings -# pylint: disable=redefined-builtin +# pylint: disable=redefined-builtin,no-name-in-module,no-member +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import mean, std, sum from .determine_all_deviations import determine_all_deviations diff --git a/pyrecest/filters/abstract_nearest_neighbor_tracker.py b/pyrecest/filters/abstract_nearest_neighbor_tracker.py index f0141c11..b95d40a8 100644 --- a/pyrecest/filters/abstract_nearest_neighbor_tracker.py +++ b/pyrecest/filters/abstract_nearest_neighbor_tracker.py @@ -2,6 +2,7 @@ import warnings from abc import abstractmethod +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import empty, ndim from pyrecest.distributions import GaussianDistribution diff --git a/pyrecest/filters/abstract_particle_filter.py b/pyrecest/filters/abstract_particle_filter.py index 5295c492..c5c4118c 100644 --- a/pyrecest/filters/abstract_particle_filter.py +++ b/pyrecest/filters/abstract_particle_filter.py @@ -1,6 +1,7 @@ from collections.abc import Callable -# pylint: disable=redefined-builtin +# pylint: disable=redefined-builtin,no-name-in-module,no-member +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import ndim, ones_like, random, sum, zeros from pyrecest.distributions.abstract_manifold_specific_distribution import ( AbstractManifoldSpecificDistribution, diff --git a/pyrecest/filters/abstract_tracker_with_logging.py b/pyrecest/filters/abstract_tracker_with_logging.py index 360c4b95..0adc17c8 100644 --- a/pyrecest/filters/abstract_tracker_with_logging.py +++ b/pyrecest/filters/abstract_tracker_with_logging.py @@ -1,5 +1,6 @@ from abc import ABC +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, full, hstack diff --git a/pyrecest/filters/circular_particle_filter.py b/pyrecest/filters/circular_particle_filter.py index 4041a587..72dea3ac 100644 --- a/pyrecest/filters/circular_particle_filter.py +++ b/pyrecest/filters/circular_particle_filter.py @@ -1,6 +1,7 @@ from typing import Union -# pylint: disable=redefined-builtin +# pylint: disable=redefined-builtin,no-name-in-module,no-member +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import float64, int32, int64, sum from .hypertoroidal_particle_filter import HypertoroidalParticleFilter diff --git a/pyrecest/filters/euclidean_particle_filter.py b/pyrecest/filters/euclidean_particle_filter.py index aa795515..817ad153 100644 --- a/pyrecest/filters/euclidean_particle_filter.py +++ b/pyrecest/filters/euclidean_particle_filter.py @@ -2,6 +2,7 @@ from collections.abc import Callable from typing import Union +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import int32, int64, zeros from ..distributions.nonperiodic.abstract_linear_distribution import ( diff --git a/pyrecest/filters/global_nearest_neighbor.py b/pyrecest/filters/global_nearest_neighbor.py index 945edf8c..78db97fc 100644 --- a/pyrecest/filters/global_nearest_neighbor.py +++ b/pyrecest/filters/global_nearest_neighbor.py @@ -1,4 +1,5 @@ -# pylint: disable=redefined-builtin +# pylint: disable=redefined-builtin,no-name-in-module,no-member +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import all, empty, full, repeat, squeeze, stack from scipy.optimize import linear_sum_assignment from scipy.spatial.distance import cdist diff --git a/pyrecest/filters/hypertoroidal_particle_filter.py b/pyrecest/filters/hypertoroidal_particle_filter.py index 97d6b036..b6a8676b 100644 --- a/pyrecest/filters/hypertoroidal_particle_filter.py +++ b/pyrecest/filters/hypertoroidal_particle_filter.py @@ -3,7 +3,8 @@ from math import pi from typing import Union -# pylint: disable=redefined-builtin +# pylint: disable=redefined-builtin,no-name-in-module,no-member +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import ( arange, int32, diff --git a/pyrecest/filters/kalman_filter.py b/pyrecest/filters/kalman_filter.py index 19ee8261..329969f1 100644 --- a/pyrecest/filters/kalman_filter.py +++ b/pyrecest/filters/kalman_filter.py @@ -1,5 +1,7 @@ +# pylint: disable=no-name-in-module,no-member import pyrecest.backend from filterpy.kalman import KalmanFilter as FilterPyKalmanFilter +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import eye from pyrecest.distributions import GaussianDistribution diff --git a/pyrecest/filters/random_matrix_tracker.py b/pyrecest/filters/random_matrix_tracker.py index 318ac6fc..31c55526 100644 --- a/pyrecest/filters/random_matrix_tracker.py +++ b/pyrecest/filters/random_matrix_tracker.py @@ -1,3 +1,4 @@ +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import concatenate, exp, eye, linalg, mean from pyrecest.utils.plotting import plot_ellipsoid diff --git a/pyrecest/filters/toroidal_particle_filter.py b/pyrecest/filters/toroidal_particle_filter.py index a21e8e1e..f87cedf0 100644 --- a/pyrecest/filters/toroidal_particle_filter.py +++ b/pyrecest/filters/toroidal_particle_filter.py @@ -1,5 +1,6 @@ from typing import Union +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import int32, int64 from .hypertoroidal_particle_filter import HypertoroidalParticleFilter diff --git a/pyrecest/filters/toroidal_wrapped_normal_filter.py b/pyrecest/filters/toroidal_wrapped_normal_filter.py index f9f7fd05..c4a7bfdc 100644 --- a/pyrecest/filters/toroidal_wrapped_normal_filter.py +++ b/pyrecest/filters/toroidal_wrapped_normal_filter.py @@ -1,3 +1,4 @@ +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, eye from pyrecest.distributions.hypertorus.toroidal_wrapped_normal_distribution import ( ToroidalWrappedNormalDistribution, diff --git a/pyrecest/filters/von_mises_filter.py b/pyrecest/filters/von_mises_filter.py index e8e9461a..369898bf 100644 --- a/pyrecest/filters/von_mises_filter.py +++ b/pyrecest/filters/von_mises_filter.py @@ -2,6 +2,7 @@ import warnings from math import pi +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import mod from pyrecest.distributions import VonMisesDistribution diff --git a/pyrecest/filters/von_mises_fisher_filter.py b/pyrecest/filters/von_mises_fisher_filter.py index d0ace6b9..4dcc3626 100644 --- a/pyrecest/filters/von_mises_fisher_filter.py +++ b/pyrecest/filters/von_mises_fisher_filter.py @@ -1,3 +1,4 @@ +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, ndim from pyrecest.distributions import VonMisesFisherDistribution diff --git a/pyrecest/filters/wrapped_normal_filter.py b/pyrecest/filters/wrapped_normal_filter.py index 742fd9db..333ba4b6 100644 --- a/pyrecest/filters/wrapped_normal_filter.py +++ b/pyrecest/filters/wrapped_normal_filter.py @@ -2,6 +2,7 @@ from functools import partial from math import pi +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, log, max, min, mod from pyrecest.distributions import CircularDiracDistribution, WrappedNormalDistribution from pyrecest.filters.abstract_circular_filter import AbstractCircularFilter diff --git a/pyrecest/sampling/euclidean_sampler.py b/pyrecest/sampling/euclidean_sampler.py index 43daaa05..b443d225 100644 --- a/pyrecest/sampling/euclidean_sampler.py +++ b/pyrecest/sampling/euclidean_sampler.py @@ -1,3 +1,4 @@ +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import eye, zeros from pyrecest.distributions import GaussianDistribution diff --git a/pyrecest/sampling/hyperspherical_sampler.py b/pyrecest/sampling/hyperspherical_sampler.py index cbc45f97..d0f7ac59 100644 --- a/pyrecest/sampling/hyperspherical_sampler.py +++ b/pyrecest/sampling/hyperspherical_sampler.py @@ -2,6 +2,7 @@ from abc import abstractmethod from math import pi +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import ( arange, arccos, diff --git a/pyrecest/sampling/hypertoroidal_sampler.py b/pyrecest/sampling/hypertoroidal_sampler.py index df38309b..9ca1ff73 100644 --- a/pyrecest/sampling/hypertoroidal_sampler.py +++ b/pyrecest/sampling/hypertoroidal_sampler.py @@ -1,5 +1,6 @@ from math import pi +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import linspace from pyrecest.distributions import CircularUniformDistribution diff --git a/pyrecest/tests/distributions/test_abstract_circular_distribution.py b/pyrecest/tests/distributions/test_abstract_circular_distribution.py index 04b3c4ca..081370f6 100644 --- a/pyrecest/tests/distributions/test_abstract_circular_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_circular_distribution.py @@ -1,7 +1,9 @@ import unittest from math import pi +# pylint: disable=no-name-in-module,no-member import pyrecest.backend +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import allclose, arange, array from pyrecest.distributions import VonMisesDistribution, WrappedNormalDistribution diff --git a/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py b/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py index 68248b84..345e3b6b 100644 --- a/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py @@ -2,7 +2,9 @@ from math import pi import numpy.testing as npt +# pylint: disable=no-name-in-module,no-member import pyrecest.backend +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import allclose, arange, array, column_stack, diff, ones, zeros from pyrecest.distributions.cart_prod.partially_wrapped_normal_distribution import ( PartiallyWrappedNormalDistribution, diff --git a/pyrecest/tests/distributions/test_abstract_hyperhemispherical_distribution.py b/pyrecest/tests/distributions/test_abstract_hyperhemispherical_distribution.py index 34cdcc0c..b3bc8113 100644 --- a/pyrecest/tests/distributions/test_abstract_hyperhemispherical_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hyperhemispherical_distribution.py @@ -3,7 +3,8 @@ import numpy.testing as npt -# pylint: disable=redefined-builtin +# pylint: disable=redefined-builtin,no-name-in-module,no-member +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, linalg, ones, sum from pyrecest.distributions import ( HyperhemisphericalWatsonDistribution, diff --git a/pyrecest/tests/distributions/test_abstract_hypersphere_subset_distribution.py b/pyrecest/tests/distributions/test_abstract_hypersphere_subset_distribution.py index 3a8dd488..4442e87f 100644 --- a/pyrecest/tests/distributions/test_abstract_hypersphere_subset_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hypersphere_subset_distribution.py @@ -1,6 +1,7 @@ import unittest import numpy.testing as npt +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, cos, linalg, sin from pyrecest.distributions import VonMisesFisherDistribution diff --git a/pyrecest/tests/distributions/test_abstract_hyperspherical_distribution.py b/pyrecest/tests/distributions/test_abstract_hyperspherical_distribution.py index fb83bb2a..c27b43bc 100644 --- a/pyrecest/tests/distributions/test_abstract_hyperspherical_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hyperspherical_distribution.py @@ -2,6 +2,7 @@ from math import pi import matplotlib +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, linalg, sqrt from pyrecest.distributions import ( AbstractHypersphericalDistribution, diff --git a/pyrecest/tests/distributions/test_abstract_hypertoroidal_distribution.py b/pyrecest/tests/distributions/test_abstract_hypertoroidal_distribution.py index acbad876..62674c19 100644 --- a/pyrecest/tests/distributions/test_abstract_hypertoroidal_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hypertoroidal_distribution.py @@ -2,6 +2,7 @@ from math import pi import numpy.testing as npt +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import array from pyrecest.distributions import AbstractHypertoroidalDistribution diff --git a/pyrecest/tests/distributions/test_abstract_linear_distribution.py b/pyrecest/tests/distributions/test_abstract_linear_distribution.py index f3d3aa2b..e511cc07 100644 --- a/pyrecest/tests/distributions/test_abstract_linear_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_linear_distribution.py @@ -2,7 +2,9 @@ import matplotlib import numpy.testing as npt +# pylint: disable=no-name-in-module,no-member import pyrecest.backend +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, diag, isclose from pyrecest.distributions import ( AbstractLinearDistribution, diff --git a/pyrecest/tests/distributions/test_abstract_mixture.py b/pyrecest/tests/distributions/test_abstract_mixture.py index 483ef305..c3e344b7 100644 --- a/pyrecest/tests/distributions/test_abstract_mixture.py +++ b/pyrecest/tests/distributions/test_abstract_mixture.py @@ -1,6 +1,8 @@ import unittest +# pylint: disable=no-name-in-module,no-member import pyrecest.backend +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import allclose, array, eye, linalg, ones from pyrecest.distributions import VonMisesFisherDistribution from pyrecest.distributions.hypersphere_subset.custom_hyperhemispherical_distribution import ( diff --git a/pyrecest/tests/distributions/test_bingham_distribution.py b/pyrecest/tests/distributions/test_bingham_distribution.py index 3caf9728..1933fc77 100644 --- a/pyrecest/tests/distributions/test_bingham_distribution.py +++ b/pyrecest/tests/distributions/test_bingham_distribution.py @@ -1,6 +1,7 @@ import unittest import numpy.testing as npt +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import array from pyrecest.distributions import BinghamDistribution diff --git a/pyrecest/tests/distributions/test_circular_fourier_distribution.py b/pyrecest/tests/distributions/test_circular_fourier_distribution.py index 4d897097..3d2f9568 100644 --- a/pyrecest/tests/distributions/test_circular_fourier_distribution.py +++ b/pyrecest/tests/distributions/test_circular_fourier_distribution.py @@ -3,8 +3,10 @@ from math import pi import numpy.testing as npt +# pylint: disable=no-name-in-module,no-member import pyrecest.backend from parameterized import parameterized +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import arange, array, ceil, linspace, sqrt from pyrecest.distributions import ( CircularFourierDistribution, diff --git a/pyrecest/tests/distributions/test_circular_uniform_distribution.py b/pyrecest/tests/distributions/test_circular_uniform_distribution.py index bef2e597..9e1a18cd 100644 --- a/pyrecest/tests/distributions/test_circular_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_circular_uniform_distribution.py @@ -2,7 +2,9 @@ from math import pi import numpy.testing as npt +# pylint: disable=no-name-in-module,no-member import pyrecest.backend +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, ones from pyrecest.distributions.circle.circular_uniform_distribution import ( CircularUniformDistribution, diff --git a/pyrecest/tests/distributions/test_custom_hemispherical_distribution.py b/pyrecest/tests/distributions/test_custom_hemispherical_distribution.py index 32709d96..7061401a 100644 --- a/pyrecest/tests/distributions/test_custom_hemispherical_distribution.py +++ b/pyrecest/tests/distributions/test_custom_hemispherical_distribution.py @@ -1,6 +1,7 @@ import unittest import warnings +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import allclose, array, eye, linalg, ndim, random from pyrecest.distributions import ( BinghamDistribution, diff --git a/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py b/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py index 99ce619e..f05810fb 100644 --- a/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py +++ b/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py @@ -2,7 +2,9 @@ from math import pi import numpy.testing as npt +# pylint: disable=no-name-in-module,no-member import pyrecest.backend +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import arange, array, eye, linspace, meshgrid, random from pyrecest.distributions import ( GaussianDistribution, diff --git a/pyrecest/tests/distributions/test_custom_hyperrectangular_distribution.py b/pyrecest/tests/distributions/test_custom_hyperrectangular_distribution.py index 911cb4ed..9b24be7c 100644 --- a/pyrecest/tests/distributions/test_custom_hyperrectangular_distribution.py +++ b/pyrecest/tests/distributions/test_custom_hyperrectangular_distribution.py @@ -1,5 +1,6 @@ import unittest +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import allclose, array, column_stack, linspace, meshgrid, ones from pyrecest.distributions.custom_hyperrectangular_distribution import ( CustomHyperrectangularDistribution, diff --git a/pyrecest/tests/distributions/test_custom_hyperspherical_distribution.py b/pyrecest/tests/distributions/test_custom_hyperspherical_distribution.py index c2b9f16f..4a988807 100644 --- a/pyrecest/tests/distributions/test_custom_hyperspherical_distribution.py +++ b/pyrecest/tests/distributions/test_custom_hyperspherical_distribution.py @@ -1,5 +1,6 @@ import unittest +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import allclose, array, linalg, random from pyrecest.distributions import VonMisesFisherDistribution from pyrecest.distributions.hypersphere_subset.custom_hyperspherical_distribution import ( diff --git a/pyrecest/tests/distributions/test_custom_linear_distribution.py b/pyrecest/tests/distributions/test_custom_linear_distribution.py index c39aa1ee..1c98cb48 100644 --- a/pyrecest/tests/distributions/test_custom_linear_distribution.py +++ b/pyrecest/tests/distributions/test_custom_linear_distribution.py @@ -2,6 +2,7 @@ from math import pi import numpy.testing as npt +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, concatenate, eye, linspace, meshgrid from pyrecest.distributions import CustomLinearDistribution, GaussianDistribution from pyrecest.distributions.nonperiodic.gaussian_mixture import GaussianMixture diff --git a/pyrecest/tests/distributions/test_disk_uniform_distribution.py b/pyrecest/tests/distributions/test_disk_uniform_distribution.py index 9232884a..9b9ed907 100644 --- a/pyrecest/tests/distributions/test_disk_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_disk_uniform_distribution.py @@ -1,5 +1,6 @@ from math import pi +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, concatenate, ones, sqrt, zeros """ Test cases for DiskUniformDistribution""" diff --git a/pyrecest/tests/distributions/test_ellipsoidal_ball_uniform_distribution.py b/pyrecest/tests/distributions/test_ellipsoidal_ball_uniform_distribution.py index fe0f596c..fcb6361d 100644 --- a/pyrecest/tests/distributions/test_ellipsoidal_ball_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_ellipsoidal_ball_uniform_distribution.py @@ -1,6 +1,7 @@ import unittest import numpy.testing as npt +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, diag from pyrecest.distributions import EllipsoidalBallUniformDistribution diff --git a/pyrecest/tests/distributions/test_gaussian_distribution.py b/pyrecest/tests/distributions/test_gaussian_distribution.py index 5eeb5518..629ee8ec 100644 --- a/pyrecest/tests/distributions/test_gaussian_distribution.py +++ b/pyrecest/tests/distributions/test_gaussian_distribution.py @@ -1,6 +1,7 @@ import unittest import scipy +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import allclose, array, linspace from pyrecest.distributions import GaussianDistribution from scipy.stats import multivariate_normal diff --git a/pyrecest/tests/distributions/test_hemispherical_uniform_distribution.py b/pyrecest/tests/distributions/test_hemispherical_uniform_distribution.py index 6cbb0758..e9630cc1 100644 --- a/pyrecest/tests/distributions/test_hemispherical_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_hemispherical_uniform_distribution.py @@ -1,6 +1,7 @@ import unittest from math import pi +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import allclose, ones from pyrecest.distributions.hypersphere_subset.hemispherical_uniform_distribution import ( HemisphericalUniformDistribution, diff --git a/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py b/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py index e4fe2010..d419dffb 100644 --- a/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py @@ -3,7 +3,8 @@ import numpy.testing as npt -# pylint: disable=redefined-builtin +# pylint: disable=redefined-builtin,no-name-in-module,no-member +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import ( array, exp, diff --git a/pyrecest/tests/distributions/test_hyperhemispherical_uniform_distribution.py b/pyrecest/tests/distributions/test_hyperhemispherical_uniform_distribution.py index e7c9c054..26e81163 100644 --- a/pyrecest/tests/distributions/test_hyperhemispherical_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_hyperhemispherical_uniform_distribution.py @@ -2,6 +2,7 @@ import unittest from math import pi +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import allclose, linalg, ones, random, reshape from pyrecest.distributions import HyperhemisphericalUniformDistribution diff --git a/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py b/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py index db054af2..da51cfd1 100644 --- a/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py @@ -2,9 +2,11 @@ from math import pi import numpy.testing as npt +# pylint: disable=no-name-in-module,no-member import pyrecest.backend -# pylint: disable=redefined-builtin +# pylint: disable=redefined-builtin,no-name-in-module,no-member +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, linalg, mod, ones, random, sqrt, sum from pyrecest.distributions import VonMisesFisherDistribution from pyrecest.distributions.hypersphere_subset.hyperspherical_dirac_distribution import ( diff --git a/pyrecest/tests/distributions/test_hyperspherical_mixture.py b/pyrecest/tests/distributions/test_hyperspherical_mixture.py index b00beb0a..facaac73 100644 --- a/pyrecest/tests/distributions/test_hyperspherical_mixture.py +++ b/pyrecest/tests/distributions/test_hyperspherical_mixture.py @@ -3,7 +3,8 @@ from numpy.testing import assert_allclose -# pylint: disable=redefined-builtin +# pylint: disable=redefined-builtin,no-name-in-module,no-member +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import arange, array, linspace, meshgrid, sqrt, stack, sum from pyrecest.distributions import ( AbstractHypersphereSubsetDistribution, diff --git a/pyrecest/tests/distributions/test_hyperspherical_uniform_distribution.py b/pyrecest/tests/distributions/test_hyperspherical_uniform_distribution.py index 6cff5157..724d9bb9 100644 --- a/pyrecest/tests/distributions/test_hyperspherical_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_hyperspherical_uniform_distribution.py @@ -1,3 +1,4 @@ +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import allclose, linalg, ones, random """ Test for uniform distribution on the hypersphere """ diff --git a/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py b/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py index 828c4dcf..474a0690 100644 --- a/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py @@ -4,7 +4,8 @@ import numpy.testing as npt -# pylint: disable=redefined-builtin +# pylint: disable=redefined-builtin,no-name-in-module,no-member +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, exp, mod, ones_like, outer, random, sum from pyrecest.distributions import ( HypertoroidalDiracDistribution, diff --git a/pyrecest/tests/distributions/test_hypertoroidal_wrapped_normal_distribution.py b/pyrecest/tests/distributions/test_hypertoroidal_wrapped_normal_distribution.py index 15f67a06..87fd205d 100644 --- a/pyrecest/tests/distributions/test_hypertoroidal_wrapped_normal_distribution.py +++ b/pyrecest/tests/distributions/test_hypertoroidal_wrapped_normal_distribution.py @@ -1,6 +1,7 @@ import unittest import numpy.testing as npt +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import array from pyrecest.distributions import HypertoroidalWNDistribution diff --git a/pyrecest/tests/distributions/test_linear_dirac_distribution.py b/pyrecest/tests/distributions/test_linear_dirac_distribution.py index dc1e5028..aafceabd 100644 --- a/pyrecest/tests/distributions/test_linear_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_linear_dirac_distribution.py @@ -1,6 +1,7 @@ import unittest import numpy.testing as npt +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import allclose, array, eye, random from pyrecest.distributions import GaussianDistribution from pyrecest.distributions.nonperiodic.linear_dirac_distribution import ( diff --git a/pyrecest/tests/distributions/test_linear_mixture.py b/pyrecest/tests/distributions/test_linear_mixture.py index 74801287..36183218 100644 --- a/pyrecest/tests/distributions/test_linear_mixture.py +++ b/pyrecest/tests/distributions/test_linear_mixture.py @@ -2,6 +2,7 @@ from warnings import catch_warnings, simplefilter import numpy.testing as npt +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, column_stack, diag, linspace, meshgrid from pyrecest.distributions import GaussianDistribution from pyrecest.distributions.nonperiodic.linear_mixture import LinearMixture diff --git a/pyrecest/tests/distributions/test_partially_wrapped_normal_distribution.py b/pyrecest/tests/distributions/test_partially_wrapped_normal_distribution.py index 40e2ebcf..25543064 100644 --- a/pyrecest/tests/distributions/test_partially_wrapped_normal_distribution.py +++ b/pyrecest/tests/distributions/test_partially_wrapped_normal_distribution.py @@ -2,6 +2,7 @@ import numpy.testing as npt import scipy.linalg +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, ones from pyrecest.distributions.cart_prod.partially_wrapped_normal_distribution import ( PartiallyWrappedNormalDistribution, diff --git a/pyrecest/tests/distributions/test_se3_dirac_distribution.py b/pyrecest/tests/distributions/test_se3_dirac_distribution.py index 7f11a031..faf62995 100644 --- a/pyrecest/tests/distributions/test_se3_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_se3_dirac_distribution.py @@ -1,6 +1,7 @@ import unittest -# pylint: disable=redefined-builtin +# pylint: disable=redefined-builtin,no-name-in-module,no-member +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, concatenate, diag, linalg, sum, tile from pyrecest.distributions import ( GaussianDistribution, diff --git a/pyrecest/tests/distributions/test_sphere_subset_distribution.py b/pyrecest/tests/distributions/test_sphere_subset_distribution.py index 81169e07..bc359c0e 100644 --- a/pyrecest/tests/distributions/test_sphere_subset_distribution.py +++ b/pyrecest/tests/distributions/test_sphere_subset_distribution.py @@ -3,6 +3,7 @@ import numpy.testing as npt from parameterized import parameterized +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import array from pyrecest.distributions.hypersphere_subset.abstract_sphere_subset_distribution import ( AbstractSphereSubsetDistribution, diff --git a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py index 8945798c..576c278a 100644 --- a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py +++ b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py @@ -4,7 +4,8 @@ import numpy.testing as npt from parameterized import parameterized -# pylint: disable=redefined-builtin +# pylint: disable=redefined-builtin,no-name-in-module,no-member +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import ( all, allclose, diff --git a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py index 6dab9881..81c7c9eb 100644 --- a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py +++ b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py @@ -4,6 +4,7 @@ import numpy.testing as npt from parameterized import parameterized +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import ( allclose, array, diff --git a/pyrecest/tests/distributions/test_toroidal_uniform_distribution.py b/pyrecest/tests/distributions/test_toroidal_uniform_distribution.py index f207b2ad..c354da79 100644 --- a/pyrecest/tests/distributions/test_toroidal_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_toroidal_uniform_distribution.py @@ -1,9 +1,11 @@ import unittest from math import pi +# pylint: disable=no-name-in-module,no-member import pyrecest.backend -# pylint: disable=redefined-builtin +# pylint: disable=redefined-builtin,no-name-in-module,no-member +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import all, allclose, array, ones, tile, zeros from pyrecest.distributions.hypertorus.toroidal_uniform_distribution import ( ToroidalUniformDistribution, diff --git a/pyrecest/tests/distributions/test_toroidal_von_mises_sine_distribution.py b/pyrecest/tests/distributions/test_toroidal_von_mises_sine_distribution.py index 48275bfe..0f416e75 100644 --- a/pyrecest/tests/distributions/test_toroidal_von_mises_sine_distribution.py +++ b/pyrecest/tests/distributions/test_toroidal_von_mises_sine_distribution.py @@ -2,8 +2,10 @@ from math import pi import numpy.testing as npt +# pylint: disable=no-name-in-module,no-member import pyrecest.backend from parameterized import parameterized +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import arange, array, column_stack, cos, exp, sin from pyrecest.distributions.hypertorus.toroidal_von_mises_sine_distribution import ( ToroidalVonMisesSineDistribution, diff --git a/pyrecest/tests/distributions/test_toroidal_wrapped_normal_distribution.py b/pyrecest/tests/distributions/test_toroidal_wrapped_normal_distribution.py index dc7a42c0..2959a4c1 100644 --- a/pyrecest/tests/distributions/test_toroidal_wrapped_normal_distribution.py +++ b/pyrecest/tests/distributions/test_toroidal_wrapped_normal_distribution.py @@ -1,7 +1,9 @@ import unittest from math import pi +# pylint: disable=no-name-in-module,no-member import pyrecest.backend +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import allclose, array, mod from pyrecest.distributions.hypertorus.toroidal_wrapped_normal_distribution import ( ToroidalWrappedNormalDistribution, diff --git a/pyrecest/tests/distributions/test_von_mises_distribution.py b/pyrecest/tests/distributions/test_von_mises_distribution.py index 5f5e9e99..319a43dd 100644 --- a/pyrecest/tests/distributions/test_von_mises_distribution.py +++ b/pyrecest/tests/distributions/test_von_mises_distribution.py @@ -3,6 +3,7 @@ import matplotlib import matplotlib.pyplot as plt import numpy.testing as npt +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, linspace from pyrecest.distributions import VonMisesDistribution diff --git a/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py b/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py index c7d44e45..32885dbd 100644 --- a/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py +++ b/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py @@ -2,6 +2,7 @@ import numpy.testing as npt from parameterized import parameterized +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import allclose, array, linalg, sqrt from pyrecest.distributions import VonMisesFisherDistribution from pyrecest.distributions.hypersphere_subset.hyperspherical_dirac_distribution import ( diff --git a/pyrecest/tests/distributions/test_watson_distribution.py b/pyrecest/tests/distributions/test_watson_distribution.py index 2cafc051..9ac6f260 100644 --- a/pyrecest/tests/distributions/test_watson_distribution.py +++ b/pyrecest/tests/distributions/test_watson_distribution.py @@ -1,6 +1,7 @@ import unittest import numpy.testing as npt +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, linalg from pyrecest.distributions import BinghamDistribution, WatsonDistribution diff --git a/pyrecest/tests/distributions/test_wrapped_cauchy_distribution.py b/pyrecest/tests/distributions/test_wrapped_cauchy_distribution.py index 54bed81c..4461fc1c 100644 --- a/pyrecest/tests/distributions/test_wrapped_cauchy_distribution.py +++ b/pyrecest/tests/distributions/test_wrapped_cauchy_distribution.py @@ -2,7 +2,9 @@ from math import pi import numpy.testing as npt +# pylint: disable=no-name-in-module,no-member import pyrecest.backend +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import arange, array from pyrecest.distributions.circle.custom_circular_distribution import ( CustomCircularDistribution, diff --git a/pyrecest/tests/distributions/test_wrapped_laplace_distribution.py b/pyrecest/tests/distributions/test_wrapped_laplace_distribution.py index 5cb50e79..fa882e9c 100644 --- a/pyrecest/tests/distributions/test_wrapped_laplace_distribution.py +++ b/pyrecest/tests/distributions/test_wrapped_laplace_distribution.py @@ -2,7 +2,9 @@ from math import pi import numpy.testing as npt +# pylint: disable=no-name-in-module,no-member import pyrecest.backend +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import arange, array, exp, linspace from pyrecest.distributions.circle.wrapped_laplace_distribution import ( WrappedLaplaceDistribution, diff --git a/pyrecest/tests/distributions/test_wrapped_normal_distribution.py b/pyrecest/tests/distributions/test_wrapped_normal_distribution.py index c7ec38e8..049aea33 100644 --- a/pyrecest/tests/distributions/test_wrapped_normal_distribution.py +++ b/pyrecest/tests/distributions/test_wrapped_normal_distribution.py @@ -3,7 +3,8 @@ import numpy.testing as npt -# pylint: disable=redefined-builtin +# pylint: disable=redefined-builtin,no-name-in-module,no-member +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import allclose, arange, array, exp, ones_like, sqrt, sum from pyrecest.distributions import WrappedNormalDistribution diff --git a/pyrecest/tests/filters/test_circular_particle_filter.py b/pyrecest/tests/filters/test_circular_particle_filter.py index e1969baa..4dd34ba9 100644 --- a/pyrecest/tests/filters/test_circular_particle_filter.py +++ b/pyrecest/tests/filters/test_circular_particle_filter.py @@ -2,6 +2,7 @@ from math import pi import numpy.testing as npt +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import allclose, arange, array, random from pyrecest.distributions import ( HypertoroidalDiracDistribution, diff --git a/pyrecest/tests/filters/test_euclidean_particle_filter.py b/pyrecest/tests/filters/test_euclidean_particle_filter.py index 891847fd..b795a492 100644 --- a/pyrecest/tests/filters/test_euclidean_particle_filter.py +++ b/pyrecest/tests/filters/test_euclidean_particle_filter.py @@ -2,6 +2,7 @@ from math import pi import numpy.testing as npt +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, mean, ones, random, zeros, zeros_like from pyrecest.distributions import GaussianDistribution from pyrecest.filters.euclidean_particle_filter import EuclideanParticleFilter diff --git a/pyrecest/tests/filters/test_global_nearest_neighbor.py b/pyrecest/tests/filters/test_global_nearest_neighbor.py index fcb3918f..44a12a08 100644 --- a/pyrecest/tests/filters/test_global_nearest_neighbor.py +++ b/pyrecest/tests/filters/test_global_nearest_neighbor.py @@ -1,11 +1,13 @@ import unittest import numpy.testing as npt +# pylint: disable=no-name-in-module,no-member import pyrecest.backend import scipy from parameterized import parameterized -# pylint: disable=redefined-builtin +# pylint: disable=redefined-builtin,no-name-in-module,no-member +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import ( all, allclose, diff --git a/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py b/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py index 41052e71..8ee26e73 100644 --- a/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py +++ b/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py @@ -2,6 +2,7 @@ from math import pi import numpy.testing as npt +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, random, zeros from pyrecest.distributions import HypertoroidalWNDistribution from pyrecest.filters import HypertoroidalParticleFilter diff --git a/pyrecest/tests/filters/test_kalman_filter.py b/pyrecest/tests/filters/test_kalman_filter.py index fa004374..e089040b 100644 --- a/pyrecest/tests/filters/test_kalman_filter.py +++ b/pyrecest/tests/filters/test_kalman_filter.py @@ -2,7 +2,9 @@ import unittest import numpy.testing as npt +# pylint: disable=no-name-in-module,no-member import pyrecest.backend +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import allclose, array, diag, eye from pyrecest.distributions import GaussianDistribution from pyrecest.filters.kalman_filter import KalmanFilter diff --git a/pyrecest/tests/filters/test_random_matrix_tracker.py b/pyrecest/tests/filters/test_random_matrix_tracker.py index 020af079..7d68cdeb 100644 --- a/pyrecest/tests/filters/test_random_matrix_tracker.py +++ b/pyrecest/tests/filters/test_random_matrix_tracker.py @@ -3,8 +3,10 @@ import matplotlib.pyplot as plt import numpy.testing as npt +# pylint: disable=no-name-in-module,no-member import pyrecest.backend from parameterized import parameterized +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, concatenate, diag, eye, linalg, mean, zeros from pyrecest.distributions.nonperiodic.gaussian_distribution import ( GaussianDistribution, diff --git a/pyrecest/tests/filters/test_toroidal_particle_filter.py b/pyrecest/tests/filters/test_toroidal_particle_filter.py index b37b219a..888d6058 100644 --- a/pyrecest/tests/filters/test_toroidal_particle_filter.py +++ b/pyrecest/tests/filters/test_toroidal_particle_filter.py @@ -1,6 +1,7 @@ import unittest from math import pi +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import allclose, array, random from pyrecest.distributions.hypertorus.hypertoroidal_wrapped_normal_distribution import ( HypertoroidalWrappedNormalDistribution, diff --git a/pyrecest/tests/filters/test_toroidal_wrapped_normal_filter.py b/pyrecest/tests/filters/test_toroidal_wrapped_normal_filter.py index bacf03b7..d7920706 100644 --- a/pyrecest/tests/filters/test_toroidal_wrapped_normal_filter.py +++ b/pyrecest/tests/filters/test_toroidal_wrapped_normal_filter.py @@ -2,6 +2,7 @@ from math import pi import numpy.testing as npt +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, mod from pyrecest.distributions.hypertorus.toroidal_wrapped_normal_distribution import ( ToroidalWrappedNormalDistribution, diff --git a/pyrecest/tests/filters/test_von_mises_filter.py b/pyrecest/tests/filters/test_von_mises_filter.py index 0d011563..0eb90585 100644 --- a/pyrecest/tests/filters/test_von_mises_filter.py +++ b/pyrecest/tests/filters/test_von_mises_filter.py @@ -1,6 +1,7 @@ import unittest import numpy.testing as npt +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import array from pyrecest.distributions import VonMisesDistribution from pyrecest.filters.von_mises_filter import VonMisesFilter diff --git a/pyrecest/tests/filters/test_von_mises_fisher_filter.py b/pyrecest/tests/filters/test_von_mises_fisher_filter.py index cfc7ff3a..fb25f18e 100644 --- a/pyrecest/tests/filters/test_von_mises_fisher_filter.py +++ b/pyrecest/tests/filters/test_von_mises_fisher_filter.py @@ -1,5 +1,6 @@ import unittest +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import allclose, array, cos, sin from pyrecest.distributions import VonMisesFisherDistribution from pyrecest.filters.von_mises_fisher_filter import VonMisesFisherFilter diff --git a/pyrecest/tests/filters/test_wrapped_normal_filter.py b/pyrecest/tests/filters/test_wrapped_normal_filter.py index ba7676de..b3595093 100644 --- a/pyrecest/tests/filters/test_wrapped_normal_filter.py +++ b/pyrecest/tests/filters/test_wrapped_normal_filter.py @@ -1,6 +1,7 @@ import unittest import numpy.testing as npt +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import array from pyrecest.distributions import WrappedNormalDistribution from pyrecest.filters.wrapped_normal_filter import WrappedNormalFilter diff --git a/pyrecest/tests/test_euclidean_sampler.py b/pyrecest/tests/test_euclidean_sampler.py index 68f30195..22da9805 100644 --- a/pyrecest/tests/test_euclidean_sampler.py +++ b/pyrecest/tests/test_euclidean_sampler.py @@ -1,5 +1,6 @@ import unittest +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import allclose, mean, ones, random, std, zeros from pyrecest.sampling.euclidean_sampler import GaussianSampler diff --git a/pyrecest/tests/test_evaluation_basic.py b/pyrecest/tests/test_evaluation_basic.py index c025b1b7..867d8f5f 100644 --- a/pyrecest/tests/test_evaluation_basic.py +++ b/pyrecest/tests/test_evaluation_basic.py @@ -7,8 +7,9 @@ import numpy.testing as npt from parameterized import parameterized -# pylint: disable=redefined-builtin -# pylint: disable=redefined-builtin +# pylint: disable=redefined-builtin,no-name-in-module,no-member +# pylint: disable=redefined-builtin,no-name-in-module,no-member +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import ( all, any, diff --git a/pyrecest/tests/test_hyperspherical_sampler.py b/pyrecest/tests/test_hyperspherical_sampler.py index 76077a84..0a458f0a 100644 --- a/pyrecest/tests/test_hyperspherical_sampler.py +++ b/pyrecest/tests/test_hyperspherical_sampler.py @@ -1,6 +1,7 @@ import importlib.util import unittest +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import allclose, linalg, prod, random healpy_installed = importlib.util.find_spec("healpy") is not None diff --git a/pyrecest/tests/test_hypertoroidal_sampler.py b/pyrecest/tests/test_hypertoroidal_sampler.py index 562c4932..21f08f51 100644 --- a/pyrecest/tests/test_hypertoroidal_sampler.py +++ b/pyrecest/tests/test_hypertoroidal_sampler.py @@ -3,7 +3,8 @@ import numpy.testing as npt -# pylint: disable=redefined-builtin +# pylint: disable=redefined-builtin,no-name-in-module,no-member +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import all, diff, std from pyrecest.sampling.hypertoroidal_sampler import CircularUniformSampler diff --git a/pyrecest/tests/test_metrics.py b/pyrecest/tests/test_metrics.py index b07ae58d..189db8c3 100644 --- a/pyrecest/tests/test_metrics.py +++ b/pyrecest/tests/test_metrics.py @@ -1,6 +1,7 @@ import unittest import numpy.testing as npt +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, random, repeat from pyrecest.utils.metrics import anees diff --git a/pyrecest/utils/metrics.py b/pyrecest/utils/metrics.py index dccbcf66..ee45e96c 100644 --- a/pyrecest/utils/metrics.py +++ b/pyrecest/utils/metrics.py @@ -1,3 +1,4 @@ +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import linalg, mean, zeros diff --git a/pyrecest/utils/plotting.py b/pyrecest/utils/plotting.py index 4b8ba2ec..971dadc5 100644 --- a/pyrecest/utils/plotting.py +++ b/pyrecest/utils/plotting.py @@ -1,6 +1,7 @@ from math import pi import matplotlib.pyplot as plt +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import ( array, column_stack, From 100337e426778b9e33ecc90a70613a09efc2c47d Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 23 Oct 2023 20:03:02 +0100 Subject: [PATCH 145/232] More --- .../evaluation/determine_all_deviations.py | 19 ++-- pyrecest/evaluation/eot_shape_database.py | 51 ++++----- pyrecest/evaluation/evaluate_for_file.py | 17 ++- .../evaluate_for_simulation_config.py | 22 +++- pyrecest/evaluation/evaluate_for_variables.py | 2 + pyrecest/evaluation/generate_groundtruth.py | 8 +- pyrecest/evaluation/generate_measurements.py | 33 +++--- .../generate_simulated_scenarios.py | 7 +- pyrecest/evaluation/get_distance_function.py | 11 +- .../evaluation/iterate_configs_and_runs.py | 11 +- .../perform_predict_update_cycles.py | 13 +-- pyrecest/evaluation/plot_results.py | 41 ++++--- pyrecest/evaluation/simulation_database.py | 18 ++- .../evaluation/summarize_filter_results.py | 22 ++-- pyrecest/tests/test_evaluation_basic.py | 103 ++++++++---------- 15 files changed, 198 insertions(+), 180 deletions(-) diff --git a/pyrecest/evaluation/determine_all_deviations.py b/pyrecest/evaluation/determine_all_deviations.py index c82898b2..102722c0 100644 --- a/pyrecest/evaluation/determine_all_deviations.py +++ b/pyrecest/evaluation/determine_all_deviations.py @@ -2,12 +2,10 @@ from typing import Callable import numpy as np - -# pylint: disable=redefined-builtin,no-name-in-module,no-member -# pylint: disable=no-name-in-module,no-member -from pyrecest.backend import any, empty, isinf, ndim, sum +from beartype import beartype +@beartype def determine_all_deviations( results, extract_mean, @@ -19,16 +17,15 @@ def determine_all_deviations( raise NotImplementedError("Not implemented yet") assert ( - ndim(groundtruths) == 2 - and isinstance(groundtruths[0, 0], np.ndarray) - and ndim(groundtruths[0, 0]) + groundtruths.ndim == 2 + and groundtruths[0, 0].ndim in ( 1, 2, ) ), "Assuming groundtruths to be a 2-D array of shape (n_runs, n_timesteps) composed arrays of shape (n_dim,) or (n_targets,n_dim)." - all_deviations_last_mat = empty((len(results), groundtruths.shape[0])) + all_deviations_last_mat = np.empty((len(results), groundtruths.shape[0])) for config_no, result_curr_config in enumerate(results): for run in range(len(groundtruths)): @@ -47,12 +44,12 @@ def determine_all_deviations( ) else: warnings.warn("No estimate for this filter, setting error to inf.") - all_deviations_last_mat[config_no][run] = float("inf") + all_deviations_last_mat[config_no][run] = np.inf - if any(isinf(all_deviations_last_mat[config_no])): + if np.any(np.isinf(all_deviations_last_mat[config_no])): print( f"Warning: {result_curr_config['filterName']} with {result_curr_config['filterParams']} " - f"parameters apparently failed {sum(isinf(all_deviations_last_mat[config_no]))} " + f"parameters apparently failed {np.sum(np.isinf(all_deviations_last_mat[config_no]))} " "times. Check if this is plausible." ) diff --git a/pyrecest/evaluation/eot_shape_database.py b/pyrecest/evaluation/eot_shape_database.py index 4b39a68f..92d5adba 100644 --- a/pyrecest/evaluation/eot_shape_database.py +++ b/pyrecest/evaluation/eot_shape_database.py @@ -1,7 +1,4 @@ -from math import pi - -# pylint: disable=no-name-in-module,no-member -from pyrecest.backend import array, cos, empty, linspace, random, sin +import numpy as np from shapely.geometry import LineString, MultiLineString, Point, Polygon from shapely.ops import unary_union @@ -14,8 +11,8 @@ def __new__(cls, shell=None, holes=None): # nosec polygon.__class__ = cls return polygon - def sample_on_boundary(self, num_points: int): - points = empty((num_points,), dtype=Point) + def sample_on_boundary(self, num_points: int) -> np.ndarray: + points = np.empty((num_points,), dtype=Point) if isinstance(self.boundary, LineString): lines = [self.boundary] @@ -27,7 +24,7 @@ def sample_on_boundary(self, num_points: int): perimeter = self.length # Generate a random distance along the perimeter - distance = random.uniform(0, perimeter) + distance = np.random.uniform(0, perimeter) # Traverse the edges to place the point for line in lines: @@ -36,27 +33,27 @@ def sample_on_boundary(self, num_points: int): break distance -= line.length - return array([(point.x, point.y) for point in points]) + return np.array([(point.x, point.y) for point in points]) - def sample_within(self, num_points: int): + def sample_within(self, num_points: int) -> np.ndarray: min_x, min_y, max_x, max_y = self.bounds - points = empty((num_points,), dtype=Point) + points = np.empty((num_points,), dtype=Point) for i in range(num_points): random_point = Point( - [random.uniform(min_x, max_x), random.uniform(min_y, max_y)] + [np.random.uniform(min_x, max_x), np.random.uniform(min_y, max_y)] ) while not random_point.within(self): random_point = Point( [ - random.uniform(min_x, max_x), - random.uniform(min_y, max_y), + np.random.uniform(min_x, max_x), + np.random.uniform(min_y, max_y), ] ) points[i] = random_point - return array(points) + return np.array(points) class StarShapedPolygon(PolygonWithSampling): # pylint: disable=abstract-method @@ -106,8 +103,8 @@ def compute_visibility_polygon(self, point): segments.append(line_of_sight) # Check for intersections along the direction to the vertex - direction = array(vertex) - array(point.coords) - far_away_point = Point(array(vertex) + 1000 * direction) + direction = np.array(vertex) - np.array(point.coords) + far_away_point = Point(np.array(vertex) + 1000 * direction) ray = LineString([point, far_away_point]) # Find intersection points with the polygon boundary @@ -130,7 +127,7 @@ class Star(StarShapedPolygon): # pylint: disable=abstract-method __slots__ = Polygon.__slots__ def __new__(cls, radius=1, arms=5, arm_width=0.3, center=(0, 0)): - arm_angle = 2 * pi / arms + arm_angle = 2 * np.pi / arms points = [] for i in range(arms): base_angle = i * arm_angle @@ -138,15 +135,15 @@ def __new__(cls, radius=1, arms=5, arm_width=0.3, center=(0, 0)): # External point points.append( ( - center[0] + radius * cos(base_angle), - center[1] + radius * sin(base_angle), + center[0] + radius * np.cos(base_angle), + center[1] + radius * np.sin(base_angle), ) ) # Internal point points.append( ( - center[0] + arm_width * cos(inner_angle), - center[1] + arm_width * sin(inner_angle), + center[0] + arm_width * np.cos(inner_angle), + center[1] + arm_width * np.sin(inner_angle), ) ) # Close the loop @@ -168,7 +165,7 @@ def __new__(cls, height_1, height_2, width_1, width_2, centroid=None): # Use a default centroid if none is provided if centroid is None: - centroid = array([0, 0]) + centroid = [0, 0] # Calculate half dimensions for clarity half_height_1 = height_1 / 2 @@ -177,7 +174,7 @@ def __new__(cls, height_1, height_2, width_1, width_2, centroid=None): half_width_2 = width_2 / 2 # Define polygon points - polygon_points = array( + polygon_points = np.array( [ [half_width_1, half_height_1], [half_height_2, half_height_1], @@ -209,11 +206,11 @@ class StarFish(StarShapedPolygon): # pylint: disable=abstract-method # pylint: disable=signature-differs def __new__(cls, scaling_factor=1): - theta = linspace(0, 2 * pi, 1000) - r = 5 + 1.5 * sin(6 * theta) + theta = np.linspace(0, 2 * np.pi, 1000) + r = 5 + 1.5 * np.sin(6 * theta) - x = r * cos(theta) * scaling_factor - y = r * sin(theta) * scaling_factor + x = r * np.cos(theta) * scaling_factor + y = r * np.sin(theta) * scaling_factor # Create polygon instance polygon = super().__new__(cls, shell=zip(x, y), holes=None) # nosec diff --git a/pyrecest/evaluation/evaluate_for_file.py b/pyrecest/evaluation/evaluate_for_file.py index c86af532..14f4de63 100644 --- a/pyrecest/evaluation/evaluate_for_file.py +++ b/pyrecest/evaluation/evaluate_for_file.py @@ -2,7 +2,6 @@ from typing import Any import numpy as np -from numpy import concatenate, ones, zeros from .evaluate_for_variables import evaluate_for_variables @@ -20,7 +19,15 @@ def evaluate_for_file( tolerate_failure: bool = False, auto_warning_on_off: bool = False, # jscpd:ignore-end -): +) -> tuple[ + dict, + list[dict], + np.ndarray, + np.ndarray, + np.ndarray, + np.ndarray, + np.ndarray[np.ndarray], +]: data = np.load(input_file_name, allow_pickle=True).item() if "name" not in scenario_config: @@ -32,7 +39,7 @@ def evaluate_for_file( else: scenario_config["n_timesteps"] = data["groundtruths"].shape[1] - n_meas_at_individual_time_step = zeros(data["measurements"].shape[1], dtype=int) + n_meas_at_individual_time_step = np.zeros(data["measurements"].shape[1], dtype=int) for idx, inner_array in enumerate(data["measurements"][0]): if inner_array.ndim == 2: @@ -45,7 +52,9 @@ def evaluate_for_file( ) scenario_config.setdefault( "apply_sys_noise_times", - concatenate([ones(scenario_config["n_timesteps"] - 1, dtype=bool), [False]]), + np.concatenate( + [np.ones(scenario_config["n_timesteps"] - 1, dtype=bool), [False]] + ), ) return evaluate_for_variables( diff --git a/pyrecest/evaluation/evaluate_for_simulation_config.py b/pyrecest/evaluation/evaluate_for_simulation_config.py index 5a5ee95c..780ededd 100644 --- a/pyrecest/evaluation/evaluate_for_simulation_config.py +++ b/pyrecest/evaluation/evaluate_for_simulation_config.py @@ -1,6 +1,9 @@ import random from typing import Any, Optional +import numpy as np +from beartype import beartype + from .evaluate_for_variables import evaluate_for_variables from .generate_simulated_scenarios import generate_simulated_scenarios from .simulation_database import simulation_database @@ -13,7 +16,7 @@ def evaluate_for_simulation_config( filter_configs: list[dict[str, Any]], n_runs: int, n_timesteps: Optional[int] = None, - initial_seed=None, + initial_seed: Optional[int | np.uint32] = None, consecutive_seed: bool = False, save_folder: str = ".", scenario_customization_params: Optional[dict] = None, @@ -23,7 +26,15 @@ def evaluate_for_simulation_config( tolerate_failure: bool = False, auto_warning_on_off: bool = False, # jscpd:ignore-end -): +) -> tuple[ + dict, + list[dict], + np.ndarray, + np.ndarray, + np.ndarray, + np.ndarray, + np.ndarray[np.ndarray], +]: if isinstance(simulation_config, str): simulation_name = simulation_config simulation_config = simulation_database( @@ -59,13 +70,14 @@ def evaluate_for_simulation_config( ) +@beartype def get_all_seeds(n_runs: int, seed_input=None, consecutive_seed: bool = True): if seed_input is None: - seed_input = random.randint(1, 0xFFFFFFFF) # nosec + seed_input = np.uint32(random.randint(1, 0xFFFFFFFF)) # nosec - if seed_input.shape[0] == n_runs: + if np.size(seed_input) == n_runs: all_seeds = seed_input - elif seed_input.shape[0] == 1 and n_runs > 1: + elif np.size(seed_input) == 1 and n_runs > 1: if consecutive_seed: all_seeds = list(range(seed_input, seed_input + n_runs)) else: diff --git a/pyrecest/evaluation/evaluate_for_variables.py b/pyrecest/evaluation/evaluate_for_variables.py index 2c821f03..184e7247 100644 --- a/pyrecest/evaluation/evaluate_for_variables.py +++ b/pyrecest/evaluation/evaluate_for_variables.py @@ -2,6 +2,8 @@ import os from typing import Any +import numpy as np + from .iterate_configs_and_runs import iterate_configs_and_runs diff --git a/pyrecest/evaluation/generate_groundtruth.py b/pyrecest/evaluation/generate_groundtruth.py index 0e327a7f..8ee97738 100644 --- a/pyrecest/evaluation/generate_groundtruth.py +++ b/pyrecest/evaluation/generate_groundtruth.py @@ -1,6 +1,6 @@ import numpy as np -from numpy import atleast_2d, empty, empty_like, ndim, squeeze +from pyrecest.backend import empty, atleast_2d, empty_like, squeeze # pylint: disable=too-many-branches def generate_groundtruth(simulation_param, x0=None): @@ -12,7 +12,7 @@ def generate_groundtruth(simulation_param, x0=None): x0 (ndarray): Starting point (optional). Returns: - groundtruth ([]): Generated ground truth as an + groundtruth (np.ndarray[np.ndarray]): Generated ground truth as an array of arrays (!) because the size of the ground truth is not necessarily the same over time (e.g., if the number of targets changes) """ @@ -20,13 +20,13 @@ def generate_groundtruth(simulation_param, x0=None): x0 = simulation_param["initial_prior"].sample(simulation_param["n_targets"]) assert ( - ndim(x0) == 1 + x0.ndim == 1 and simulation_param["n_targets"] == 1 or x0.shape[0] == simulation_param["n_targets"] ), "Mismatch in number of targets." # Initialize ground truth - groundtruth = empty(simulation_param["n_timesteps"], dtype=np.ndarray) + groundtruth = np.empty(simulation_param["n_timesteps"], dtype=object) if "inputs" in simulation_param: assert ( diff --git a/pyrecest/evaluation/generate_measurements.py b/pyrecest/evaluation/generate_measurements.py index aab5c926..047ae963 100644 --- a/pyrecest/evaluation/generate_measurements.py +++ b/pyrecest/evaluation/generate_measurements.py @@ -1,7 +1,7 @@ -from math import pi - import numpy as np -from numpy import dot, empty, mod, random, shape, squeeze, sum, tile, zeros +from math import pi +from pyrecest.backend import tile, squeeze, sum, zeros, mod +from beartype import beartype from pyrecest.distributions import ( AbstractHypertoroidalDistribution, GaussianDistribution, @@ -29,10 +29,8 @@ def generate_measurements(groundtruth, simulation_config): Comprises timesteps elements, each of which is a numpy array of shape (n_meas_at_individual_time_step[t], n_dim). """ - assert "n_meas_at_individual_time_step" not in simulation_config or shape( - simulation_config["n_meas_at_individual_time_step"] - ) == (simulation_config["n_timesteps"],) - measurements = empty(simulation_config["n_timesteps"], dtype=np.ndarray) + assert "n_meas_at_individual_time_step" not in simulation_config or np.shape(simulation_config["n_meas_at_individual_time_step"]) == (simulation_config["n_timesteps"],) + measurements = np.empty(simulation_config["n_timesteps"], dtype=object) if simulation_config.get("mtt", False) and simulation_config.get("eot", False): raise NotImplementedError( @@ -49,23 +47,21 @@ def generate_measurements(groundtruth, simulation_config): assert ("intensity_lambda" in simulation_config.keys()) != ( "n_meas_at_individual_time_step" in simulation_config.keys() ), "Must either give intensity_lambda or n_meas_at_individual_time_step for EOT" - target_shape = simulation_config["target_shape"] + shape = simulation_config["target_shape"] eot_sampling_style = simulation_config["eot_sampling_style"] assert isinstance( - target_shape, Polygon + shape, Polygon ), "Currently only StarConvexPolygon (based on shapely Polygons) are supported as target shapes." for t in range(simulation_config["n_timesteps"]): if groundtruth[0].shape[-1] == 2: curr_shape = translate( - target_shape, groundtruth[0][..., 0], yoff=groundtruth[0][..., 1] + shape, groundtruth[0][..., 0], yoff=groundtruth[0][..., 1] ) elif groundtruth[0].shape[-1] == 3: curr_shape = rotate( translate( - target_shape, - groundtruth[0][..., 1], - yoff=groundtruth[0][..., 2], + shape, groundtruth[0][..., 1], yoff=groundtruth[0][..., 2] ), angle=groundtruth[0][..., 0], origin="centroid", @@ -74,7 +70,7 @@ def generate_measurements(groundtruth, simulation_config): raise ValueError( "Currently only R^2 and SE(2) scenarios are supported." ) - if not isinstance(target_shape, PolygonWithSampling): + if not isinstance(shape, PolygonWithSampling): curr_shape.__class__ = ( PolygonWithSampling # Evil class sugery to add sampling methods ) @@ -112,7 +108,7 @@ def generate_measurements(groundtruth, simulation_config): simulation_config["clutter_rate"] == 0 ), "Clutter currently not supported." - n_observations = random.binomial( + n_observations = np.random.binomial( 1, simulation_config["detection_probability"], (simulation_config["n_timesteps"], simulation_config["n_targets"]), @@ -120,7 +116,7 @@ def generate_measurements(groundtruth, simulation_config): for t in range(simulation_config["n_timesteps"]): n_meas_at_t = sum(n_observations[t, :]) - measurements[t] = float("NaN") * zeros( + measurements[t] = float('NaN') * zeros( (simulation_config["meas_matrix_for_each_target"].shape[0], n_meas_at_t) ) @@ -128,7 +124,7 @@ def generate_measurements(groundtruth, simulation_config): for target_no in range(simulation_config["n_targets"]): if n_observations[t, target_no] == 1: meas_no += 1 - measurements[t][meas_no - 1, :] = dot( + measurements[t][meas_no - 1, :] = np.dot( simulation_config["meas_matrix_for_each_target"], groundtruth[t, target_no, :], ) + simulation_config["meas_noise"].sample(1) @@ -161,7 +157,7 @@ def generate_measurements(groundtruth, simulation_config): ) + noise_samples ), - 2 * pi, + 2.0 * pi, ) elif isinstance( @@ -187,6 +183,7 @@ def generate_measurements(groundtruth, simulation_config): return measurements +@beartype def generate_n_measurements_PPP(area: float, intensity_lambda: float) -> int: # Compute the expected number of points expected_num_points = intensity_lambda * area diff --git a/pyrecest/evaluation/generate_simulated_scenarios.py b/pyrecest/evaluation/generate_simulated_scenarios.py index 30d58e9e..46a5c7cf 100644 --- a/pyrecest/evaluation/generate_simulated_scenarios.py +++ b/pyrecest/evaluation/generate_simulated_scenarios.py @@ -1,5 +1,4 @@ import numpy as np -from numpy import empty, random from .check_and_fix_config import check_and_fix_config from .generate_groundtruth import generate_groundtruth @@ -22,17 +21,17 @@ def generate_simulated_scenarios( """ simulation_params = check_and_fix_config(simulation_params) - groundtruths = empty( + groundtruths = np.empty( (np.size(simulation_params["all_seeds"]), simulation_params["n_timesteps"]), dtype=np.ndarray, ) - measurements = empty( + measurements = np.empty( (np.size(simulation_params["all_seeds"]), simulation_params["n_timesteps"]), dtype=np.ndarray, ) for run, seed in enumerate(simulation_params["all_seeds"]): - random.seed(seed) + np.random.seed(seed) groundtruths[run, :] = generate_groundtruth(simulation_params) measurements[run, :] = generate_measurements( groundtruths[run, :], simulation_params diff --git a/pyrecest/evaluation/get_distance_function.py b/pyrecest/evaluation/get_distance_function.py index 54eec690..9cc158c7 100644 --- a/pyrecest/evaluation/get_distance_function.py +++ b/pyrecest/evaluation/get_distance_function.py @@ -1,6 +1,5 @@ +import numpy as np from numpy.linalg import norm -# pylint: disable=no-name-in-module,no-member -from pyrecest.backend import arccos, dot from pyrecest.distributions import AbstractHypertoroidalDistribution @@ -18,12 +17,12 @@ def distance_function(xest, xtrue): elif "hypersphere" in manifold_name: def distance_function(x1, x2): - return arccos(dot(x1, x2)) + return np.arccos(np.dot(x1, x2)) elif "hypersphereSymmetric" in manifold_name: def distance_function(x1, x2): - return min(arccos(dot(x1, x2)), arccos(dot(x1, -x2))) + return min(np.arccos(np.dot(x1, x2)), np.arccos(np.dot(x1, -x2))) elif "se2" in manifold_name or "se2linear" in manifold_name: @@ -45,7 +44,9 @@ def distance_function(x1, x2): elif "se3bounded" in manifold_name: def distance_function(x1, x2): - return min(arccos(dot(x1[:4], x2[:4])), arccos(dot(x1[:4], -x2[:4]))) + return min( + np.arccos(np.dot(x1[:4], x2[:4])), np.arccos(np.dot(x1[:4], -x2[:4])) + ) elif ( "euclidean" in manifold_name or "Euclidean" in manifold_name diff --git a/pyrecest/evaluation/iterate_configs_and_runs.py b/pyrecest/evaluation/iterate_configs_and_runs.py index 76364707..794a809e 100644 --- a/pyrecest/evaluation/iterate_configs_and_runs.py +++ b/pyrecest/evaluation/iterate_configs_and_runs.py @@ -1,8 +1,7 @@ import warnings from typing import Any, Dict -# pylint: disable=no-name-in-module,no-member -from pyrecest.backend import empty, zeros +import numpy as np from .perform_predict_update_cycles import perform_predict_update_cycles @@ -21,15 +20,15 @@ def iterate_configs_and_runs( ) raise NotImplementedError("This is not implemented yet.") - n_configs = sum((f["parameter"]).shape[0] for f in filter_configs) + n_configs = sum(np.size(f["parameter"]) for f in filter_configs) n_runs = groundtruths.shape[0] - run_times = empty((n_configs, n_runs)) - run_failed = zeros((n_configs, n_runs), dtype=bool) + run_times = np.empty((n_configs, n_runs)) + run_failed = np.zeros((n_configs, n_runs), dtype=bool) if evaluation_config["convert_to_point_estimate_during_runtime"]: raise NotImplementedError("This is not implemented yet.") - last_filter_states = empty((n_configs, n_runs), dtype=object) + last_filter_states = np.empty((n_configs, n_runs), dtype=object) for run in range(n_runs): for config_no, filter_config in enumerate(filter_configs): diff --git a/pyrecest/evaluation/perform_predict_update_cycles.py b/pyrecest/evaluation/perform_predict_update_cycles.py index 7b3df706..1b63b37b 100644 --- a/pyrecest/evaluation/perform_predict_update_cycles.py +++ b/pyrecest/evaluation/perform_predict_update_cycles.py @@ -1,8 +1,7 @@ import time import warnings -# pylint: disable=no-name-in-module,no-member -from pyrecest.backend import array, atleast_2d, squeeze +import numpy as np from .configure_for_filter import configure_for_filter @@ -18,7 +17,7 @@ def perform_predict_update_cycles( cumulated_updates_preferred=None, ): if extract_all_estimates: - all_estimates = empty_like(groundtruth) + all_estimates = np.empty_like(groundtruth) else: all_estimates = None @@ -29,11 +28,11 @@ def perform_predict_update_cycles( # Check conditions for cumulative updates perform_cumulative_updates = cumulated_updates_preferred and any( - array(scenario_config["n_meas_at_individual_time_step"]) > 1 + np.array(scenario_config["n_meas_at_individual_time_step"]) > 1 ) if ( cumulated_updates_preferred - and any(array(scenario_config["n_meas_at_individual_time_step"]) > 1) + and any(np.array(scenario_config["n_meas_at_individual_time_step"]) > 1) and scenario_config.get("plot", False) ): warnings.warn("When plotting, measurements are fused sequentially.") @@ -50,14 +49,14 @@ def perform_predict_update_cycles( if perform_cumulative_updates: raise NotImplementedError("Cumulative updates not implemented yet.") - all_meas_curr_time_step = atleast_2d(measurements[t]) + all_meas_curr_time_step = np.atleast_2d(measurements[t]) n_updates = all_meas_curr_time_step.shape[0] for m in range(n_updates): curr_meas = all_meas_curr_time_step[m, :] if not scenario_config.get("use_likelihood", False): filter_obj.update_identity( - meas_noise=meas_noise_for_filter, measurement=squeeze(curr_meas) + meas_noise=meas_noise_for_filter, measurement=np.squeeze(curr_meas) ) # If plotting is required diff --git a/pyrecest/evaluation/plot_results.py b/pyrecest/evaluation/plot_results.py index 3a14950b..273ac830 100644 --- a/pyrecest/evaluation/plot_results.py +++ b/pyrecest/evaluation/plot_results.py @@ -1,10 +1,8 @@ import warnings import matplotlib.pyplot as plt - -# pylint: disable=redefined-builtin,no-name-in-module,no-member -# pylint: disable=no-name-in-module,no-member -from pyrecest.backend import any, array, isnan, ones, shape +import numpy as np +from beartype import beartype from .get_axis_label import get_axis_label from .group_results_by_filter import group_results_by_filter @@ -20,7 +18,7 @@ def plot_results( Args: filenames (str or list): File names to load results from. - plot_log (array of bool): Whether to plot in log scale for each axis. + plot_log (np.array of bool): Whether to plot in log scale for each axis. plot_stds (bool): Whether to plot standard deviations. omit_slow (bool): Whether to omit slow filters from plotting. @@ -33,10 +31,10 @@ def plot_results( print("Not all warnings are enabled.") # Expand plot_log to handle all plots (pad it) - if plot_log.shape in ((), (1,)): - plot_log = False * ones((2, 3), dtype=bool) + if np.size(plot_log) == 1: + plot_log = False * np.ones((2, 3), dtype=bool) else: - assert shape(plot_log) == (2, 3) + assert np.shape(plot_log) == (2, 3) plot_random_filter = True if filename is None: @@ -64,10 +62,10 @@ def plot_results( # Iterate over all possible names and plot the lines for those that were evaluated color, style_marker, style_line = get_plot_style_for_filter(curr_filter_name) - params = array(results_grouped[curr_filter_name]["parameter"]) - errors_mean = array(results_grouped[curr_filter_name]["error_mean"]) - errors_std = array(results_grouped[curr_filter_name]["error_std"]) - times_mean = array(results_grouped[curr_filter_name]["time_mean"]) + params = np.asarray(results_grouped[curr_filter_name]["parameter"]) + errors_mean = np.asarray(results_grouped[curr_filter_name]["error_mean"]) + errors_std = np.asarray(results_grouped[curr_filter_name]["error_std"]) + times_mean = np.asarray(results_grouped[curr_filter_name]["time_mean"]) if curr_filter_name.startswith("ff") or curr_filter_name == "htgf": params = params**state_dim @@ -76,7 +74,11 @@ def plot_results( # Plot errors plt.figure(0) - if params[0] is not None and not any(isnan(params)) and params.shape[0] > 1: + if ( + params[0] is not None + and not np.any(np.isnan(params)) + and np.size(params) > 1 + ): if plot_stds: plt.plot( params, @@ -111,7 +113,11 @@ def plot_results( # Plot times plt.figure(1) - if params[0] is not None and not any(isnan(params)) and params.shape[0] > 1: + if ( + params[0] is not None + and not np.any(np.isnan(params)) + and np.size(params) > 1 + ): plt.plot( params, times_factor * times_mean, @@ -137,7 +143,11 @@ def plot_results( # Plot errors over time plt.figure(2) - if params[0] is not None and not any(isnan(params)) and params.shape[0] > 1: + if ( + params[0] is not None + and not np.any(np.isnan(params)) + and np.size(params) > 1 + ): plt.plot( times_factor * times_mean, errors_mean, @@ -220,6 +230,7 @@ def get_plot_style_for_filter(filter_name): return color, style_marker, style_line +@beartype def long_name_to_short_name(short_name: str) -> str: """Get short name from long name.""" diff --git a/pyrecest/evaluation/simulation_database.py b/pyrecest/evaluation/simulation_database.py index 6ac9e89a..e20cc578 100644 --- a/pyrecest/evaluation/simulation_database.py +++ b/pyrecest/evaluation/simulation_database.py @@ -1,11 +1,13 @@ import warnings from typing import Optional -# pylint: disable=no-name-in-module,no-member -from pyrecest.backend import eye, zeros +import numpy as np +from beartype import beartype from pyrecest.distributions import GaussianDistribution +from pyrecest.backend import eye, zeros +@beartype def simulation_database( scenario_name: str = "custom", scenario_customization_params: Optional[dict] = None ) -> dict: @@ -26,9 +28,15 @@ def simulation_database( elif scenario_name == "R2randomWalk": simulation_param["manifold"] = "Euclidean" simulation_param["n_timesteps"] = 10 - simulation_param["initial_prior"] = GaussianDistribution(zeros(2), 0.5 * eye(2)) - simulation_param["meas_noise"] = GaussianDistribution(zeros(2), 0.5 * eye(2)) - simulation_param["sys_noise"] = GaussianDistribution(zeros(2), 0.5 * eye(2)) + simulation_param["initial_prior"] = GaussianDistribution( + zeros(2), 0.5 * eye(2) + ) + simulation_param["meas_noise"] = GaussianDistribution( + zeros(2), 0.5 * eye(2) + ) + simulation_param["sys_noise"] = GaussianDistribution( + zeros(2), 0.5 * eye(2) + ) simulation_param["gen_next_state_without_noise_is_vectorized"] = True else: raise ValueError("Scenario not recognized.") diff --git a/pyrecest/evaluation/summarize_filter_results.py b/pyrecest/evaluation/summarize_filter_results.py index 335f270a..df7fb0b6 100644 --- a/pyrecest/evaluation/summarize_filter_results.py +++ b/pyrecest/evaluation/summarize_filter_results.py @@ -1,8 +1,6 @@ import warnings -# pylint: disable=redefined-builtin,no-name-in-module,no-member -# pylint: disable=no-name-in-module,no-member -from pyrecest.backend import mean, std, sum +import numpy as np from .determine_all_deviations import determine_all_deviations from .get_distance_function import get_distance_function @@ -42,18 +40,18 @@ def summarize_filter_results( errors_all = determine_all_deviations( filter_results, extract_mean, distance_function, groundtruths ) - errors_mean = mean(errors_all, axis=1) - errors_std = std(errors_all, axis=1) - times_mean = mean(runtimes, axis=1) - failure_rates = sum(run_failed, axis=1) / run_failed.shape[1] + errors_mean = np.mean(errors_all, axis=1) + errors_std = np.std(errors_all, axis=1) + times_mean = np.mean(runtimes, axis=1) + failure_rates = np.sum(run_failed, axis=1) / run_failed.shape[1] results_summarized = filter_configs - for d, curr_err, curr_std, curr_time, curr_fail_rate in zip( + for d, err, std, time, fail_rate in zip( results_summarized, errors_mean, errors_std, times_mean, failure_rates ): - d["error_mean"] = curr_err - d["error_std"] = curr_std - d["time_mean"] = curr_time - d["failure_rate"] = curr_fail_rate + d["error_mean"] = err + d["error_std"] = std + d["time_mean"] = time + d["failure_rate"] = fail_rate return results_summarized diff --git a/pyrecest/tests/test_evaluation_basic.py b/pyrecest/tests/test_evaluation_basic.py index 867d8f5f..5b18ea57 100644 --- a/pyrecest/tests/test_evaluation_basic.py +++ b/pyrecest/tests/test_evaluation_basic.py @@ -3,27 +3,11 @@ import unittest from typing import Optional +from pyrecest.backend import array, sqrt, eye, zeros +import pyrecest.backend + import numpy as np -import numpy.testing as npt from parameterized import parameterized - -# pylint: disable=redefined-builtin,no-name-in-module,no-member -# pylint: disable=redefined-builtin,no-name-in-module,no-member -# pylint: disable=no-name-in-module,no-member -from pyrecest.backend import ( - all, - any, - array, - atleast_2d, - eye, - linalg, - ndim, - ones, - random, - shape, - sqrt, - zeros, -) from pyrecest.distributions import ( GaussianDistribution, HypertoroidalWrappedNormalDistribution, @@ -92,7 +76,7 @@ def test_plot_results(self): @parameterized.expand( [ - (zeros(2),), + (np.zeros(2),), (None,), ] ) @@ -100,18 +84,18 @@ def test_generate_gt_R2(self, x0): groundtruth = generate_groundtruth(self.simulation_param, x0) # Test if groundtruth and its content is as expected - self.assertEqual(shape(groundtruth), (self.n_timesteps_default,)) + self.assertEqual(np.shape(groundtruth), (self.n_timesteps_default,)) self.assertEqual( - shape(groundtruth[0]), (self.simulation_param["initial_prior"].dim,) + np.shape(groundtruth[0]), (self.simulation_param["initial_prior"].dim,) ) @parameterized.expand([(1,), (3,)]) def test_generate_measurements(self, n_meas): - self.simulation_param["n_meas_at_individual_time_step"] = n_meas * ones( + self.simulation_param["n_meas_at_individual_time_step"] = n_meas * np.ones( self.n_timesteps_default, dtype=int ) measurements = generate_measurements( - zeros( + np.zeros( (self.n_timesteps_default, self.simulation_param["initial_prior"].dim) ), self.simulation_param, @@ -120,7 +104,7 @@ def test_generate_measurements(self, n_meas): self.assertEqual(np.size(measurements), self.n_timesteps_default) for i in range(self.n_timesteps_default): self.assertEqual( - atleast_2d(measurements[i]).shape, + np.atleast_2d(measurements[i]).shape, ( self.simulation_param["n_meas_at_individual_time_step"][i], self.simulation_param["initial_prior"].dim, @@ -129,7 +113,7 @@ def test_generate_measurements(self, n_meas): @parameterized.expand([("boundary",), ("within",)]) def test_generate_measurements_eot(self, eot_sampling_style: str): - random.seed(0) + np.random.seed(0) simulation_param = { "eot": True, "intensity_lambda": 0.2, @@ -140,7 +124,7 @@ def test_generate_measurements_eot(self, eot_sampling_style: str): state_dim = 2 measurements = generate_measurements( - zeros((self.n_timesteps_default, state_dim)), + np.zeros((self.n_timesteps_default, state_dim)), simulation_param, ) @@ -149,14 +133,14 @@ def test_generate_measurements_eot(self, eot_sampling_style: str): [meas_at_timestep.shape[0] for meas_at_timestep in measurements] ) # If one measurement at every timestep, then the number is apparently not stochastic - self.assertFalse(all(n_meas_at_individual_time_step == 1)) + self.assertFalse(np.all(n_meas_at_individual_time_step == 1)) state_dim_at_individual_time_step = array( [meas_at_timestep.shape[-1] for meas_at_timestep in measurements] ) has_state_dim_all = state_dim_at_individual_time_step == state_dim has_dim_zero_all = state_dim_at_individual_time_step == 0 self.assertTrue( - all( + np.all( [ state_dim or dim_zero for state_dim, dim_zero in zip(has_state_dim_all, has_dim_zero_all) @@ -169,31 +153,29 @@ def test_generate_simulated_scenario(self): groundtruths, measurements = generate_simulated_scenarios(self.simulation_param) self.assertEqual( - shape(groundtruths), (self.n_runs_default, self.n_timesteps_default) + np.shape(groundtruths), (self.n_runs_default, self.n_timesteps_default) ) self.assertEqual( - shape(measurements), (self.n_runs_default, self.n_timesteps_default) + np.shape(measurements), (self.n_runs_default, self.n_timesteps_default) ) return groundtruths, measurements def test_determine_all_deviations(self): - import numpy as _np - def dummy_extract_mean(x): return x def dummy_distance_function(x, y): - return linalg.norm(x - y) + return np.linalg.norm(x - y) # Initialize the outer array with object type - groundtruths = _np.empty((3, 4), dtype=object) + groundtruths = np.empty((3, 4), dtype=object) # Populate each entry with (2,) arrays for i in range(3): for j in range(4): groundtruths[i, j] = array([i + j, i - j]) - results = array([groundtruths[:, -1], groundtruths[:, -1] + 1]) + results = np.array([groundtruths[:, -1], groundtruths[:, -1] + 1]) # Run the function and get the deviations matrix all_deviations = determine_all_deviations( @@ -207,13 +189,13 @@ def dummy_distance_function(x, y): assert len(all_deviations) == len(results) # Validate some of the results - npt.assert_allclose( + np.testing.assert_allclose( # Should be zeros as the lastEstimates match groundtruths all_deviations[0], [0.0, 0.0, 0.0], ) - npt.assert_allclose( - # Should be sqrt(2) away from groundtruths + np.testing.assert_allclose( + # Should be np.sqrt(2) away from groundtruths all_deviations[1], [sqrt(2), sqrt(2), sqrt(2)], ) @@ -221,10 +203,10 @@ def dummy_distance_function(x, y): def test_configure_kf(self): filterParam = {"name": "kf", "parameter": None} scenarioParam = { - "initial_prior": GaussianDistribution(array([0.0, 0.0]), eye(2)), + "initial_prior": GaussianDistribution(array([0, 0]), eye(2)), "inputs": None, "manifold_type": "Euclidean", - "meas_noise": GaussianDistribution(array([0.0, 0.0]), eye(2)), + "meas_noise": GaussianDistribution(array([0, 0]), eye(2)), } ( @@ -236,6 +218,7 @@ def test_configure_kf(self): self.assertIsInstance(configured_filter, KalmanFilter) self.assertIsNotNone(predictionRoutine) + self.assertTrue(meas_noise_for_filter.shape == (2, 2)) def test_configure_pf(self): filter_config = {"name": "pf", "parameter": 100} @@ -279,14 +262,16 @@ def test_perform_predict_update_cycles(self): ) = perform_predict_update_cycles( scenario_param, {"name": "kf", "parameter": None}, - zeros((self.n_timesteps_default, 2)), - generate_measurements(zeros((self.n_timesteps_default, 2)), scenario_param), + np.zeros((self.n_timesteps_default, 2)), + generate_measurements( + np.zeros((self.n_timesteps_default, 2)), scenario_param + ), ) self.assertIsInstance(time_elapsed, float) self.assertGreater(time_elapsed, 0) self.assertIsNotNone(last_filter_state) - # self.assertIsInstance(last_estimate, ) + self.assertIsInstance(last_estimate, np.ndarray) self.assertEqual(last_estimate.shape, (2,)) self.assertIsNone(all_estimates) @@ -297,7 +282,7 @@ def test_get_distance_function(self): callable(distance_function), f"Expected distanceFunction to be callable, but got {type(distance_function)}", ) - self.assertEqual(distance_function(array([0, 0]), array([0, 0])), 0) + self.assertEqual(distance_function(np.array([0, 0]), np.array([0, 0])), 0) def test_get_mean_calc(self): extract_mean = get_extract_mean("hypertorus") @@ -370,24 +355,28 @@ def _validate_eval_data( self.assertIsInstance(evaluation_config, dict) - self.assertEqual(shape(last_filter_states), (n_configs, self.n_runs_default)) - self.assertTrue(all(last_filter_states != None)) # noqa + self.assertEqual(np.shape(last_filter_states), (n_configs, self.n_runs_default)) + self.assertTrue(np.all(last_filter_states != None)) # noqa - self.assertEqual(shape(runtimes), (n_configs, self.n_runs_default)) + self.assertEqual(np.shape(runtimes), (n_configs, self.n_runs_default)) print(runtimes) - self.assertTrue(all(runtimes >= 0)) + self.assertTrue(np.all(runtimes > 0)) - self.assertEqual(shape(run_failed), (n_configs, self.n_runs_default)) - self.assertTrue(not any(run_failed)) + self.assertEqual(np.shape(run_failed), (n_configs, self.n_runs_default)) + self.assertTrue(not np.any(run_failed)) - self.assertEqual(ndim(groundtruths), 2) - # self.assertIsInstance(groundtruths[0, 0], ) - self.assertIn(ndim(groundtruths[0, 0]), (1, 2)) + self.assertEqual(np.ndim(groundtruths), 2) + self.assertIsInstance(groundtruths[0, 0], np.ndarray) + self.assertIn(np.ndim(groundtruths[0, 0]), (1, 2)) - self.assertEqual(ndim(measurements), 2) - # self.assertIsInstance(measurements[0, 0], ) - self.assertIn(ndim(measurements[0, 0]), (1, 2)) + self.assertEqual(np.ndim(measurements), 2) + self.assertIsInstance(measurements[0, 0], np.ndarray) + self.assertIn(np.ndim(measurements[0, 0]), (1, 2)) + @unittest.skipIf( + pyrecest.backend.__name__ == "pyrecest.pytorch", + reason="Not supported on PyTorch backend", + ) def test_evaluate_for_simulation_config_R2_random_walk(self): filters_configs_input = [ {"name": "kf", "parameter": None}, From 771825317e34b44c031bb1a44fab5c88cc6837e8 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 23 Oct 2023 20:14:15 +0100 Subject: [PATCH 146/232] More........ --- pyrecest/tests/test_evaluation_basic.py | 40 ++++++++++++++++++------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/pyrecest/tests/test_evaluation_basic.py b/pyrecest/tests/test_evaluation_basic.py index 5b18ea57..a9b05e84 100644 --- a/pyrecest/tests/test_evaluation_basic.py +++ b/pyrecest/tests/test_evaluation_basic.py @@ -3,7 +3,7 @@ import unittest from typing import Optional -from pyrecest.backend import array, sqrt, eye, zeros +from pyrecest.backend import array, sqrt, eye, zeros, all import pyrecest.backend import numpy as np @@ -80,6 +80,10 @@ def test_plot_results(self): (None,), ] ) + @unittest.skipIf( + pyrecest.backend.__name__ == "pyrecest.pytorch", + reason="Not supported on PyTorch backend", + ) def test_generate_gt_R2(self, x0): groundtruth = generate_groundtruth(self.simulation_param, x0) @@ -133,7 +137,7 @@ def test_generate_measurements_eot(self, eot_sampling_style: str): [meas_at_timestep.shape[0] for meas_at_timestep in measurements] ) # If one measurement at every timestep, then the number is apparently not stochastic - self.assertFalse(np.all(n_meas_at_individual_time_step == 1)) + self.assertFalse(all(n_meas_at_individual_time_step == 1)) state_dim_at_individual_time_step = array( [meas_at_timestep.shape[-1] for meas_at_timestep in measurements] ) @@ -249,6 +253,10 @@ def test_configure_unsupported_filter(self): with self.assertRaises(ValueError): configure_for_filter(filterParam, scenario_config) + @unittest.skipIf( + pyrecest.backend.__name__ == "pyrecest.pytorch", + reason="Not supported on PyTorch backend", + ) def test_perform_predict_update_cycles(self): scenario_name = "R2randomWalk" scenario_param = simulation_database(scenario_name) @@ -282,7 +290,7 @@ def test_get_distance_function(self): callable(distance_function), f"Expected distanceFunction to be callable, but got {type(distance_function)}", ) - self.assertEqual(distance_function(np.array([0, 0]), np.array([0, 0])), 0) + self.assertEqual(distance_function(array([0, 0]), array([0, 0])), 0) def test_get_mean_calc(self): extract_mean = get_extract_mean("hypertorus") @@ -312,6 +320,10 @@ def test_get_axis_label(self): ), ] ) + @unittest.skipIf( + pyrecest.backend.__name__ == "pyrecest.pytorch", + reason="Not supported on PyTorch backend", + ) def test_iterate_configs_and_runs(self, filter_configs): groundtruths, measurements = self.test_generate_simulated_scenario() evaluation_config = { @@ -412,6 +424,10 @@ def test_evaluate_for_simulation_config_R2_random_walk(self): measurements, ) + @unittest.skipIf( + pyrecest.backend.__name__ == "pyrecest.pytorch", + reason="Not supported on PyTorch backend", + ) def test_evaluate_for_file_R2_random_walk(self): self.simulation_param["all_seeds"] = range(self.n_runs_default) groundtruths, measurements = generate_simulated_scenarios(self.simulation_param) @@ -513,6 +529,10 @@ def test_group_results_by_filter(self): self.assertEqual(repackaged_data1, repackaged_data2) + @unittest.skipIf( + pyrecest.backend.__name__ == "pyrecest.pytorch", + reason="Not supported on PyTorch backend", + ) def test_summarize_filter_results(self): data = self._load_evaluation_data() results_summarized = summarize_filter_results(**data) @@ -523,16 +543,16 @@ def test_summarize_filter_results(self): time_mean = result["time_mean"] failure_rate = result["failure_rate"] - self.assertGreaterEqual(error_mean, 0) - self.assertLessEqual(error_mean, 2) + self.assertGreaterEqual(error_mean, 0.0) + self.assertLessEqual(error_mean, 2.0) - self.assertGreaterEqual(error_std, 0) - self.assertLessEqual(error_std, 1) + self.assertGreaterEqual(error_std, 0.0) + self.assertLessEqual(error_std, 1.0) - self.assertGreaterEqual(time_mean, 0) - self.assertLessEqual(time_mean, 1) + self.assertGreaterEqual(time_mean, 0.0) + self.assertLessEqual(time_mean, 1.0) - self.assertEqual(failure_rate, 0) + self.assertEqual(failure_rate, 0.0) if __name__ == "__main__": From 63e2d59a92285ff9640f353764f20e2b7a68add5 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 23 Oct 2023 20:21:24 +0100 Subject: [PATCH 147/232] More.... --- pyrecest/distributions/abstract_se3_distribution.py | 4 ++-- .../lin_hypersphere_cart_prod_dirac_distribution.py | 2 +- pyrecest/distributions/circle/von_mises_distribution.py | 2 +- pyrecest/tests/test_hyperspherical_sampler.py | 8 +++++--- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/pyrecest/distributions/abstract_se3_distribution.py b/pyrecest/distributions/abstract_se3_distribution.py index 9af55729..a4672dd8 100644 --- a/pyrecest/distributions/abstract_se3_distribution.py +++ b/pyrecest/distributions/abstract_se3_distribution.py @@ -53,9 +53,9 @@ def plot_state( @staticmethod def plot_point(se3point): # pylint: disable=too-many-locals - import numpy as _np - """Visualize just a point in the SE(3) domain (no uncertainties are considered)""" + import numpy as _np + q = _np.quaternion(*se3point[:4]) rotMat = quaternion.as_rotation_matrix(q) diff --git a/pyrecest/distributions/cart_prod/lin_hypersphere_cart_prod_dirac_distribution.py b/pyrecest/distributions/cart_prod/lin_hypersphere_cart_prod_dirac_distribution.py index 6260a05e..6cf72e63 100644 --- a/pyrecest/distributions/cart_prod/lin_hypersphere_cart_prod_dirac_distribution.py +++ b/pyrecest/distributions/cart_prod/lin_hypersphere_cart_prod_dirac_distribution.py @@ -1,4 +1,4 @@ -# pylint: disable=no-name-in-module,no-member +# pylint: disable=redefined-builtin,no-name-in-module,no-member from pyrecest.backend import abs, linalg, max from ..abstract_se3_distribution import AbstractSE3Distribution diff --git a/pyrecest/distributions/circle/von_mises_distribution.py b/pyrecest/distributions/circle/von_mises_distribution.py index 5ba9e867..a64ac349 100644 --- a/pyrecest/distributions/circle/von_mises_distribution.py +++ b/pyrecest/distributions/circle/von_mises_distribution.py @@ -1,6 +1,6 @@ from math import pi -# pylint: disable=no-name-in-module,no-member +# pylint: disable=redefined-builtin,no-name-in-module,no-member from pyrecest.backend import ( abs, arctan2, diff --git a/pyrecest/tests/test_hyperspherical_sampler.py b/pyrecest/tests/test_hyperspherical_sampler.py index 0a458f0a..c70a5ddf 100644 --- a/pyrecest/tests/test_hyperspherical_sampler.py +++ b/pyrecest/tests/test_hyperspherical_sampler.py @@ -21,7 +21,6 @@ class TestHypersphericalGridGenerationFunction(unittest.TestCase): - @unittest.skipIf(not healpy_installed, "healpy is not installed") @parameterized.expand( [ ("healpix", 2, 48, "n_side"), @@ -30,6 +29,7 @@ class TestHypersphericalGridGenerationFunction(unittest.TestCase): ("spherical_fibonacci", 12, 12, "n_samples"), ] ) + @unittest.skipIf(not healpy_installed, "healpy is not installed") def test_get_grid_sphere( self, method, grid_density_parameter, grid_points_expected, desc_key ): @@ -71,6 +71,7 @@ class TestHypersphericalSampler(unittest.TestCase): (SphericalFibonacciSampler(), 12, 12, "n_samples"), ] ) + @unittest.skipIf(not healpy_installed, "healpy is not installed") def test_samplers( self, sampler, grid_density_parameter, grid_points_expected, desc_key ): @@ -89,6 +90,7 @@ def test_samplers( self.assertEqual(grid_description[desc_key], grid_density_parameter) @parameterized.expand([(0, 72), (1, 648)]) + @unittest.skipIf(not healpy_installed, "healpy is not installed") def test_healpix_hopf_sampler(self, input_value, expected_grid_points): sampler = HealpixHopfSampler() dim = 3 @@ -127,9 +129,9 @@ class TestHopfConversion(unittest.TestCase): def test_conversion(self): # Generate a sample matrix of size (n, 4) containing unit vectors. n = 100 # sample size - random_vectors = random.randn(n, 4) + random_vectors = random.normal(0.0, 1.0, (n, 4)) unit_vectors = ( - random_vectors / linalg.norm(random_vectors, axis=1)[:, np.newaxis] + random_vectors / linalg.norm(random_vectors, axis=1)[:, None] ) # Pass the quaternions through the conversion functions From 77652f598f7e3b4f9ff3a6f919fed9182d5f3e5d Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 23 Oct 2023 20:24:55 +0100 Subject: [PATCH 148/232] More......... --- .../distributions/circle/wrapped_normal_distribution.py | 2 +- .../abstract_spherical_harmonics_distribution.py | 2 +- .../hypersphere_subset/hyperspherical_dirac_distribution.py | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pyrecest/distributions/circle/wrapped_normal_distribution.py b/pyrecest/distributions/circle/wrapped_normal_distribution.py index f669917a..c7e93351 100644 --- a/pyrecest/distributions/circle/wrapped_normal_distribution.py +++ b/pyrecest/distributions/circle/wrapped_normal_distribution.py @@ -1,7 +1,7 @@ from math import pi from typing import Union -# pylint: disable=no-name-in-module,no-member +# pylint: disable=redefined-builtin,no-name-in-module,no-member from pyrecest.backend import ( abs, angle, diff --git a/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py index f13f7a91..55fc27ca 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py @@ -2,7 +2,7 @@ import warnings from math import pi -# pylint: disable=no-name-in-module,no-member +# pylint: disable=redefined-builtin,no-name-in-module,no-member from pyrecest.backend import abs, atleast_2d, imag, isnan, real, sqrt, zeros from scipy.linalg import norm diff --git a/pyrecest/distributions/hypersphere_subset/hyperspherical_dirac_distribution.py b/pyrecest/distributions/hypersphere_subset/hyperspherical_dirac_distribution.py index fc587887..7f67cc4a 100644 --- a/pyrecest/distributions/hypersphere_subset/hyperspherical_dirac_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/hyperspherical_dirac_distribution.py @@ -2,7 +2,7 @@ # pylint: disable=redefined-builtin,no-name-in-module,no-member # pylint: disable=no-name-in-module,no-member -from pyrecest.backend import linalg, reshape, sum +from pyrecest.backend import linalg, reshape, sum, atan2 from ..circle.circular_dirac_distribution import CircularDiracDistribution from .abstract_hypersphere_subset_dirac_distribution import ( @@ -16,7 +16,7 @@ class HypersphericalDiracDistribution( ): def plot(self, *args, **kwargs): if self.dim == 2: - p = plt.stem(np.atan2(self.d[1, :], self.d[0, :]), self.w, *args, **kwargs) + p = plt.stem(atan2(self.d[1, :], self.d[0, :]), self.w, *args, **kwargs) elif self.dim == 3: fig = plt.figure() ax = fig.add_subplot(111, projection="3d") @@ -33,7 +33,7 @@ def to_circular_dirac_distribution(self): assert ( self.dim == 2 ), "Conversion to circular dirac distribution only supported for 2D case." - return CircularDiracDistribution(np.atan2(self.d[1, :], self.d[0, :]), self.w) + return CircularDiracDistribution(atan2(self.d[1, :], self.d[0, :]), self.w) def mean_direction(self): vec_sum = sum(self.d * reshape(self.w, (-1, 1)), axis=0) From c4f86e781808ba9994a91d25d0b1a34e8f2d288b Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 23 Oct 2023 20:26:04 +0100 Subject: [PATCH 149/232] More.... --- .../distributions/hypersphere_subset/watson_distribution.py | 2 +- .../hypertorus/custom_hypertoroidal_distribution.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/pyrecest/distributions/hypersphere_subset/watson_distribution.py b/pyrecest/distributions/hypersphere_subset/watson_distribution.py index f6b2e724..84df9f88 100644 --- a/pyrecest/distributions/hypersphere_subset/watson_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/watson_distribution.py @@ -1,6 +1,6 @@ import mpmath import numpy.testing as npt -# pylint: disable=no-name-in-module,no-member +# pylint: disable=watson_distribution,no-name-in-module,no-member from pyrecest.backend import ( abs, array, diff --git a/pyrecest/distributions/hypertorus/custom_hypertoroidal_distribution.py b/pyrecest/distributions/hypertorus/custom_hypertoroidal_distribution.py index 55f1d953..2e9ebe18 100644 --- a/pyrecest/distributions/hypertorus/custom_hypertoroidal_distribution.py +++ b/pyrecest/distributions/hypertorus/custom_hypertoroidal_distribution.py @@ -5,6 +5,7 @@ from ..abstract_custom_distribution import AbstractCustomDistribution from .abstract_hypertoroidal_distribution import AbstractHypertoroidalDistribution +from ..circle.custom_circular_distribution import CustomCircularDistribution class CustomHypertoroidalDistribution( From 646504bb6af55faa9c4af28b432da026b7de0638 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 23 Oct 2023 20:29:50 +0100 Subject: [PATCH 150/232] More. --- pyrecest/_backend/__init__.py | 1 + pyrecest/_backend/numpy/__init__.py | 1 + pyrecest/_backend/pytorch/__init__.py | 1 + pyrecest/tests/test_hyperspherical_sampler.py | 2 +- 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/pyrecest/_backend/__init__.py b/pyrecest/_backend/__init__.py index a0721881..4facb05f 100644 --- a/pyrecest/_backend/__init__.py +++ b/pyrecest/_backend/__init__.py @@ -191,6 +191,7 @@ def get_backend_name(): "max", "min", "roll", + "atan2", ], "autodiff": [ "custom_gradient", diff --git a/pyrecest/_backend/numpy/__init__.py b/pyrecest/_backend/numpy/__init__.py index f7b180a3..d9f98560 100644 --- a/pyrecest/_backend/numpy/__init__.py +++ b/pyrecest/_backend/numpy/__init__.py @@ -96,6 +96,7 @@ max, min, roll, + atan2, ) from scipy.special import erf, gamma, polygamma # NOQA diff --git a/pyrecest/_backend/pytorch/__init__.py b/pyrecest/_backend/pytorch/__init__.py index 9360d13b..f56860ca 100644 --- a/pyrecest/_backend/pytorch/__init__.py +++ b/pyrecest/_backend/pytorch/__init__.py @@ -56,6 +56,7 @@ max, min, roll, + atan2, ) from torch import repeat_interleave as repeat from torch import ( diff --git a/pyrecest/tests/test_hyperspherical_sampler.py b/pyrecest/tests/test_hyperspherical_sampler.py index c70a5ddf..8417c32a 100644 --- a/pyrecest/tests/test_hyperspherical_sampler.py +++ b/pyrecest/tests/test_hyperspherical_sampler.py @@ -112,7 +112,7 @@ def test_fibonacci_hopf_sampler(self): grid_density_parameter = [12, 4] grid, _ = sampler.get_grid(grid_density_parameter) - expected_points = prod(grid_density_parameter) + expected_points = grid_density_parameter[0] * grid_density_parameter[1] self.assertEqual( grid.shape[0], expected_points, From 47914866597f4f408872efb5ddf117196cf5baf2 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 23 Oct 2023 20:32:08 +0100 Subject: [PATCH 151/232] More.. --- pyrecest/filters/wrapped_normal_filter.py | 2 +- .../tests/distributions/test_abstract_linear_distribution.py | 1 + pyrecest/tests/distributions/test_disk_uniform_distribution.py | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/pyrecest/filters/wrapped_normal_filter.py b/pyrecest/filters/wrapped_normal_filter.py index 333ba4b6..fe8ec55a 100644 --- a/pyrecest/filters/wrapped_normal_filter.py +++ b/pyrecest/filters/wrapped_normal_filter.py @@ -2,7 +2,7 @@ from functools import partial from math import pi -# pylint: disable=no-name-in-module,no-member +# pylint: disable=redefined-builtin,no-name-in-module,no-member from pyrecest.backend import array, log, max, min, mod from pyrecest.distributions import CircularDiracDistribution, WrappedNormalDistribution from pyrecest.filters.abstract_circular_filter import AbstractCircularFilter diff --git a/pyrecest/tests/distributions/test_abstract_linear_distribution.py b/pyrecest/tests/distributions/test_abstract_linear_distribution.py index e511cc07..eec29c08 100644 --- a/pyrecest/tests/distributions/test_abstract_linear_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_linear_distribution.py @@ -24,6 +24,7 @@ def setUp(self): self.g_2D = GaussianDistribution(self.mu_2D, self.C_2D) self.g_3D = GaussianDistribution(self.mu_3D, self.C_3D) + def test_integrate(self): """Test that the numerical integration of a Gaussian distribution equals 1.""" dist = GaussianDistribution(array([1.0, 2.0]), diag(array([1.0, 2.0]))) integration_result = dist.integrate_numerically() diff --git a/pyrecest/tests/distributions/test_disk_uniform_distribution.py b/pyrecest/tests/distributions/test_disk_uniform_distribution.py index 9b9ed907..6d18be22 100644 --- a/pyrecest/tests/distributions/test_disk_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_disk_uniform_distribution.py @@ -1,9 +1,9 @@ +""" Test cases for DiskUniformDistribution""" from math import pi # pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, concatenate, ones, sqrt, zeros -""" Test cases for DiskUniformDistribution""" import unittest import numpy.testing as npt From e5f9fdd6e8182588a2daab90b599cb3e9fc20947 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 23 Oct 2023 20:41:05 +0100 Subject: [PATCH 152/232] More.. --- pyrecest/_backend/__init__.py | 1 - pyrecest/_backend/numpy/__init__.py | 1 - pyrecest/_backend/pytorch/__init__.py | 1 - .../hypersphere_subset/hyperspherical_dirac_distribution.py | 6 +++--- .../tests/distributions/test_disk_uniform_distribution.py | 4 ++-- 5 files changed, 5 insertions(+), 8 deletions(-) diff --git a/pyrecest/_backend/__init__.py b/pyrecest/_backend/__init__.py index 4facb05f..a0721881 100644 --- a/pyrecest/_backend/__init__.py +++ b/pyrecest/_backend/__init__.py @@ -191,7 +191,6 @@ def get_backend_name(): "max", "min", "roll", - "atan2", ], "autodiff": [ "custom_gradient", diff --git a/pyrecest/_backend/numpy/__init__.py b/pyrecest/_backend/numpy/__init__.py index d9f98560..f7b180a3 100644 --- a/pyrecest/_backend/numpy/__init__.py +++ b/pyrecest/_backend/numpy/__init__.py @@ -96,7 +96,6 @@ max, min, roll, - atan2, ) from scipy.special import erf, gamma, polygamma # NOQA diff --git a/pyrecest/_backend/pytorch/__init__.py b/pyrecest/_backend/pytorch/__init__.py index f56860ca..9360d13b 100644 --- a/pyrecest/_backend/pytorch/__init__.py +++ b/pyrecest/_backend/pytorch/__init__.py @@ -56,7 +56,6 @@ max, min, roll, - atan2, ) from torch import repeat_interleave as repeat from torch import ( diff --git a/pyrecest/distributions/hypersphere_subset/hyperspherical_dirac_distribution.py b/pyrecest/distributions/hypersphere_subset/hyperspherical_dirac_distribution.py index 7f67cc4a..b0045db0 100644 --- a/pyrecest/distributions/hypersphere_subset/hyperspherical_dirac_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/hyperspherical_dirac_distribution.py @@ -2,7 +2,7 @@ # pylint: disable=redefined-builtin,no-name-in-module,no-member # pylint: disable=no-name-in-module,no-member -from pyrecest.backend import linalg, reshape, sum, atan2 +from pyrecest.backend import linalg, reshape, sum, arctan2 from ..circle.circular_dirac_distribution import CircularDiracDistribution from .abstract_hypersphere_subset_dirac_distribution import ( @@ -16,7 +16,7 @@ class HypersphericalDiracDistribution( ): def plot(self, *args, **kwargs): if self.dim == 2: - p = plt.stem(atan2(self.d[1, :], self.d[0, :]), self.w, *args, **kwargs) + p = plt.stem(arctan2(self.d[1, :], self.d[0, :]), self.w, *args, **kwargs) elif self.dim == 3: fig = plt.figure() ax = fig.add_subplot(111, projection="3d") @@ -33,7 +33,7 @@ def to_circular_dirac_distribution(self): assert ( self.dim == 2 ), "Conversion to circular dirac distribution only supported for 2D case." - return CircularDiracDistribution(atan2(self.d[1, :], self.d[0, :]), self.w) + return CircularDiracDistribution(arctan2(self.d[1, :], self.d[0, :]), self.w) def mean_direction(self): vec_sum = sum(self.d * reshape(self.w, (-1, 1)), axis=0) diff --git a/pyrecest/tests/distributions/test_disk_uniform_distribution.py b/pyrecest/tests/distributions/test_disk_uniform_distribution.py index 6d18be22..cf0e5b0d 100644 --- a/pyrecest/tests/distributions/test_disk_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_disk_uniform_distribution.py @@ -18,8 +18,8 @@ def test_pdf(self): xs = array( [ - [0.5, 0, 1, 1 / sqrt(2), 0, 3, 1.5], - [0.5, 1, 0, 1 / sqrt(2), 3, 0, 1.5], + [0.5, 0.0, 1.0, 1.0 / sqrt(2.0), 0.0, 3.0, 1.5], + [0.5, 1.0, 0.0, 1.0 / sqrt(2.0), 3.0, 0.0, 1.5], ] ).T pdf_values = dist.pdf(xs) From f155f63072a0f9b2868416930ea6314e20f8038f Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 23 Oct 2023 20:45:43 +0100 Subject: [PATCH 153/232] More... --- pyrecest/filters/abstract_tracker_with_logging.py | 3 ++- pyrecest/filters/global_nearest_neighbor.py | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyrecest/filters/abstract_tracker_with_logging.py b/pyrecest/filters/abstract_tracker_with_logging.py index 0adc17c8..fc5456f1 100644 --- a/pyrecest/filters/abstract_tracker_with_logging.py +++ b/pyrecest/filters/abstract_tracker_with_logging.py @@ -14,6 +14,7 @@ def __init__(self, **kwargs): setattr(self, f"{clean_key}_over_time", array([[]])) def _store_estimates(self, curr_ests, estimates_over_time): + import numpy as _np # Ensure curr_ests is a 2D array if curr_ests.ndim == 1: curr_ests = curr_ests.reshape(-1, 1) @@ -22,7 +23,7 @@ def _store_estimates(self, curr_ests, estimates_over_time): n = curr_ests.shape[0] if n <= m: - curr_ests = np.pad( + curr_ests = _np.pad( curr_ests, ((0, m - n), (0, 0)), mode="constant", diff --git a/pyrecest/filters/global_nearest_neighbor.py b/pyrecest/filters/global_nearest_neighbor.py index 78db97fc..b84757de 100644 --- a/pyrecest/filters/global_nearest_neighbor.py +++ b/pyrecest/filters/global_nearest_neighbor.py @@ -1,5 +1,4 @@ # pylint: disable=redefined-builtin,no-name-in-module,no-member -# pylint: disable=no-name-in-module,no-member from pyrecest.backend import all, empty, full, repeat, squeeze, stack from scipy.optimize import linear_sum_assignment from scipy.spatial.distance import cdist From 6e4734c0ce09a665fe8a9e3a40ce601e2d21b2da Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 23 Oct 2023 20:55:57 +0100 Subject: [PATCH 154/232] More... --- pyrecest/evaluation/generate_measurements.py | 1 + pyrecest/evaluation/simulation_database.py | 3 +-- .../test_abstract_hypercylindrical_distribution.py | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pyrecest/evaluation/generate_measurements.py b/pyrecest/evaluation/generate_measurements.py index 047ae963..815f8882 100644 --- a/pyrecest/evaluation/generate_measurements.py +++ b/pyrecest/evaluation/generate_measurements.py @@ -1,5 +1,6 @@ import numpy as np from math import pi +# pylint: disable=redefined-builtin,no-name-in-module,no-member from pyrecest.backend import tile, squeeze, sum, zeros, mod from beartype import beartype from pyrecest.distributions import ( diff --git a/pyrecest/evaluation/simulation_database.py b/pyrecest/evaluation/simulation_database.py index e20cc578..e1d2a985 100644 --- a/pyrecest/evaluation/simulation_database.py +++ b/pyrecest/evaluation/simulation_database.py @@ -1,10 +1,9 @@ import warnings from typing import Optional -import numpy as np from beartype import beartype from pyrecest.distributions import GaussianDistribution - +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import eye, zeros @beartype diff --git a/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py b/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py index 345e3b6b..b511f363 100644 --- a/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py @@ -20,7 +20,7 @@ def test_mode_numerical_gaussian_2D(self): def test_linear_mean_numerical(self): hwn = PartiallyWrappedNormalDistribution( - array([1, 2]), array([[2.0, 0.3], [0.3, 1.0]]), 1 + array([1.0, 2.0]), array([[2.0, 0.3], [0.3, 1.0]]), 1 ) npt.assert_allclose(hwn.linear_mean_numerical(), hwn.mu[-1]) @@ -42,7 +42,7 @@ def test_condition_on_periodic(self): zeros(10), atol=1e-10, ) - dist_cond2 = hwn.condition_on_periodic(array(1.5) + 2 * pi) + dist_cond2 = hwn.condition_on_periodic(array(1.5) + 2.0 * pi) npt.assert_allclose( diff( hwn.pdf(column_stack([1.5 * ones(11), arange(-5, 6)])) From 4cd7f20b9e9863bbeae0ee7145ef0777124e2589 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 23 Oct 2023 20:56:54 +0100 Subject: [PATCH 155/232] More.. --- pyrecest/tests/test_evaluation_basic.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pyrecest/tests/test_evaluation_basic.py b/pyrecest/tests/test_evaluation_basic.py index a9b05e84..56413e2f 100644 --- a/pyrecest/tests/test_evaluation_basic.py +++ b/pyrecest/tests/test_evaluation_basic.py @@ -3,7 +3,9 @@ import unittest from typing import Optional +# pylint: disable=redefined-builtin,no-name-in-module,no-member from pyrecest.backend import array, sqrt, eye, zeros, all +# pylint: disable=no-name-in-module,no-member import pyrecest.backend import numpy as np From 2757cfdea4a7e704dbb3aea4b507af2f34414bdb Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Mon, 23 Oct 2023 22:19:39 +0100 Subject: [PATCH 156/232] More.. --- .../distributions/nonperiodic/linear_mixture.py | 3 ++- .../filters/hypertoroidal_particle_filter.py | 17 ++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/pyrecest/distributions/nonperiodic/linear_mixture.py b/pyrecest/distributions/nonperiodic/linear_mixture.py index b083bc6f..8fb2de68 100644 --- a/pyrecest/distributions/nonperiodic/linear_mixture.py +++ b/pyrecest/distributions/nonperiodic/linear_mixture.py @@ -3,10 +3,11 @@ from ..abstract_mixture import AbstractMixture from .abstract_linear_distribution import AbstractLinearDistribution from .gaussian_distribution import GaussianDistribution +from typing import Sequence class LinearMixture(AbstractMixture, AbstractLinearDistribution): - def __init__(self, dists: list[AbstractLinearDistribution], w): + def __init__(self, dists: Sequence[AbstractLinearDistribution], w): from .gaussian_mixture import GaussianMixture assert all( diff --git a/pyrecest/filters/hypertoroidal_particle_filter.py b/pyrecest/filters/hypertoroidal_particle_filter.py index b6a8676b..ac262449 100644 --- a/pyrecest/filters/hypertoroidal_particle_filter.py +++ b/pyrecest/filters/hypertoroidal_particle_filter.py @@ -63,16 +63,15 @@ def predict_nonlinear( f: Callable, noise_distribution: AbstractHypertoroidalDistribution | None = None, function_is_vectorized: bool = True, + shift_instead_of_add: bool = True, ): - if function_is_vectorized: - self.filter_state.d = f(self.filter_state.d) - else: - self.filter_state.d = self.filter_state.apply_function(f) - - if noise_distribution is not None: - noise = noise_distribution.sample(self.filter_state.w.shape[0]) - self.filter_state.d += noise.squeeze() - self.filter_state.d = mod(self.filter_state.d, 2.0 * pi) + super().predict_nonlinear( + f, + noise_distribution, + function_is_vectorized, + shift_instead_of_add, + ) + self.filter_state.d = mod(self.filter_state.d, 2.0 * pi) def predict_nonlinear_nonadditive(self, f: Callable, samples, weights): assert samples.shape == weights.size, "samples and weights must match in size" From 3749970648ac2b4f715e378dcb46d30d162b2dd7 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 08:24:30 +0100 Subject: [PATCH 157/232] More...... --- .../hypersphere_subset/watson_distribution.py | 2 +- .../hypertorus/toroidal_wrapped_normal_distribution.py | 2 +- pyrecest/evaluation/generate_groundtruth.py | 1 + pyrecest/filters/global_nearest_neighbor.py | 2 +- pyrecest/sampling/hyperspherical_sampler.py | 2 +- .../test_hyperspherical_uniform_distribution.py | 3 +-- pyrecest/tests/test_hyperspherical_sampler.py | 8 ++------ 7 files changed, 8 insertions(+), 12 deletions(-) diff --git a/pyrecest/distributions/hypersphere_subset/watson_distribution.py b/pyrecest/distributions/hypersphere_subset/watson_distribution.py index 84df9f88..e4395e18 100644 --- a/pyrecest/distributions/hypersphere_subset/watson_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/watson_distribution.py @@ -1,6 +1,6 @@ import mpmath import numpy.testing as npt -# pylint: disable=watson_distribution,no-name-in-module,no-member +# pylint: disable=redefined-builtin,no-name-in-module,no-member from pyrecest.backend import ( abs, array, diff --git a/pyrecest/distributions/hypertorus/toroidal_wrapped_normal_distribution.py b/pyrecest/distributions/hypertorus/toroidal_wrapped_normal_distribution.py index 51e2c773..4ac3aa28 100644 --- a/pyrecest/distributions/hypertorus/toroidal_wrapped_normal_distribution.py +++ b/pyrecest/distributions/hypertorus/toroidal_wrapped_normal_distribution.py @@ -1,6 +1,6 @@ from numpy import cos, exp, sin # pylint: disable=no-name-in-module,no-member -from pyrecest.backend import array +from pyrecest.backend import array, zeros from .abstract_toroidal_distribution import AbstractToroidalDistribution from .hypertoroidal_wrapped_normal_distribution import ( diff --git a/pyrecest/evaluation/generate_groundtruth.py b/pyrecest/evaluation/generate_groundtruth.py index 8ee97738..942a413b 100644 --- a/pyrecest/evaluation/generate_groundtruth.py +++ b/pyrecest/evaluation/generate_groundtruth.py @@ -1,5 +1,6 @@ import numpy as np +# pylint: disable=no-name-in-module,no-member from pyrecest.backend import empty, atleast_2d, empty_like, squeeze # pylint: disable=too-many-branches diff --git a/pyrecest/filters/global_nearest_neighbor.py b/pyrecest/filters/global_nearest_neighbor.py index b84757de..56fc6da2 100644 --- a/pyrecest/filters/global_nearest_neighbor.py +++ b/pyrecest/filters/global_nearest_neighbor.py @@ -137,7 +137,7 @@ def find_association( association = col_ind[:n_targets] - if warn_on_no_meas_for_track and backend.any(association > n_meas): + if warn_on_no_meas_for_track and any(association > n_meas): print( "GNN: No measurement was within gating threshold for at least one target." ) diff --git a/pyrecest/sampling/hyperspherical_sampler.py b/pyrecest/sampling/hyperspherical_sampler.py index d0f7ac59..4583ca97 100644 --- a/pyrecest/sampling/hyperspherical_sampler.py +++ b/pyrecest/sampling/hyperspherical_sampler.py @@ -72,7 +72,7 @@ class AbstractSphericalCoordinatesBasedSampler(AbstractSphericalUniformSampler): @abstractmethod def get_grid_spherical_coordinates( self, - grid_density_parameter: int, + grid_density_parameter: int | list[int], ): raise NotImplementedError() diff --git a/pyrecest/tests/distributions/test_hyperspherical_uniform_distribution.py b/pyrecest/tests/distributions/test_hyperspherical_uniform_distribution.py index 724d9bb9..4fbff8d7 100644 --- a/pyrecest/tests/distributions/test_hyperspherical_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_hyperspherical_uniform_distribution.py @@ -1,7 +1,6 @@ +""" Test for uniform distribution on the hypersphere """ # pylint: disable=no-name-in-module,no-member from pyrecest.backend import allclose, linalg, ones, random - -""" Test for uniform distribution on the hypersphere """ import unittest from pyrecest.distributions import ( diff --git a/pyrecest/tests/test_hyperspherical_sampler.py b/pyrecest/tests/test_hyperspherical_sampler.py index 8417c32a..db2050f3 100644 --- a/pyrecest/tests/test_hyperspherical_sampler.py +++ b/pyrecest/tests/test_hyperspherical_sampler.py @@ -1,15 +1,9 @@ import importlib.util import unittest - # pylint: disable=no-name-in-module,no-member from pyrecest.backend import allclose, linalg, prod, random - -healpy_installed = importlib.util.find_spec("healpy") is not None - - from parameterized import parameterized from pyrecest.sampling.hyperspherical_sampler import get_grid_hypersphere - from ..sampling.hyperspherical_sampler import ( AbstractHopfBasedS3Sampler, DriscollHealySampler, @@ -19,6 +13,8 @@ SphericalFibonacciSampler, ) +healpy_installed = importlib.util.find_spec("healpy") is not None + class TestHypersphericalGridGenerationFunction(unittest.TestCase): @parameterized.expand( From 65b3fd062ef1645cce5959fc8e67bea6237cbdf4 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 08:25:58 +0100 Subject: [PATCH 158/232] More --- .../hypertoroidal_wrapped_normal_distribution.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py b/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py index 46ee2fcb..9d259152 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py @@ -46,6 +46,20 @@ def __init__(self, mu, C): AbstractHypertoroidalDistribution.__init__(self, numel_mu) self.mu = mod(mu, 2.0 * pi) self.C = C + + def set_mean(self, mu): + """ + Set the mean of the distribution. + + Parameters: + mu (numpy array): The new mean. + + Returns: + HypertoroidalWNDistribution: A new instance of the distribution with the updated mean. + """ + dist = copy.deepcopy(self) + dist.mu = mod(mu, 2.0 * pi) + return dist def pdf(self, xs, m: Union[int, int32, int64] = 3): """ From 26b9b55a22fd7dca97d2d94b70419612d9fdfaef Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 09:36:24 +0100 Subject: [PATCH 159/232] More --- pyrecest/_backend/__init__.py | 1 + pyrecest/_backend/numpy/__init__.py | 1 + pyrecest/_backend/pytorch/__init__.py | 1 + pyrecest/filters/abstract_nearest_neighbor_tracker.py | 2 +- 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/pyrecest/_backend/__init__.py b/pyrecest/_backend/__init__.py index a0721881..9d0ae75d 100644 --- a/pyrecest/_backend/__init__.py +++ b/pyrecest/_backend/__init__.py @@ -191,6 +191,7 @@ def get_backend_name(): "max", "min", "roll", + "dstack", ], "autodiff": [ "custom_gradient", diff --git a/pyrecest/_backend/numpy/__init__.py b/pyrecest/_backend/numpy/__init__.py index f7b180a3..1b9abefc 100644 --- a/pyrecest/_backend/numpy/__init__.py +++ b/pyrecest/_backend/numpy/__init__.py @@ -96,6 +96,7 @@ max, min, roll, + dstack, ) from scipy.special import erf, gamma, polygamma # NOQA diff --git a/pyrecest/_backend/pytorch/__init__.py b/pyrecest/_backend/pytorch/__init__.py index 9360d13b..94c40e5c 100644 --- a/pyrecest/_backend/pytorch/__init__.py +++ b/pyrecest/_backend/pytorch/__init__.py @@ -56,6 +56,7 @@ max, min, roll, + dstack, ) from torch import repeat_interleave as repeat from torch import ( diff --git a/pyrecest/filters/abstract_nearest_neighbor_tracker.py b/pyrecest/filters/abstract_nearest_neighbor_tracker.py index b95d40a8..2bc0919e 100644 --- a/pyrecest/filters/abstract_nearest_neighbor_tracker.py +++ b/pyrecest/filters/abstract_nearest_neighbor_tracker.py @@ -3,7 +3,7 @@ from abc import abstractmethod # pylint: disable=no-name-in-module,no-member -from pyrecest.backend import empty, ndim +from pyrecest.backend import empty, ndim, dstack from pyrecest.distributions import GaussianDistribution from .abstract_euclidean_filter import AbstractEuclideanFilter From 726349a57daa74f29420ff690cb4f1ca13e8f5ae Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 09:36:57 +0100 Subject: [PATCH 160/232] More... --- pyrecest/sampling/hypertoroidal_sampler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrecest/sampling/hypertoroidal_sampler.py b/pyrecest/sampling/hypertoroidal_sampler.py index 9ca1ff73..c5b878c6 100644 --- a/pyrecest/sampling/hypertoroidal_sampler.py +++ b/pyrecest/sampling/hypertoroidal_sampler.py @@ -16,7 +16,7 @@ class AbstractCircularSampler(AbstractHypertoroidalSampler): class CircularUniformSampler(AbstractCircularSampler): - def sample_stochastic(self, n_samples: int, dim: int): + def sample_stochastic(self, n_samples: int, dim: int = 1): assert ( dim == 1 ), "CircularUniformSampler is supposed to be used for the circle (which is one-dimensional) only." From 0b1321e8dda653dc1a074611fccdadf468520bf9 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 09:41:41 +0100 Subject: [PATCH 161/232] More --- .../abstract_hypersphere_subset_distribution.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py index 1fb770b8..1286e754 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py @@ -4,7 +4,6 @@ from typing import Union # pylint: disable=redefined-builtin,no-name-in-module,no-member -# pylint: disable=no-name-in-module,no-member from pyrecest.backend import ( abs, array, @@ -57,6 +56,7 @@ def mean_direction_numerical(self, integration_boundaries=None): def f(x, i=i): return x[i] * self.pdf(x) + # pylint: disable=cell-var-from-loop fangles = self.gen_fun_hyperspherical_coords(f, self.dim) # Casts the floats to arrays, relevant for operations on torch.tensors From de12c8b3de76d7c655138b2e51d73dd89cf7edd7 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 10:55:38 +0200 Subject: [PATCH 162/232] More... --- pyrecest/filters/abstract_particle_filter.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pyrecest/filters/abstract_particle_filter.py b/pyrecest/filters/abstract_particle_filter.py index c5c4118c..9a3079bb 100644 --- a/pyrecest/filters/abstract_particle_filter.py +++ b/pyrecest/filters/abstract_particle_filter.py @@ -33,13 +33,13 @@ def predict_nonlinear( self.filter_state.d = f(self.filter_state.d) else: self.filter_state = self.filter_state.apply_function(f) - + n_particles = self.filter_state.w.shape[0] if noise_distribution is not None: if not shift_instead_of_add: noise = noise_distribution.sample(self.filter_state.w.shape[0]) self.filter_state.d = self.filter_state.d + noise else: - for i in range(self.filter_state.d.shape[1]): + for i in range(n_particles): noise_curr = noise_distribution.set_mean(self.filter_state.d[i, :]) self.filter_state.d[i, :] = noise_curr.sample(1) @@ -49,10 +49,10 @@ def predict_nonlinear_nonadditive(self, f, samples, weights): ), "samples and weights must match in size" weights = weights / sum(weights) - n = self.filter_state.w.shape[0] - noise_samples = random.choice(self.filter_state.d, n, p=weights) - d = zeros((n, self.filter_state.dim)) - for i in range(n): + n_particles = self.filter_state.w.shape[0] + noise_samples = random.choice(self.filter_state.d, n_particles, p=weights) + d = zeros((n_particles, self.filter_state.dim)) + for i in range(n_particles): d[i, :] = f(self.filter_state.d[i, :], noise_samples[i]) self.filter_state.d = d From 6dd96aa104f7fdc03fb8f54aa5a4461667993ba3 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 10:00:34 +0100 Subject: [PATCH 163/232] More... --- .../abstract_hypersphere_subset_distribution.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py index 1286e754..cde4af57 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hypersphere_subset_distribution.py @@ -376,11 +376,11 @@ def polar_to_cart(polar_coords): @staticmethod def compute_unit_hypersphere_surface(dim: Union[int, int32, int64]) -> float: if dim == 1: - surface_area = 2 * pi + surface_area = 2.0 * pi elif dim == 2: - surface_area = 4 * pi + surface_area = 4.0 * pi elif dim == 3: - surface_area = 2 * pi**2 + surface_area = 2.0 * pi**2 else: - surface_area = 2 * pi ** ((dim + 1) / 2) / gamma((dim + 1) / 2) + surface_area = 2.0 * pi ** ((dim + 1) / 2) / gamma((dim + 1) / 2) return surface_area From 3e53d7735fd0dbec34b8ea2dbc5d89166afcefb5 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 10:18:29 +0100 Subject: [PATCH 164/232] More.. --- .../distributions/test_circular_fourier_distribution.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pyrecest/tests/distributions/test_circular_fourier_distribution.py b/pyrecest/tests/distributions/test_circular_fourier_distribution.py index 3d2f9568..e31682be 100644 --- a/pyrecest/tests/distributions/test_circular_fourier_distribution.py +++ b/pyrecest/tests/distributions/test_circular_fourier_distribution.py @@ -26,7 +26,7 @@ class TestCircularFourierDistribution(unittest.TestCase): arange(0.1, 2.1, 0.1), 101, ), - ("sqrt", VonMisesDistribution, 0.5, arange(0.1, 2.1, 0.1), 101, 1e-8), + ("sqrt", VonMisesDistribution, array(0.5), arange(0.1, 2.1, 0.1), 101), ( "identity", WrappedNormalDistribution, @@ -105,9 +105,9 @@ def test_integrate_numerically(self, mult_by_n, transformation): transformation=transformation, store_values_multiplied_by_n=mult_by_n, ) - npt.assert_array_almost_equal(fd.integrate_numerically(), 1) + npt.assert_array_almost_equal(fd.integrate_numerically(), 1.0) fd_real = fd.to_real_fd() - npt.assert_array_almost_equal(fd_real.integrate_numerically(), 1) + npt.assert_array_almost_equal(fd_real.integrate_numerically(), 1.0) fd_unnorm = copy.copy(fd) fd_unnorm.c = fd.c * (scale_by) if transformation == "identity": From 8ba9589d9e189ddaee405109f959fd1248663203 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 10:29:24 +0100 Subject: [PATCH 165/232] More......... --- .../test_circular_fourier_distribution.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pyrecest/tests/distributions/test_circular_fourier_distribution.py b/pyrecest/tests/distributions/test_circular_fourier_distribution.py index e31682be..7074b7f2 100644 --- a/pyrecest/tests/distributions/test_circular_fourier_distribution.py +++ b/pyrecest/tests/distributions/test_circular_fourier_distribution.py @@ -23,22 +23,22 @@ class TestCircularFourierDistribution(unittest.TestCase): "identity", VonMisesDistribution, array(0.4), - arange(0.1, 2.1, 0.1), + arange(0.1, 2.1, 0.5), 101, ), - ("sqrt", VonMisesDistribution, array(0.5), arange(0.1, 2.1, 0.1), 101), + ("sqrt", VonMisesDistribution, array(0.5), arange(0.1, 2.1, 0.5), 101), ( "identity", WrappedNormalDistribution, array(0.8), - arange(0.2, 2.1, 0.1), + arange(0.2, 2.1, 0.5), 101, ), ( "sqrt", WrappedNormalDistribution, array(0.8), - arange(0.2, 2.1, 0.1), + arange(0.2, 2.1, 0.5), 101, ), ] @@ -61,7 +61,7 @@ def test_fourier_conversion( ceil(coeffs / 2.0), "Length of Fourier Coefficients mismatch.", ) - npt.assert_allclose(fd.pdf(xvals), dist.pdf(xvals), atol=1e-5) + npt.assert_allclose(fd.pdf(xvals), dist.pdf(xvals), rtol=2e-3, atol=5e-5) @parameterized.expand( [ From 79a380e2ee80bb4c9500f3056e5d3659e2336a40 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 10:32:09 +0100 Subject: [PATCH 166/232] More.......... --- .../tests/distributions/test_disk_uniform_distribution.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pyrecest/tests/distributions/test_disk_uniform_distribution.py b/pyrecest/tests/distributions/test_disk_uniform_distribution.py index cf0e5b0d..4ccadc9a 100644 --- a/pyrecest/tests/distributions/test_disk_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_disk_uniform_distribution.py @@ -17,9 +17,9 @@ def test_pdf(self): dist = DiskUniformDistribution() xs = array( - [ - [0.5, 0.0, 1.0, 1.0 / sqrt(2.0), 0.0, 3.0, 1.5], - [0.5, 1.0, 0.0, 1.0 / sqrt(2.0), 3.0, 0.0, 1.5], + [ # Without multiplying it by 0.99, machine precision can play a role + [0.5, 0.0, 1.0, 1.0 / sqrt(2.0)*0.99, 0.0, 3.0, 1.5], + [0.5, 1.0, 0.0, 1.0 / sqrt(2.0)*0.99, 3.0, 0.0, 1.5], ] ).T pdf_values = dist.pdf(xs) From 75be01f1172f88348337e92d36dd674210587ccc Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 10:32:19 +0100 Subject: [PATCH 167/232] More.... --- pyrecest/tests/distributions/test_disk_uniform_distribution.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrecest/tests/distributions/test_disk_uniform_distribution.py b/pyrecest/tests/distributions/test_disk_uniform_distribution.py index 4ccadc9a..d3b07164 100644 --- a/pyrecest/tests/distributions/test_disk_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_disk_uniform_distribution.py @@ -17,7 +17,7 @@ def test_pdf(self): dist = DiskUniformDistribution() xs = array( - [ # Without multiplying it by 0.99, machine precision can play a role + [ # Without multiplying it by 0.99, machine precision can play a role [0.5, 0.0, 1.0, 1.0 / sqrt(2.0)*0.99, 0.0, 3.0, 1.5], [0.5, 1.0, 0.0, 1.0 / sqrt(2.0)*0.99, 3.0, 0.0, 1.5], ] From a8246de9ab490fb01bd618c80075ab214ad2503c Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 10:33:34 +0100 Subject: [PATCH 168/232] More --- .../hypertorus/hypertoroidal_dirac_distribution.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py b/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py index 74b70f77..16ba5d5c 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py @@ -40,6 +40,9 @@ def __init__(self, d, w=None, dim: int | None = None): def plot(self, *args, **kwargs): raise NotImplementedError("Plotting is not implemented") + def set_mean(self, mean): + self.d = mod(self.d - self.mean_direction() + mean, 2.0 * pi) + def mean_direction(self): """ Calculate the mean direction of the HypertoroidalDiracDistribution. From f75b861c6d87f26d36545303010263b61fbf8037 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 11:42:56 +0100 Subject: [PATCH 169/232] More --- pyrecest/filters/abstract_particle_filter.py | 3 ++- .../tests/filters/test_euclidean_particle_filter.py | 12 ++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/pyrecest/filters/abstract_particle_filter.py b/pyrecest/filters/abstract_particle_filter.py index 9a3079bb..5cfb08ba 100644 --- a/pyrecest/filters/abstract_particle_filter.py +++ b/pyrecest/filters/abstract_particle_filter.py @@ -50,7 +50,8 @@ def predict_nonlinear_nonadditive(self, f, samples, weights): weights = weights / sum(weights) n_particles = self.filter_state.w.shape[0] - noise_samples = random.choice(self.filter_state.d, n_particles, p=weights) + noise_samples = random.choice(samples, n_particles, p=weights) + d = zeros((n_particles, self.filter_state.dim)) for i in range(n_particles): d[i, :] = f(self.filter_state.d[i, :], noise_samples[i]) diff --git a/pyrecest/tests/filters/test_euclidean_particle_filter.py b/pyrecest/tests/filters/test_euclidean_particle_filter.py index b795a492..8a106395 100644 --- a/pyrecest/tests/filters/test_euclidean_particle_filter.py +++ b/pyrecest/tests/filters/test_euclidean_particle_filter.py @@ -17,7 +17,7 @@ def setUp(self): self.sys_noise_default = GaussianDistribution( zeros_like(self.mu), 0.5 * self.C_prior ) - self.pf = EuclideanParticleFilter(n_particles=500, dim=3) + self.pf = EuclideanParticleFilter(n_particles=1000, dim=3) self.forced_mean = array([1.0, 2.0, 3.0]) self.pf.filter_state = self.prior @@ -31,14 +31,14 @@ def test_predict_update_cycle_3d(self): # jscpd:ignore-end self.assertEqual(self.pf.get_point_estimate().shape, (3,)) - npt.assert_almost_equal( - self.pf.get_point_estimate(), self.forced_mean, decimal=1 + npt.assert_allclose( + self.pf.get_point_estimate(), self.forced_mean, atol=0.1 ) def test_predict_nonlinear_nonadditive(self): - n = 5 - samples = random.rand(n, 3) - weights = ones(n) / n + n_noise_samples = 10 + samples = random.rand(n_noise_samples, 3) + weights = ones(n_noise_samples) / n_noise_samples def f(x, w): return x + w From addc4f75f49f23a751504c3400d7edf4a04725c8 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 11:44:33 +0100 Subject: [PATCH 170/232] Also test numpy backend --- .github/workflows/tests.yml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 00d143e3..72c93b48 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -31,8 +31,6 @@ jobs: python -m pip install --upgrade pip python -m pip install poetry poetry env use python - # poetry install --extras healpy_support --no-root # skip the project root package - # poetry run python -m pip install torch==2.1.0+cpu torchvision torchaudio -f https://download.pytorch.org/whl/cpu poetry install --extras "healpy_support" --extras "pytorch_support" poetry run python -m pip install torch==2.1.0+cpu torchaudio==2.1.0+cpu -f https://download.pytorch.org/whl/torch_stable.html @@ -45,9 +43,9 @@ jobs: - name: Run tests with numpy backend run: | - #poetry env use python - #export PYRECEST_BACKEND=numpy - #poetry run python -m pytest --rootdir . -v --strict-config --junitxml=junit_test_results_numpy.xml ./pyrecest + poetry env use python + export PYRECEST_BACKEND=numpy + poetry run python -m pytest --rootdir . -v --strict-config --junitxml=junit_test_results_numpy.xml ./pyrecest env: PYTHONPATH: ${{ github.workspace }} From 06675dfefdfe1b05ec222e5907b180e0b29e6379 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 11:56:23 +0100 Subject: [PATCH 171/232] More... --- pyrecest/tests/distributions/test_abstract_mixture.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pyrecest/tests/distributions/test_abstract_mixture.py b/pyrecest/tests/distributions/test_abstract_mixture.py index c3e344b7..4b472921 100644 --- a/pyrecest/tests/distributions/test_abstract_mixture.py +++ b/pyrecest/tests/distributions/test_abstract_mixture.py @@ -36,14 +36,14 @@ def test_sample_metropolis_hastings_basics_only_t2(self): reason="Not supported on PyTorch backend", ) def test_sample_metropolis_hastings_basics_only_s2(self): - vmf1 = VonMisesFisherDistribution(array([1.0, 0.0, 0.0]), array(2.0)) - vmf2 = VonMisesFisherDistribution(array([0.0, 1.0, 0.0]), array(2.0)) + vmf1 = VonMisesFisherDistribution(array([1.0, 0.0, 0.0]), 2.0) # Needs to be float for scipy + vmf2 = VonMisesFisherDistribution(array([0.0, 1.0, 0.0]), 2.0) # Needs to be float for scipy mix = HypersphericalMixture([vmf1, vmf2], array([0.5, 0.5])) s = self._test_sample(mix, 10) self.assertTrue(allclose(linalg.norm(s, axis=1), ones(10), rtol=1e-10)) def test_sample_metropolis_hastings_basics_only_h2(self): - vmf = VonMisesFisherDistribution(array([1.0, 0.0, 0.0]), array(2.0)) + vmf = VonMisesFisherDistribution(array([1.0, 0.0, 0.0]), 2.0) # Needs to be float for scipy mix = CustomHyperhemisphericalDistribution( lambda x: vmf.pdf(x) + vmf.pdf(-x), 2 ) From e9d19f088a8fd9f317a72f3895151d6d91a5e039 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 11:58:46 +0100 Subject: [PATCH 172/232] More --- pyrecest/__init__.py | 2 +- pyrecest/distributions/hypertorus/__init__.py | 1 - pyrecest/distributions/nonperiodic/__init__.py | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/pyrecest/__init__.py b/pyrecest/__init__.py index 0beba0b6..8cff810a 100644 --- a/pyrecest/__init__.py +++ b/pyrecest/__init__.py @@ -1 +1 @@ -import pyrecest._backend +import pyrecest._backend \ No newline at end of file diff --git a/pyrecest/distributions/hypertorus/__init__.py b/pyrecest/distributions/hypertorus/__init__.py index 8b137891..e69de29b 100644 --- a/pyrecest/distributions/hypertorus/__init__.py +++ b/pyrecest/distributions/hypertorus/__init__.py @@ -1 +0,0 @@ - diff --git a/pyrecest/distributions/nonperiodic/__init__.py b/pyrecest/distributions/nonperiodic/__init__.py index 8b137891..e69de29b 100644 --- a/pyrecest/distributions/nonperiodic/__init__.py +++ b/pyrecest/distributions/nonperiodic/__init__.py @@ -1 +0,0 @@ - From 91d849635aeab908979290b847fb08bdd0090440 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 12:00:08 +0100 Subject: [PATCH 173/232] More.... --- .../abstract_spherical_harmonics_distribution.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py index 55fc27ca..e84523d2 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_spherical_harmonics_distribution.py @@ -24,7 +24,7 @@ def __init__(self, coeff_mat, transformation="identity"): n = coeff_mat.shape[0] for i in range(n): # Set the irrelevant elements to nan - coeff_mat[i, 2 * i + 1 :] = float("NaN") + coeff_mat[i, 2 * i + 1 :] = float("NaN") # noqa: E203 AbstractOrthogonalBasisDistribution.__init__(self, coeff_mat, transformation) def pdf(self, xs): From b7838eb598d3b394d397318899893a2ceec3f29f Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 12:01:58 +0100 Subject: [PATCH 174/232] More --- .../hypertorus/hypertoroidal_dirac_distribution.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py b/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py index 16ba5d5c..53fa1984 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py @@ -67,7 +67,7 @@ def trigonometric_moment(self, n: Union[int, int32, int64]): def apply_function( self, f: Callable, f_supports_multiple: bool = True ) -> "HypertoroidalDiracDistribution": - dist = super().apply_function(f, f_supports_multiple) + dist: HypertoroidalDiracDistribution = super().apply_function(f, f_supports_multiple) dist.d = mod(dist.d, 2.0 * pi) return dist From e370a8a5d5bb0af1887c987e0569fdb8ec877fa4 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 12:02:41 +0100 Subject: [PATCH 175/232] More... --- pyrecest/distributions/circle/circular_fourier_distribution.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrecest/distributions/circle/circular_fourier_distribution.py b/pyrecest/distributions/circle/circular_fourier_distribution.py index 9abe0ed3..04f5792e 100644 --- a/pyrecest/distributions/circle/circular_fourier_distribution.py +++ b/pyrecest/distributions/circle/circular_fourier_distribution.py @@ -295,7 +295,7 @@ def from_distribution( ) -> "CircularFourierDistribution": if isinstance(distribution, CircularDiracDistribution): fd = CircularFourierDistribution( - conj(distribution.trigonometric_moment(n, whole_range=True)) + conj(distribution.trigonometric_moment(n)) / (2.0 * pi), transformation, multiplied_by_n=False, From f1980b67675d290f7ad0ad683b766ff7842a4944 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 12:04:42 +0100 Subject: [PATCH 176/232] More..... --- pyrecest/sampling/hyperspherical_sampler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrecest/sampling/hyperspherical_sampler.py b/pyrecest/sampling/hyperspherical_sampler.py index 4583ca97..887fcfbe 100644 --- a/pyrecest/sampling/hyperspherical_sampler.py +++ b/pyrecest/sampling/hyperspherical_sampler.py @@ -56,7 +56,7 @@ def sample_stochastic(self, n_samples: int, dim: int): return HypersphericalUniformDistribution(dim).sample(n_samples) @abstractmethod - def get_grid(self, grid_density_parameter: int, dim: int): + def get_grid(self, grid_density_parameter: int | list[int], dim: int): raise NotImplementedError() From 185d9342af493405d513cc178c19517189e5f219 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 12:04:58 +0100 Subject: [PATCH 177/232] More... --- .../nonperiodic/gaussian_distribution.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/pyrecest/distributions/nonperiodic/gaussian_distribution.py b/pyrecest/distributions/nonperiodic/gaussian_distribution.py index 49096af4..510ce9d4 100644 --- a/pyrecest/distributions/nonperiodic/gaussian_distribution.py +++ b/pyrecest/distributions/nonperiodic/gaussian_distribution.py @@ -2,9 +2,8 @@ # pylint: disable=no-name-in-module,no-member from pyrecest.backend import dot, linalg, ndim, random +import pyrecest.backend from scipy.linalg import cholesky -from scipy.stats import multivariate_normal as mvn - from .abstract_linear_distribution import AbstractLinearDistribution @@ -39,7 +38,16 @@ def pdf(self, xs): assert ( self.dim == 1 and xs.ndim <= 1 or xs.shape[-1] == self.dim ), "Dimension incorrect" - return mvn.pdf(xs, self.mu, self.C) + if pyrecest.backend.__name__ == "pyrecest.numpy": + from scipy.stats import multivariate_normal as mvn + pdfvals = mvn.pdf(xs, self.mu, self.C) + elif pyrecest.backend.__name__ == "pyrecest.pytorch": + from torch.distributions import MultivariateNormal + distribution = MultivariateNormal(self.mu, self.C) + log_probs = distribution.log_prob(xs) + pdfvals = pyrecest.backend.exp(log_probs) + + return pdfvals def shift(self, shift_by): assert shift_by.ndim == 0 and self.dim == 1 or shift_by.shape[0] == self.dim From fb88142193a9fc6f4f18a97561a7e0134283ae06 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 12:16:58 +0100 Subject: [PATCH 178/232] Moore --- pyrecest/distributions/nonperiodic/linear_dirac_distribution.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrecest/distributions/nonperiodic/linear_dirac_distribution.py b/pyrecest/distributions/nonperiodic/linear_dirac_distribution.py index e610fb29..0bde68b1 100644 --- a/pyrecest/distributions/nonperiodic/linear_dirac_distribution.py +++ b/pyrecest/distributions/nonperiodic/linear_dirac_distribution.py @@ -14,7 +14,7 @@ def __init__(self, d, w=None): def mean(self): # Like np.average(self.d, weights=self.w, axis=0) but for all backends - return (self.d * self.w.reshape(-1, 1)).sum(dim=0) + return self.w @ self.d def set_mean(self, new_mean): mean_offset = new_mean - self.mean From f59499bc98bea127d35acbb45f0a708e798dbc71 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 12:17:39 +0100 Subject: [PATCH 179/232] More.... --- .../distributions/test_hypercylindrical_dirac_distribution.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py b/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py index d419dffb..3c8984e5 100644 --- a/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_hypercylindrical_dirac_distribution.py @@ -117,5 +117,5 @@ def test_from_distribution(self): # Call array(...) to be compatibel with all backends C = array(wishart.rvs(df, scale, random_state=random_gen)) hwn = PartiallyWrappedNormalDistribution(array([1.0, 2.0, 3.0, 4.0]), C, 2) - hddist = HypercylindricalDiracDistribution.from_distribution(hwn, 100000) + hddist = HypercylindricalDiracDistribution.from_distribution(hwn, 200000) npt.assert_allclose(hddist.hybrid_mean(), hwn.hybrid_mean(), atol=0.2) From c3e1b1193141116275e1d132d6d92e8f3aada9c7 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 12:19:19 +0100 Subject: [PATCH 180/232] Moore --- pyrecest/distributions/nonperiodic/gaussian_distribution.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pyrecest/distributions/nonperiodic/gaussian_distribution.py b/pyrecest/distributions/nonperiodic/gaussian_distribution.py index 510ce9d4..71a395da 100644 --- a/pyrecest/distributions/nonperiodic/gaussian_distribution.py +++ b/pyrecest/distributions/nonperiodic/gaussian_distribution.py @@ -2,6 +2,7 @@ # pylint: disable=no-name-in-module,no-member from pyrecest.backend import dot, linalg, ndim, random +# pylint: disable=no-name-in-module import pyrecest.backend from scipy.linalg import cholesky from .abstract_linear_distribution import AbstractLinearDistribution From a7262476fc502b650564dead4ce48f6b16d4ee6f Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 12:21:23 +0100 Subject: [PATCH 181/232] More......... --- pyrecest/_backend/__init__.py | 4 ++-- pyrecest/distributions/cart_prod/__init__.py | 1 - pyrecest/distributions/circle/__init__.py | 1 - pyrecest/distributions/conditional/__init__.py | 1 - pyrecest/distributions/hypersphere_subset/__init__.py | 1 - pyrecest/tests/__init__.py | 1 - pyrecest/tests/distributions/__init__.py | 1 - pyrecest/tests/filters/__init__.py | 1 - pyrecest/utils/__init__.py | 1 - 9 files changed, 2 insertions(+), 10 deletions(-) diff --git a/pyrecest/_backend/__init__.py b/pyrecest/_backend/__init__.py index 9d0ae75d..a640846d 100644 --- a/pyrecest/_backend/__init__.py +++ b/pyrecest/_backend/__init__.py @@ -13,8 +13,8 @@ def get_backend_name(): - #return os.environ.get("PYRECEST_BACKEND", "numpy") - return os.environ.get("PYRECEST_BACKEND", "pytorch") + return os.environ.get("PYRECEST_BACKEND", "numpy") + #return os.environ.get("PYRECEST_BACKEND", "pytorch") BACKEND_NAME = get_backend_name() diff --git a/pyrecest/distributions/cart_prod/__init__.py b/pyrecest/distributions/cart_prod/__init__.py index 8b137891..e69de29b 100644 --- a/pyrecest/distributions/cart_prod/__init__.py +++ b/pyrecest/distributions/cart_prod/__init__.py @@ -1 +0,0 @@ - diff --git a/pyrecest/distributions/circle/__init__.py b/pyrecest/distributions/circle/__init__.py index 8b137891..e69de29b 100644 --- a/pyrecest/distributions/circle/__init__.py +++ b/pyrecest/distributions/circle/__init__.py @@ -1 +0,0 @@ - diff --git a/pyrecest/distributions/conditional/__init__.py b/pyrecest/distributions/conditional/__init__.py index 8b137891..e69de29b 100644 --- a/pyrecest/distributions/conditional/__init__.py +++ b/pyrecest/distributions/conditional/__init__.py @@ -1 +0,0 @@ - diff --git a/pyrecest/distributions/hypersphere_subset/__init__.py b/pyrecest/distributions/hypersphere_subset/__init__.py index 8b137891..e69de29b 100644 --- a/pyrecest/distributions/hypersphere_subset/__init__.py +++ b/pyrecest/distributions/hypersphere_subset/__init__.py @@ -1 +0,0 @@ - diff --git a/pyrecest/tests/__init__.py b/pyrecest/tests/__init__.py index 8b137891..e69de29b 100644 --- a/pyrecest/tests/__init__.py +++ b/pyrecest/tests/__init__.py @@ -1 +0,0 @@ - diff --git a/pyrecest/tests/distributions/__init__.py b/pyrecest/tests/distributions/__init__.py index 8b137891..e69de29b 100644 --- a/pyrecest/tests/distributions/__init__.py +++ b/pyrecest/tests/distributions/__init__.py @@ -1 +0,0 @@ - diff --git a/pyrecest/tests/filters/__init__.py b/pyrecest/tests/filters/__init__.py index 8b137891..e69de29b 100644 --- a/pyrecest/tests/filters/__init__.py +++ b/pyrecest/tests/filters/__init__.py @@ -1 +0,0 @@ - diff --git a/pyrecest/utils/__init__.py b/pyrecest/utils/__init__.py index 8b137891..e69de29b 100644 --- a/pyrecest/utils/__init__.py +++ b/pyrecest/utils/__init__.py @@ -1 +0,0 @@ - From 097d6cb78482ac7f5671a585dbd516718a04c84e Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 12:41:41 +0100 Subject: [PATCH 182/232] Liniter changes --- .../distributions/abstract_se3_distribution.py | 3 ++- .../circle/abstract_circular_distribution.py | 1 + .../circle/circular_fourier_distribution.py | 3 +-- .../abstract_hyperhemispherical_distribution.py | 1 + .../abstract_hyperspherical_distribution.py | 1 + .../hyperspherical_dirac_distribution.py | 2 +- .../hypersphere_subset/watson_distribution.py | 1 + .../abstract_hypertoroidal_distribution.py | 1 + .../custom_hypertoroidal_distribution.py | 2 +- .../hypertoroidal_dirac_distribution.py | 4 +++- .../hypertoroidal_wrapped_normal_distribution.py | 2 +- .../toroidal_wrapped_normal_distribution.py | 1 + .../nonperiodic/abstract_linear_distribution.py | 1 + .../nonperiodic/gaussian_distribution.py | 8 ++++++-- .../nonperiodic/linear_dirac_distribution.py | 1 + .../distributions/nonperiodic/linear_mixture.py | 2 +- pyrecest/evaluation/determine_all_deviations.py | 10 +++------- pyrecest/evaluation/generate_groundtruth.py | 3 ++- pyrecest/evaluation/generate_measurements.py | 14 +++++++++----- pyrecest/evaluation/simulation_database.py | 16 ++++++---------- .../filters/abstract_nearest_neighbor_tracker.py | 2 +- pyrecest/filters/abstract_particle_filter.py | 2 +- .../filters/abstract_tracker_with_logging.py | 1 + pyrecest/filters/kalman_filter.py | 1 + .../test_abstract_circular_distribution.py | 1 + ...est_abstract_hypercylindrical_distribution.py | 2 ++ ...t_abstract_hypersphere_subset_distribution.py | 1 + .../test_abstract_hyperspherical_distribution.py | 1 + .../test_abstract_hypertoroidal_distribution.py | 1 + .../test_abstract_linear_distribution.py | 2 ++ .../tests/distributions/test_abstract_mixture.py | 13 ++++++++++--- .../distributions/test_bingham_distribution.py | 1 + .../test_circular_fourier_distribution.py | 2 ++ .../test_circular_uniform_distribution.py | 2 ++ .../test_custom_hypercylindrical_distribution.py | 2 ++ .../test_custom_linear_distribution.py | 1 + .../test_disk_uniform_distribution.py | 11 +++++------ ...test_ellipsoidal_ball_uniform_distribution.py | 1 + .../distributions/test_gaussian_distribution.py | 1 + .../test_hyperspherical_dirac_distribution.py | 1 + .../test_hyperspherical_uniform_distribution.py | 2 +- ..._hypertoroidal_wrapped_normal_distribution.py | 1 + .../test_linear_dirac_distribution.py | 1 + .../tests/distributions/test_linear_mixture.py | 1 + ...test_partially_wrapped_normal_distribution.py | 1 + .../test_sphere_subset_distribution.py | 1 + ...test_spherical_harmonics_distribution_real.py | 1 + .../test_toroidal_von_mises_sine_distribution.py | 2 ++ .../test_toroidal_wrapped_normal_distribution.py | 1 + .../distributions/test_von_mises_distribution.py | 1 + .../test_von_mises_fisher_distribution.py | 1 + .../distributions/test_watson_distribution.py | 1 + .../test_wrapped_cauchy_distribution.py | 2 ++ .../test_wrapped_laplace_distribution.py | 2 ++ .../filters/test_circular_particle_filter.py | 1 + .../filters/test_euclidean_particle_filter.py | 5 ++--- .../filters/test_global_nearest_neighbor.py | 1 + .../test_hypertoroidal_particle_filter.py | 1 + pyrecest/tests/filters/test_kalman_filter.py | 2 ++ .../tests/filters/test_random_matrix_tracker.py | 2 ++ .../test_toroidal_wrapped_normal_filter.py | 1 + pyrecest/tests/filters/test_von_mises_filter.py | 1 + .../tests/filters/test_wrapped_normal_filter.py | 1 + pyrecest/tests/test_evaluation_basic.py | 9 +++++---- pyrecest/tests/test_hyperspherical_sampler.py | 11 ++++++----- pyrecest/tests/test_metrics.py | 1 + pyrecest/utils/plotting.py | 1 + 67 files changed, 124 insertions(+), 57 deletions(-) diff --git a/pyrecest/distributions/abstract_se3_distribution.py b/pyrecest/distributions/abstract_se3_distribution.py index a4672dd8..2493611f 100644 --- a/pyrecest/distributions/abstract_se3_distribution.py +++ b/pyrecest/distributions/abstract_se3_distribution.py @@ -4,6 +4,7 @@ import matplotlib.pyplot as plt import quaternion + # pylint: disable=no-name-in-module,no-member from pyrecest.backend import column_stack, concatenate, int32, int64 @@ -55,7 +56,7 @@ def plot_state( def plot_point(se3point): # pylint: disable=too-many-locals """Visualize just a point in the SE(3) domain (no uncertainties are considered)""" import numpy as _np - + q = _np.quaternion(*se3point[:4]) rotMat = quaternion.as_rotation_matrix(q) diff --git a/pyrecest/distributions/circle/abstract_circular_distribution.py b/pyrecest/distributions/circle/abstract_circular_distribution.py index f0230093..54e14710 100644 --- a/pyrecest/distributions/circle/abstract_circular_distribution.py +++ b/pyrecest/distributions/circle/abstract_circular_distribution.py @@ -1,6 +1,7 @@ from math import pi import matplotlib.pyplot as plt + # pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, cos, linspace, mod, sin diff --git a/pyrecest/distributions/circle/circular_fourier_distribution.py b/pyrecest/distributions/circle/circular_fourier_distribution.py index 04f5792e..a86dbdc2 100644 --- a/pyrecest/distributions/circle/circular_fourier_distribution.py +++ b/pyrecest/distributions/circle/circular_fourier_distribution.py @@ -295,8 +295,7 @@ def from_distribution( ) -> "CircularFourierDistribution": if isinstance(distribution, CircularDiracDistribution): fd = CircularFourierDistribution( - conj(distribution.trigonometric_moment(n)) - / (2.0 * pi), + conj(distribution.trigonometric_moment(n)) / (2.0 * pi), transformation, multiplied_by_n=False, ) diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py index 4e33093f..14b4cc8d 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py @@ -4,6 +4,7 @@ from typing import Union import matplotlib.pyplot as plt + # pylint: disable=no-name-in-module,no-member from pyrecest.backend import ( array, diff --git a/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py b/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py index cf94168c..832ea204 100644 --- a/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/abstract_hyperspherical_distribution.py @@ -3,6 +3,7 @@ from typing import Union import matplotlib.pyplot as plt + # pylint: disable=no-name-in-module,no-member from pyrecest.backend import ( array, diff --git a/pyrecest/distributions/hypersphere_subset/hyperspherical_dirac_distribution.py b/pyrecest/distributions/hypersphere_subset/hyperspherical_dirac_distribution.py index b0045db0..e18cd241 100644 --- a/pyrecest/distributions/hypersphere_subset/hyperspherical_dirac_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/hyperspherical_dirac_distribution.py @@ -2,7 +2,7 @@ # pylint: disable=redefined-builtin,no-name-in-module,no-member # pylint: disable=no-name-in-module,no-member -from pyrecest.backend import linalg, reshape, sum, arctan2 +from pyrecest.backend import arctan2, linalg, reshape, sum from ..circle.circular_dirac_distribution import CircularDiracDistribution from .abstract_hypersphere_subset_dirac_distribution import ( diff --git a/pyrecest/distributions/hypersphere_subset/watson_distribution.py b/pyrecest/distributions/hypersphere_subset/watson_distribution.py index e4395e18..8531c712 100644 --- a/pyrecest/distributions/hypersphere_subset/watson_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/watson_distribution.py @@ -1,5 +1,6 @@ import mpmath import numpy.testing as npt + # pylint: disable=redefined-builtin,no-name-in-module,no-member from pyrecest.backend import ( abs, diff --git a/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py b/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py index bc79d426..43105a18 100644 --- a/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py +++ b/pyrecest/distributions/hypertorus/abstract_hypertoroidal_distribution.py @@ -3,6 +3,7 @@ from typing import Union import matplotlib.pyplot as plt + # pylint: disable=no-name-in-module,no-member import pyrecest.backend diff --git a/pyrecest/distributions/hypertorus/custom_hypertoroidal_distribution.py b/pyrecest/distributions/hypertorus/custom_hypertoroidal_distribution.py index 2e9ebe18..de9c8b88 100644 --- a/pyrecest/distributions/hypertorus/custom_hypertoroidal_distribution.py +++ b/pyrecest/distributions/hypertorus/custom_hypertoroidal_distribution.py @@ -4,8 +4,8 @@ from pyrecest.backend import mod, zeros from ..abstract_custom_distribution import AbstractCustomDistribution -from .abstract_hypertoroidal_distribution import AbstractHypertoroidalDistribution from ..circle.custom_circular_distribution import CustomCircularDistribution +from .abstract_hypertoroidal_distribution import AbstractHypertoroidalDistribution class CustomHypertoroidalDistribution( diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py b/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py index 53fa1984..fb603dc4 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py @@ -67,7 +67,9 @@ def trigonometric_moment(self, n: Union[int, int32, int64]): def apply_function( self, f: Callable, f_supports_multiple: bool = True ) -> "HypertoroidalDiracDistribution": - dist: HypertoroidalDiracDistribution = super().apply_function(f, f_supports_multiple) + dist: HypertoroidalDiracDistribution = super().apply_function( + f, f_supports_multiple + ) dist.d = mod(dist.d, 2.0 * pi) return dist diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py b/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py index 9d259152..b9848d1b 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_wrapped_normal_distribution.py @@ -46,7 +46,7 @@ def __init__(self, mu, C): AbstractHypertoroidalDistribution.__init__(self, numel_mu) self.mu = mod(mu, 2.0 * pi) self.C = C - + def set_mean(self, mu): """ Set the mean of the distribution. diff --git a/pyrecest/distributions/hypertorus/toroidal_wrapped_normal_distribution.py b/pyrecest/distributions/hypertorus/toroidal_wrapped_normal_distribution.py index 4ac3aa28..7cf6a1ee 100644 --- a/pyrecest/distributions/hypertorus/toroidal_wrapped_normal_distribution.py +++ b/pyrecest/distributions/hypertorus/toroidal_wrapped_normal_distribution.py @@ -1,4 +1,5 @@ from numpy import cos, exp, sin + # pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, zeros diff --git a/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py b/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py index 6057f851..e422bfdb 100644 --- a/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py +++ b/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py @@ -2,6 +2,7 @@ from typing import Union import matplotlib.pyplot as plt + # pylint: disable=no-name-in-module,no-member import pyrecest.backend diff --git a/pyrecest/distributions/nonperiodic/gaussian_distribution.py b/pyrecest/distributions/nonperiodic/gaussian_distribution.py index 71a395da..0066b697 100644 --- a/pyrecest/distributions/nonperiodic/gaussian_distribution.py +++ b/pyrecest/distributions/nonperiodic/gaussian_distribution.py @@ -1,10 +1,12 @@ import copy -# pylint: disable=no-name-in-module,no-member -from pyrecest.backend import dot, linalg, ndim, random # pylint: disable=no-name-in-module import pyrecest.backend + +# pylint: disable=no-name-in-module,no-member +from pyrecest.backend import dot, linalg, ndim, random from scipy.linalg import cholesky + from .abstract_linear_distribution import AbstractLinearDistribution @@ -41,9 +43,11 @@ def pdf(self, xs): ), "Dimension incorrect" if pyrecest.backend.__name__ == "pyrecest.numpy": from scipy.stats import multivariate_normal as mvn + pdfvals = mvn.pdf(xs, self.mu, self.C) elif pyrecest.backend.__name__ == "pyrecest.pytorch": from torch.distributions import MultivariateNormal + distribution = MultivariateNormal(self.mu, self.C) log_probs = distribution.log_prob(xs) pdfvals = pyrecest.backend.exp(log_probs) diff --git a/pyrecest/distributions/nonperiodic/linear_dirac_distribution.py b/pyrecest/distributions/nonperiodic/linear_dirac_distribution.py index 0bde68b1..af551645 100644 --- a/pyrecest/distributions/nonperiodic/linear_dirac_distribution.py +++ b/pyrecest/distributions/nonperiodic/linear_dirac_distribution.py @@ -1,4 +1,5 @@ import matplotlib.pyplot as plt + # pylint: disable=no-name-in-module,no-member from pyrecest.backend import cov, ones, reshape diff --git a/pyrecest/distributions/nonperiodic/linear_mixture.py b/pyrecest/distributions/nonperiodic/linear_mixture.py index 8fb2de68..cc5fb309 100644 --- a/pyrecest/distributions/nonperiodic/linear_mixture.py +++ b/pyrecest/distributions/nonperiodic/linear_mixture.py @@ -1,9 +1,9 @@ import warnings +from typing import Sequence from ..abstract_mixture import AbstractMixture from .abstract_linear_distribution import AbstractLinearDistribution from .gaussian_distribution import GaussianDistribution -from typing import Sequence class LinearMixture(AbstractMixture, AbstractLinearDistribution): diff --git a/pyrecest/evaluation/determine_all_deviations.py b/pyrecest/evaluation/determine_all_deviations.py index 102722c0..04423452 100644 --- a/pyrecest/evaluation/determine_all_deviations.py +++ b/pyrecest/evaluation/determine_all_deviations.py @@ -16,13 +16,9 @@ def determine_all_deviations( if mean_calculation_symm != "": raise NotImplementedError("Not implemented yet") - assert ( - groundtruths.ndim == 2 - and groundtruths[0, 0].ndim - in ( - 1, - 2, - ) + assert groundtruths.ndim == 2 and groundtruths[0, 0].ndim in ( + 1, + 2, ), "Assuming groundtruths to be a 2-D array of shape (n_runs, n_timesteps) composed arrays of shape (n_dim,) or (n_targets,n_dim)." all_deviations_last_mat = np.empty((len(results), groundtruths.shape[0])) diff --git a/pyrecest/evaluation/generate_groundtruth.py b/pyrecest/evaluation/generate_groundtruth.py index 942a413b..02722d71 100644 --- a/pyrecest/evaluation/generate_groundtruth.py +++ b/pyrecest/evaluation/generate_groundtruth.py @@ -1,7 +1,8 @@ import numpy as np # pylint: disable=no-name-in-module,no-member -from pyrecest.backend import empty, atleast_2d, empty_like, squeeze +from pyrecest.backend import atleast_2d, empty_like, squeeze + # pylint: disable=too-many-branches def generate_groundtruth(simulation_param, x0=None): diff --git a/pyrecest/evaluation/generate_measurements.py b/pyrecest/evaluation/generate_measurements.py index 815f8882..068a5db6 100644 --- a/pyrecest/evaluation/generate_measurements.py +++ b/pyrecest/evaluation/generate_measurements.py @@ -1,8 +1,10 @@ -import numpy as np from math import pi -# pylint: disable=redefined-builtin,no-name-in-module,no-member -from pyrecest.backend import tile, squeeze, sum, zeros, mod + +import numpy as np from beartype import beartype + +# pylint: disable=redefined-builtin,no-name-in-module,no-member +from pyrecest.backend import mod, squeeze, sum, tile, zeros from pyrecest.distributions import ( AbstractHypertoroidalDistribution, GaussianDistribution, @@ -30,7 +32,9 @@ def generate_measurements(groundtruth, simulation_config): Comprises timesteps elements, each of which is a numpy array of shape (n_meas_at_individual_time_step[t], n_dim). """ - assert "n_meas_at_individual_time_step" not in simulation_config or np.shape(simulation_config["n_meas_at_individual_time_step"]) == (simulation_config["n_timesteps"],) + assert "n_meas_at_individual_time_step" not in simulation_config or np.shape( + simulation_config["n_meas_at_individual_time_step"] + ) == (simulation_config["n_timesteps"],) measurements = np.empty(simulation_config["n_timesteps"], dtype=object) if simulation_config.get("mtt", False) and simulation_config.get("eot", False): @@ -117,7 +121,7 @@ def generate_measurements(groundtruth, simulation_config): for t in range(simulation_config["n_timesteps"]): n_meas_at_t = sum(n_observations[t, :]) - measurements[t] = float('NaN') * zeros( + measurements[t] = float("NaN") * zeros( (simulation_config["meas_matrix_for_each_target"].shape[0], n_meas_at_t) ) diff --git a/pyrecest/evaluation/simulation_database.py b/pyrecest/evaluation/simulation_database.py index e1d2a985..6698e2ff 100644 --- a/pyrecest/evaluation/simulation_database.py +++ b/pyrecest/evaluation/simulation_database.py @@ -2,9 +2,11 @@ from typing import Optional from beartype import beartype -from pyrecest.distributions import GaussianDistribution + # pylint: disable=no-name-in-module,no-member from pyrecest.backend import eye, zeros +from pyrecest.distributions import GaussianDistribution + @beartype def simulation_database( @@ -27,15 +29,9 @@ def simulation_database( elif scenario_name == "R2randomWalk": simulation_param["manifold"] = "Euclidean" simulation_param["n_timesteps"] = 10 - simulation_param["initial_prior"] = GaussianDistribution( - zeros(2), 0.5 * eye(2) - ) - simulation_param["meas_noise"] = GaussianDistribution( - zeros(2), 0.5 * eye(2) - ) - simulation_param["sys_noise"] = GaussianDistribution( - zeros(2), 0.5 * eye(2) - ) + simulation_param["initial_prior"] = GaussianDistribution(zeros(2), 0.5 * eye(2)) + simulation_param["meas_noise"] = GaussianDistribution(zeros(2), 0.5 * eye(2)) + simulation_param["sys_noise"] = GaussianDistribution(zeros(2), 0.5 * eye(2)) simulation_param["gen_next_state_without_noise_is_vectorized"] = True else: raise ValueError("Scenario not recognized.") diff --git a/pyrecest/filters/abstract_nearest_neighbor_tracker.py b/pyrecest/filters/abstract_nearest_neighbor_tracker.py index 2bc0919e..c9726231 100644 --- a/pyrecest/filters/abstract_nearest_neighbor_tracker.py +++ b/pyrecest/filters/abstract_nearest_neighbor_tracker.py @@ -3,7 +3,7 @@ from abc import abstractmethod # pylint: disable=no-name-in-module,no-member -from pyrecest.backend import empty, ndim, dstack +from pyrecest.backend import dstack, empty, ndim from pyrecest.distributions import GaussianDistribution from .abstract_euclidean_filter import AbstractEuclideanFilter diff --git a/pyrecest/filters/abstract_particle_filter.py b/pyrecest/filters/abstract_particle_filter.py index 5cfb08ba..4ea9ce54 100644 --- a/pyrecest/filters/abstract_particle_filter.py +++ b/pyrecest/filters/abstract_particle_filter.py @@ -51,7 +51,7 @@ def predict_nonlinear_nonadditive(self, f, samples, weights): weights = weights / sum(weights) n_particles = self.filter_state.w.shape[0] noise_samples = random.choice(samples, n_particles, p=weights) - + d = zeros((n_particles, self.filter_state.dim)) for i in range(n_particles): d[i, :] = f(self.filter_state.d[i, :], noise_samples[i]) diff --git a/pyrecest/filters/abstract_tracker_with_logging.py b/pyrecest/filters/abstract_tracker_with_logging.py index fc5456f1..f949be24 100644 --- a/pyrecest/filters/abstract_tracker_with_logging.py +++ b/pyrecest/filters/abstract_tracker_with_logging.py @@ -15,6 +15,7 @@ def __init__(self, **kwargs): def _store_estimates(self, curr_ests, estimates_over_time): import numpy as _np + # Ensure curr_ests is a 2D array if curr_ests.ndim == 1: curr_ests = curr_ests.reshape(-1, 1) diff --git a/pyrecest/filters/kalman_filter.py b/pyrecest/filters/kalman_filter.py index 329969f1..b4ff36bd 100644 --- a/pyrecest/filters/kalman_filter.py +++ b/pyrecest/filters/kalman_filter.py @@ -1,6 +1,7 @@ # pylint: disable=no-name-in-module,no-member import pyrecest.backend from filterpy.kalman import KalmanFilter as FilterPyKalmanFilter + # pylint: disable=no-name-in-module,no-member from pyrecest.backend import eye from pyrecest.distributions import GaussianDistribution diff --git a/pyrecest/tests/distributions/test_abstract_circular_distribution.py b/pyrecest/tests/distributions/test_abstract_circular_distribution.py index 081370f6..46bf96dd 100644 --- a/pyrecest/tests/distributions/test_abstract_circular_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_circular_distribution.py @@ -3,6 +3,7 @@ # pylint: disable=no-name-in-module,no-member import pyrecest.backend + # pylint: disable=no-name-in-module,no-member from pyrecest.backend import allclose, arange, array from pyrecest.distributions import VonMisesDistribution, WrappedNormalDistribution diff --git a/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py b/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py index b511f363..3bd064a2 100644 --- a/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hypercylindrical_distribution.py @@ -2,8 +2,10 @@ from math import pi import numpy.testing as npt + # pylint: disable=no-name-in-module,no-member import pyrecest.backend + # pylint: disable=no-name-in-module,no-member from pyrecest.backend import allclose, arange, array, column_stack, diff, ones, zeros from pyrecest.distributions.cart_prod.partially_wrapped_normal_distribution import ( diff --git a/pyrecest/tests/distributions/test_abstract_hypersphere_subset_distribution.py b/pyrecest/tests/distributions/test_abstract_hypersphere_subset_distribution.py index 4442e87f..c539632e 100644 --- a/pyrecest/tests/distributions/test_abstract_hypersphere_subset_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hypersphere_subset_distribution.py @@ -1,6 +1,7 @@ import unittest import numpy.testing as npt + # pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, cos, linalg, sin from pyrecest.distributions import VonMisesFisherDistribution diff --git a/pyrecest/tests/distributions/test_abstract_hyperspherical_distribution.py b/pyrecest/tests/distributions/test_abstract_hyperspherical_distribution.py index c27b43bc..106176c0 100644 --- a/pyrecest/tests/distributions/test_abstract_hyperspherical_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hyperspherical_distribution.py @@ -2,6 +2,7 @@ from math import pi import matplotlib + # pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, linalg, sqrt from pyrecest.distributions import ( diff --git a/pyrecest/tests/distributions/test_abstract_hypertoroidal_distribution.py b/pyrecest/tests/distributions/test_abstract_hypertoroidal_distribution.py index 62674c19..981e720b 100644 --- a/pyrecest/tests/distributions/test_abstract_hypertoroidal_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hypertoroidal_distribution.py @@ -2,6 +2,7 @@ from math import pi import numpy.testing as npt + # pylint: disable=no-name-in-module,no-member from pyrecest.backend import array from pyrecest.distributions import AbstractHypertoroidalDistribution diff --git a/pyrecest/tests/distributions/test_abstract_linear_distribution.py b/pyrecest/tests/distributions/test_abstract_linear_distribution.py index eec29c08..8fb0aa55 100644 --- a/pyrecest/tests/distributions/test_abstract_linear_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_linear_distribution.py @@ -2,8 +2,10 @@ import matplotlib import numpy.testing as npt + # pylint: disable=no-name-in-module,no-member import pyrecest.backend + # pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, diag, isclose from pyrecest.distributions import ( diff --git a/pyrecest/tests/distributions/test_abstract_mixture.py b/pyrecest/tests/distributions/test_abstract_mixture.py index 4b472921..1ff27ab8 100644 --- a/pyrecest/tests/distributions/test_abstract_mixture.py +++ b/pyrecest/tests/distributions/test_abstract_mixture.py @@ -2,6 +2,7 @@ # pylint: disable=no-name-in-module,no-member import pyrecest.backend + # pylint: disable=no-name-in-module,no-member from pyrecest.backend import allclose, array, eye, linalg, ones from pyrecest.distributions import VonMisesFisherDistribution @@ -36,14 +37,20 @@ def test_sample_metropolis_hastings_basics_only_t2(self): reason="Not supported on PyTorch backend", ) def test_sample_metropolis_hastings_basics_only_s2(self): - vmf1 = VonMisesFisherDistribution(array([1.0, 0.0, 0.0]), 2.0) # Needs to be float for scipy - vmf2 = VonMisesFisherDistribution(array([0.0, 1.0, 0.0]), 2.0) # Needs to be float for scipy + vmf1 = VonMisesFisherDistribution( + array([1.0, 0.0, 0.0]), 2.0 + ) # Needs to be float for scipy + vmf2 = VonMisesFisherDistribution( + array([0.0, 1.0, 0.0]), 2.0 + ) # Needs to be float for scipy mix = HypersphericalMixture([vmf1, vmf2], array([0.5, 0.5])) s = self._test_sample(mix, 10) self.assertTrue(allclose(linalg.norm(s, axis=1), ones(10), rtol=1e-10)) def test_sample_metropolis_hastings_basics_only_h2(self): - vmf = VonMisesFisherDistribution(array([1.0, 0.0, 0.0]), 2.0) # Needs to be float for scipy + vmf = VonMisesFisherDistribution( + array([1.0, 0.0, 0.0]), 2.0 + ) # Needs to be float for scipy mix = CustomHyperhemisphericalDistribution( lambda x: vmf.pdf(x) + vmf.pdf(-x), 2 ) diff --git a/pyrecest/tests/distributions/test_bingham_distribution.py b/pyrecest/tests/distributions/test_bingham_distribution.py index 1933fc77..39c3e131 100644 --- a/pyrecest/tests/distributions/test_bingham_distribution.py +++ b/pyrecest/tests/distributions/test_bingham_distribution.py @@ -1,6 +1,7 @@ import unittest import numpy.testing as npt + # pylint: disable=no-name-in-module,no-member from pyrecest.backend import array from pyrecest.distributions import BinghamDistribution diff --git a/pyrecest/tests/distributions/test_circular_fourier_distribution.py b/pyrecest/tests/distributions/test_circular_fourier_distribution.py index 7074b7f2..0d5ca0c2 100644 --- a/pyrecest/tests/distributions/test_circular_fourier_distribution.py +++ b/pyrecest/tests/distributions/test_circular_fourier_distribution.py @@ -3,9 +3,11 @@ from math import pi import numpy.testing as npt + # pylint: disable=no-name-in-module,no-member import pyrecest.backend from parameterized import parameterized + # pylint: disable=no-name-in-module,no-member from pyrecest.backend import arange, array, ceil, linspace, sqrt from pyrecest.distributions import ( diff --git a/pyrecest/tests/distributions/test_circular_uniform_distribution.py b/pyrecest/tests/distributions/test_circular_uniform_distribution.py index 9e1a18cd..52599c52 100644 --- a/pyrecest/tests/distributions/test_circular_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_circular_uniform_distribution.py @@ -2,8 +2,10 @@ from math import pi import numpy.testing as npt + # pylint: disable=no-name-in-module,no-member import pyrecest.backend + # pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, ones from pyrecest.distributions.circle.circular_uniform_distribution import ( diff --git a/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py b/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py index f05810fb..05328c04 100644 --- a/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py +++ b/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py @@ -2,8 +2,10 @@ from math import pi import numpy.testing as npt + # pylint: disable=no-name-in-module,no-member import pyrecest.backend + # pylint: disable=no-name-in-module,no-member from pyrecest.backend import arange, array, eye, linspace, meshgrid, random from pyrecest.distributions import ( diff --git a/pyrecest/tests/distributions/test_custom_linear_distribution.py b/pyrecest/tests/distributions/test_custom_linear_distribution.py index 1c98cb48..52646931 100644 --- a/pyrecest/tests/distributions/test_custom_linear_distribution.py +++ b/pyrecest/tests/distributions/test_custom_linear_distribution.py @@ -2,6 +2,7 @@ from math import pi import numpy.testing as npt + # pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, concatenate, eye, linspace, meshgrid from pyrecest.distributions import CustomLinearDistribution, GaussianDistribution diff --git a/pyrecest/tests/distributions/test_disk_uniform_distribution.py b/pyrecest/tests/distributions/test_disk_uniform_distribution.py index d3b07164..b791d6d4 100644 --- a/pyrecest/tests/distributions/test_disk_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_disk_uniform_distribution.py @@ -1,12 +1,11 @@ """ Test cases for DiskUniformDistribution""" +import unittest from math import pi +import numpy.testing as npt + # pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, concatenate, ones, sqrt, zeros - -import unittest - -import numpy.testing as npt from pyrecest.distributions import DiskUniformDistribution @@ -18,8 +17,8 @@ def test_pdf(self): xs = array( [ # Without multiplying it by 0.99, machine precision can play a role - [0.5, 0.0, 1.0, 1.0 / sqrt(2.0)*0.99, 0.0, 3.0, 1.5], - [0.5, 1.0, 0.0, 1.0 / sqrt(2.0)*0.99, 3.0, 0.0, 1.5], + [0.5, 0.0, 1.0, 1.0 / sqrt(2.0) * 0.99, 0.0, 3.0, 1.5], + [0.5, 1.0, 0.0, 1.0 / sqrt(2.0) * 0.99, 3.0, 0.0, 1.5], ] ).T pdf_values = dist.pdf(xs) diff --git a/pyrecest/tests/distributions/test_ellipsoidal_ball_uniform_distribution.py b/pyrecest/tests/distributions/test_ellipsoidal_ball_uniform_distribution.py index fcb6361d..ead743f2 100644 --- a/pyrecest/tests/distributions/test_ellipsoidal_ball_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_ellipsoidal_ball_uniform_distribution.py @@ -1,6 +1,7 @@ import unittest import numpy.testing as npt + # pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, diag from pyrecest.distributions import EllipsoidalBallUniformDistribution diff --git a/pyrecest/tests/distributions/test_gaussian_distribution.py b/pyrecest/tests/distributions/test_gaussian_distribution.py index 629ee8ec..683336ae 100644 --- a/pyrecest/tests/distributions/test_gaussian_distribution.py +++ b/pyrecest/tests/distributions/test_gaussian_distribution.py @@ -1,6 +1,7 @@ import unittest import scipy + # pylint: disable=no-name-in-module,no-member from pyrecest.backend import allclose, array, linspace from pyrecest.distributions import GaussianDistribution diff --git a/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py b/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py index da51cfd1..c2fa36d0 100644 --- a/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py @@ -2,6 +2,7 @@ from math import pi import numpy.testing as npt + # pylint: disable=no-name-in-module,no-member import pyrecest.backend diff --git a/pyrecest/tests/distributions/test_hyperspherical_uniform_distribution.py b/pyrecest/tests/distributions/test_hyperspherical_uniform_distribution.py index 4fbff8d7..13c953d0 100644 --- a/pyrecest/tests/distributions/test_hyperspherical_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_hyperspherical_uniform_distribution.py @@ -1,8 +1,8 @@ """ Test for uniform distribution on the hypersphere """ # pylint: disable=no-name-in-module,no-member -from pyrecest.backend import allclose, linalg, ones, random import unittest +from pyrecest.backend import allclose, linalg, ones, random from pyrecest.distributions import ( AbstractHypersphericalDistribution, HypersphericalUniformDistribution, diff --git a/pyrecest/tests/distributions/test_hypertoroidal_wrapped_normal_distribution.py b/pyrecest/tests/distributions/test_hypertoroidal_wrapped_normal_distribution.py index 87fd205d..8786534b 100644 --- a/pyrecest/tests/distributions/test_hypertoroidal_wrapped_normal_distribution.py +++ b/pyrecest/tests/distributions/test_hypertoroidal_wrapped_normal_distribution.py @@ -1,6 +1,7 @@ import unittest import numpy.testing as npt + # pylint: disable=no-name-in-module,no-member from pyrecest.backend import array from pyrecest.distributions import HypertoroidalWNDistribution diff --git a/pyrecest/tests/distributions/test_linear_dirac_distribution.py b/pyrecest/tests/distributions/test_linear_dirac_distribution.py index aafceabd..5b06c89f 100644 --- a/pyrecest/tests/distributions/test_linear_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_linear_dirac_distribution.py @@ -1,6 +1,7 @@ import unittest import numpy.testing as npt + # pylint: disable=no-name-in-module,no-member from pyrecest.backend import allclose, array, eye, random from pyrecest.distributions import GaussianDistribution diff --git a/pyrecest/tests/distributions/test_linear_mixture.py b/pyrecest/tests/distributions/test_linear_mixture.py index 36183218..783b3245 100644 --- a/pyrecest/tests/distributions/test_linear_mixture.py +++ b/pyrecest/tests/distributions/test_linear_mixture.py @@ -2,6 +2,7 @@ from warnings import catch_warnings, simplefilter import numpy.testing as npt + # pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, column_stack, diag, linspace, meshgrid from pyrecest.distributions import GaussianDistribution diff --git a/pyrecest/tests/distributions/test_partially_wrapped_normal_distribution.py b/pyrecest/tests/distributions/test_partially_wrapped_normal_distribution.py index 25543064..61223c5c 100644 --- a/pyrecest/tests/distributions/test_partially_wrapped_normal_distribution.py +++ b/pyrecest/tests/distributions/test_partially_wrapped_normal_distribution.py @@ -2,6 +2,7 @@ import numpy.testing as npt import scipy.linalg + # pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, ones from pyrecest.distributions.cart_prod.partially_wrapped_normal_distribution import ( diff --git a/pyrecest/tests/distributions/test_sphere_subset_distribution.py b/pyrecest/tests/distributions/test_sphere_subset_distribution.py index bc359c0e..ad4d014f 100644 --- a/pyrecest/tests/distributions/test_sphere_subset_distribution.py +++ b/pyrecest/tests/distributions/test_sphere_subset_distribution.py @@ -3,6 +3,7 @@ import numpy.testing as npt from parameterized import parameterized + # pylint: disable=no-name-in-module,no-member from pyrecest.backend import array from pyrecest.distributions.hypersphere_subset.abstract_sphere_subset_distribution import ( diff --git a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py index 81c7c9eb..1ef0fff7 100644 --- a/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py +++ b/pyrecest/tests/distributions/test_spherical_harmonics_distribution_real.py @@ -4,6 +4,7 @@ import numpy.testing as npt from parameterized import parameterized + # pylint: disable=no-name-in-module,no-member from pyrecest.backend import ( allclose, diff --git a/pyrecest/tests/distributions/test_toroidal_von_mises_sine_distribution.py b/pyrecest/tests/distributions/test_toroidal_von_mises_sine_distribution.py index 0f416e75..d40f8c4f 100644 --- a/pyrecest/tests/distributions/test_toroidal_von_mises_sine_distribution.py +++ b/pyrecest/tests/distributions/test_toroidal_von_mises_sine_distribution.py @@ -2,9 +2,11 @@ from math import pi import numpy.testing as npt + # pylint: disable=no-name-in-module,no-member import pyrecest.backend from parameterized import parameterized + # pylint: disable=no-name-in-module,no-member from pyrecest.backend import arange, array, column_stack, cos, exp, sin from pyrecest.distributions.hypertorus.toroidal_von_mises_sine_distribution import ( diff --git a/pyrecest/tests/distributions/test_toroidal_wrapped_normal_distribution.py b/pyrecest/tests/distributions/test_toroidal_wrapped_normal_distribution.py index 2959a4c1..807c000c 100644 --- a/pyrecest/tests/distributions/test_toroidal_wrapped_normal_distribution.py +++ b/pyrecest/tests/distributions/test_toroidal_wrapped_normal_distribution.py @@ -3,6 +3,7 @@ # pylint: disable=no-name-in-module,no-member import pyrecest.backend + # pylint: disable=no-name-in-module,no-member from pyrecest.backend import allclose, array, mod from pyrecest.distributions.hypertorus.toroidal_wrapped_normal_distribution import ( diff --git a/pyrecest/tests/distributions/test_von_mises_distribution.py b/pyrecest/tests/distributions/test_von_mises_distribution.py index 319a43dd..6f96d159 100644 --- a/pyrecest/tests/distributions/test_von_mises_distribution.py +++ b/pyrecest/tests/distributions/test_von_mises_distribution.py @@ -3,6 +3,7 @@ import matplotlib import matplotlib.pyplot as plt import numpy.testing as npt + # pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, linspace from pyrecest.distributions import VonMisesDistribution diff --git a/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py b/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py index 32885dbd..4ecfac71 100644 --- a/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py +++ b/pyrecest/tests/distributions/test_von_mises_fisher_distribution.py @@ -2,6 +2,7 @@ import numpy.testing as npt from parameterized import parameterized + # pylint: disable=no-name-in-module,no-member from pyrecest.backend import allclose, array, linalg, sqrt from pyrecest.distributions import VonMisesFisherDistribution diff --git a/pyrecest/tests/distributions/test_watson_distribution.py b/pyrecest/tests/distributions/test_watson_distribution.py index 9ac6f260..f1772a93 100644 --- a/pyrecest/tests/distributions/test_watson_distribution.py +++ b/pyrecest/tests/distributions/test_watson_distribution.py @@ -1,6 +1,7 @@ import unittest import numpy.testing as npt + # pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, linalg from pyrecest.distributions import BinghamDistribution, WatsonDistribution diff --git a/pyrecest/tests/distributions/test_wrapped_cauchy_distribution.py b/pyrecest/tests/distributions/test_wrapped_cauchy_distribution.py index 4461fc1c..c4b752b1 100644 --- a/pyrecest/tests/distributions/test_wrapped_cauchy_distribution.py +++ b/pyrecest/tests/distributions/test_wrapped_cauchy_distribution.py @@ -2,8 +2,10 @@ from math import pi import numpy.testing as npt + # pylint: disable=no-name-in-module,no-member import pyrecest.backend + # pylint: disable=no-name-in-module,no-member from pyrecest.backend import arange, array from pyrecest.distributions.circle.custom_circular_distribution import ( diff --git a/pyrecest/tests/distributions/test_wrapped_laplace_distribution.py b/pyrecest/tests/distributions/test_wrapped_laplace_distribution.py index fa882e9c..f39bdc20 100644 --- a/pyrecest/tests/distributions/test_wrapped_laplace_distribution.py +++ b/pyrecest/tests/distributions/test_wrapped_laplace_distribution.py @@ -2,8 +2,10 @@ from math import pi import numpy.testing as npt + # pylint: disable=no-name-in-module,no-member import pyrecest.backend + # pylint: disable=no-name-in-module,no-member from pyrecest.backend import arange, array, exp, linspace from pyrecest.distributions.circle.wrapped_laplace_distribution import ( diff --git a/pyrecest/tests/filters/test_circular_particle_filter.py b/pyrecest/tests/filters/test_circular_particle_filter.py index 4dd34ba9..fe3d21fe 100644 --- a/pyrecest/tests/filters/test_circular_particle_filter.py +++ b/pyrecest/tests/filters/test_circular_particle_filter.py @@ -2,6 +2,7 @@ from math import pi import numpy.testing as npt + # pylint: disable=no-name-in-module,no-member from pyrecest.backend import allclose, arange, array, random from pyrecest.distributions import ( diff --git a/pyrecest/tests/filters/test_euclidean_particle_filter.py b/pyrecest/tests/filters/test_euclidean_particle_filter.py index 8a106395..543e5267 100644 --- a/pyrecest/tests/filters/test_euclidean_particle_filter.py +++ b/pyrecest/tests/filters/test_euclidean_particle_filter.py @@ -2,6 +2,7 @@ from math import pi import numpy.testing as npt + # pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, mean, ones, random, zeros, zeros_like from pyrecest.distributions import GaussianDistribution @@ -31,9 +32,7 @@ def test_predict_update_cycle_3d(self): # jscpd:ignore-end self.assertEqual(self.pf.get_point_estimate().shape, (3,)) - npt.assert_allclose( - self.pf.get_point_estimate(), self.forced_mean, atol=0.1 - ) + npt.assert_allclose(self.pf.get_point_estimate(), self.forced_mean, atol=0.1) def test_predict_nonlinear_nonadditive(self): n_noise_samples = 10 diff --git a/pyrecest/tests/filters/test_global_nearest_neighbor.py b/pyrecest/tests/filters/test_global_nearest_neighbor.py index 44a12a08..114a3e80 100644 --- a/pyrecest/tests/filters/test_global_nearest_neighbor.py +++ b/pyrecest/tests/filters/test_global_nearest_neighbor.py @@ -1,6 +1,7 @@ import unittest import numpy.testing as npt + # pylint: disable=no-name-in-module,no-member import pyrecest.backend import scipy diff --git a/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py b/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py index 8ee26e73..178d51cb 100644 --- a/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py +++ b/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py @@ -2,6 +2,7 @@ from math import pi import numpy.testing as npt + # pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, random, zeros from pyrecest.distributions import HypertoroidalWNDistribution diff --git a/pyrecest/tests/filters/test_kalman_filter.py b/pyrecest/tests/filters/test_kalman_filter.py index e089040b..1e6f28f6 100644 --- a/pyrecest/tests/filters/test_kalman_filter.py +++ b/pyrecest/tests/filters/test_kalman_filter.py @@ -2,8 +2,10 @@ import unittest import numpy.testing as npt + # pylint: disable=no-name-in-module,no-member import pyrecest.backend + # pylint: disable=no-name-in-module,no-member from pyrecest.backend import allclose, array, diag, eye from pyrecest.distributions import GaussianDistribution diff --git a/pyrecest/tests/filters/test_random_matrix_tracker.py b/pyrecest/tests/filters/test_random_matrix_tracker.py index 7d68cdeb..149538de 100644 --- a/pyrecest/tests/filters/test_random_matrix_tracker.py +++ b/pyrecest/tests/filters/test_random_matrix_tracker.py @@ -3,9 +3,11 @@ import matplotlib.pyplot as plt import numpy.testing as npt + # pylint: disable=no-name-in-module,no-member import pyrecest.backend from parameterized import parameterized + # pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, concatenate, diag, eye, linalg, mean, zeros from pyrecest.distributions.nonperiodic.gaussian_distribution import ( diff --git a/pyrecest/tests/filters/test_toroidal_wrapped_normal_filter.py b/pyrecest/tests/filters/test_toroidal_wrapped_normal_filter.py index d7920706..dfc18e45 100644 --- a/pyrecest/tests/filters/test_toroidal_wrapped_normal_filter.py +++ b/pyrecest/tests/filters/test_toroidal_wrapped_normal_filter.py @@ -2,6 +2,7 @@ from math import pi import numpy.testing as npt + # pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, mod from pyrecest.distributions.hypertorus.toroidal_wrapped_normal_distribution import ( diff --git a/pyrecest/tests/filters/test_von_mises_filter.py b/pyrecest/tests/filters/test_von_mises_filter.py index 0eb90585..04221807 100644 --- a/pyrecest/tests/filters/test_von_mises_filter.py +++ b/pyrecest/tests/filters/test_von_mises_filter.py @@ -1,6 +1,7 @@ import unittest import numpy.testing as npt + # pylint: disable=no-name-in-module,no-member from pyrecest.backend import array from pyrecest.distributions import VonMisesDistribution diff --git a/pyrecest/tests/filters/test_wrapped_normal_filter.py b/pyrecest/tests/filters/test_wrapped_normal_filter.py index b3595093..c309bc31 100644 --- a/pyrecest/tests/filters/test_wrapped_normal_filter.py +++ b/pyrecest/tests/filters/test_wrapped_normal_filter.py @@ -1,6 +1,7 @@ import unittest import numpy.testing as npt + # pylint: disable=no-name-in-module,no-member from pyrecest.backend import array from pyrecest.distributions import WrappedNormalDistribution diff --git a/pyrecest/tests/test_evaluation_basic.py b/pyrecest/tests/test_evaluation_basic.py index 56413e2f..00a5bb83 100644 --- a/pyrecest/tests/test_evaluation_basic.py +++ b/pyrecest/tests/test_evaluation_basic.py @@ -3,13 +3,14 @@ import unittest from typing import Optional -# pylint: disable=redefined-builtin,no-name-in-module,no-member -from pyrecest.backend import array, sqrt, eye, zeros, all +import numpy as np + # pylint: disable=no-name-in-module,no-member import pyrecest.backend - -import numpy as np from parameterized import parameterized + +# pylint: disable=redefined-builtin,no-name-in-module,no-member +from pyrecest.backend import all, array, eye, sqrt, zeros from pyrecest.distributions import ( GaussianDistribution, HypertoroidalWrappedNormalDistribution, diff --git a/pyrecest/tests/test_hyperspherical_sampler.py b/pyrecest/tests/test_hyperspherical_sampler.py index db2050f3..c9606e0e 100644 --- a/pyrecest/tests/test_hyperspherical_sampler.py +++ b/pyrecest/tests/test_hyperspherical_sampler.py @@ -1,9 +1,12 @@ import importlib.util import unittest -# pylint: disable=no-name-in-module,no-member -from pyrecest.backend import allclose, linalg, prod, random + from parameterized import parameterized + +# pylint: disable=no-name-in-module,no-member +from pyrecest.backend import allclose, linalg, random from pyrecest.sampling.hyperspherical_sampler import get_grid_hypersphere + from ..sampling.hyperspherical_sampler import ( AbstractHopfBasedS3Sampler, DriscollHealySampler, @@ -126,9 +129,7 @@ def test_conversion(self): # Generate a sample matrix of size (n, 4) containing unit vectors. n = 100 # sample size random_vectors = random.normal(0.0, 1.0, (n, 4)) - unit_vectors = ( - random_vectors / linalg.norm(random_vectors, axis=1)[:, None] - ) + unit_vectors = random_vectors / linalg.norm(random_vectors, axis=1)[:, None] # Pass the quaternions through the conversion functions θ, ϕ, ψ = AbstractHopfBasedS3Sampler.quaternion_to_hopf_yershova(unit_vectors) diff --git a/pyrecest/tests/test_metrics.py b/pyrecest/tests/test_metrics.py index 189db8c3..a05d9925 100644 --- a/pyrecest/tests/test_metrics.py +++ b/pyrecest/tests/test_metrics.py @@ -1,6 +1,7 @@ import unittest import numpy.testing as npt + # pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, random, repeat from pyrecest.utils.metrics import anees diff --git a/pyrecest/utils/plotting.py b/pyrecest/utils/plotting.py index 971dadc5..ffa7b5ea 100644 --- a/pyrecest/utils/plotting.py +++ b/pyrecest/utils/plotting.py @@ -1,6 +1,7 @@ from math import pi import matplotlib.pyplot as plt + # pylint: disable=no-name-in-module,no-member from pyrecest.backend import ( array, From 1ab95765a74cda2a5b1ff90a8e370c2b1a647c1a Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 12:51:09 +0100 Subject: [PATCH 183/232] More --- pyrecest/distributions/nonperiodic/gaussian_distribution.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pyrecest/distributions/nonperiodic/gaussian_distribution.py b/pyrecest/distributions/nonperiodic/gaussian_distribution.py index 0066b697..f348ad83 100644 --- a/pyrecest/distributions/nonperiodic/gaussian_distribution.py +++ b/pyrecest/distributions/nonperiodic/gaussian_distribution.py @@ -46,6 +46,7 @@ def pdf(self, xs): pdfvals = mvn.pdf(xs, self.mu, self.C) elif pyrecest.backend.__name__ == "pyrecest.pytorch": + # pylint: disable=import-error from torch.distributions import MultivariateNormal distribution = MultivariateNormal(self.mu, self.C) From d18e5e31104ca79dc5cb21c56025ac550d8c03f0 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 14:59:57 +0100 Subject: [PATCH 184/232] Added jax backend --- pyrecest/_backend/__init__.py | 5 +- pyrecest/_backend/_backend_config.py | 2 + pyrecest/_backend/jax/__init__.py | 242 +++++++++++++++++++++++++++ pyrecest/_backend/jax/autodiff.py | 128 ++++++++++++++ pyrecest/_backend/jax/fft.py | 4 + pyrecest/_backend/jax/linalg.py | 28 ++++ pyrecest/_backend/jax/random.py | 116 +++++++++++++ 7 files changed, 523 insertions(+), 2 deletions(-) create mode 100644 pyrecest/_backend/jax/__init__.py create mode 100644 pyrecest/_backend/jax/autodiff.py create mode 100644 pyrecest/_backend/jax/fft.py create mode 100644 pyrecest/_backend/jax/linalg.py create mode 100644 pyrecest/_backend/jax/random.py diff --git a/pyrecest/_backend/__init__.py b/pyrecest/_backend/__init__.py index a640846d..89266049 100644 --- a/pyrecest/_backend/__init__.py +++ b/pyrecest/_backend/__init__.py @@ -13,8 +13,9 @@ def get_backend_name(): - return os.environ.get("PYRECEST_BACKEND", "numpy") + # return os.environ.get("PYRECEST_BACKEND", "numpy") #return os.environ.get("PYRECEST_BACKEND", "pytorch") + return os.environ.get("PYRECEST_BACKEND", "jax") BACKEND_NAME = get_backend_name() @@ -295,7 +296,7 @@ def _create_backend_module(self, backend_name): f"attribute '{attribute_name}'" ) - raise RuntimeError(error) from None + # raise RuntimeError(error) from None else: setattr(new_submodule, attribute_name, attribute) diff --git a/pyrecest/_backend/_backend_config.py b/pyrecest/_backend/_backend_config.py index e94659ae..57e7028f 100644 --- a/pyrecest/_backend/_backend_config.py +++ b/pyrecest/_backend/_backend_config.py @@ -4,6 +4,8 @@ np_atol = 1e-12 np_rtol = 1e-6 +jax_atol = 1e-6 +jax_rtol = 1e-5 DEFAULT_DTYPE = None DEFAULT_COMPLEX_DTYPE = None \ No newline at end of file diff --git a/pyrecest/_backend/jax/__init__.py b/pyrecest/_backend/jax/__init__.py new file mode 100644 index 00000000..45e26ad1 --- /dev/null +++ b/pyrecest/_backend/jax/__init__.py @@ -0,0 +1,242 @@ +"""Jax-based computation backend.""" +import jax.numpy as _jnp +from jax.numpy import ( + all, + allclose, + amax, + amin, + any, + argmax, + argmin, + broadcast_arrays, + broadcast_to, + clip, + complex64, + complex128, + concatenate, + conj, + cross, + cumprod, + cumsum, + diag_indices, + diagonal, + einsum, + empty_like, + equal, + expand_dims, + flip, + float32, + float64, + greater, + hsplit, + hstack, + int32, + int64, + isclose, + isnan, + kron, + less, + less_equal, + logical_and, + logical_or, + maximum, + mean, + meshgrid, + minimum, + moveaxis, + ones_like, + pad, + prod, + quantile, + repeat, + reshape, + searchsorted, + shape, + sort, + split, + stack, + std, + sum, + take, + tile, + transpose, + trapz, + tril, + tril_indices, + triu, + triu_indices, + uint8, + unique, + vstack, + where, + zeros_like, + diag, + diff, + apply_along_axis, + nonzero, + column_stack, + conj, + atleast_1d, + atleast_2d, + dstack, + full, + isreal, + triu, + kron, + angle, + arctan, + cov, + count_nonzero, + full_like, + isinf, + deg2rad, + argsort, + max, + min, + roll, + dstack, + abs, + arange, + abs, + angle, + arange, + arccos, + arccosh, + arcsin, + arctan2, + arctanh, + ceil, + copy, + cos, + cosh, + divide, + dot, + exp, + floor, + imag, + log, + matmul, + mod, + ndim, + outer, + power, + real, + sign, + sin, + sinh, + sqrt, + squeeze, + tan, + tanh, + trace, + vectorize, + empty, + eye, + zeros, + linspace, + ones, +) + +from jax import device_get as to_numpy + +from jax.scipy.special import erf, gamma, polygamma + +from jax.numpy import ravel as flatten +from jax.numpy import asarray as from_numpy + +from .._backend_config import jax_atol as atol +from .._backend_config import jax_rtol as rtol + + +from . import autodiff +from . import linalg +from . import random +from . import fft + +from jax.numpy import array + +unsupported_functions = [ + 'array_from_sparse', + 'assignment', + 'assignment_by_sum', + 'cast', + 'convert_to_wider_dtype', + 'get_default_dtype', + 'get_default_cdtype', + 'get_slice', + 'is_array', + 'is_complex', + 'ravel_tril_indices', + 'set_default_dtype', + 'to_ndarray', +] +for func_name in unsupported_functions: + exec(f"{func_name} = lambda *args, **kwargs: NotImplementedError('This function is not supported in this JAX backend.')") + + + + +def as_dtype(array, dtype): + """Change the data type of a given array. + + Parameters: + - array: The array whose data type needs to be changed + - dtype: The new data type + + Returns: + A new array with the specified data type. + """ + return _jnp.asarray(array, dtype=dtype) + + +# Check if dtype is floating-point +def is_floating(array): + return _jnp.issubdtype(array.dtype, _jnp.floating) + + +# Check if dtype is boolean +def is_bool(array): + return _jnp.issubdtype(array.dtype, _jnp.bool_) + + +# Matrix-vector multiplication +def matvec(matrix, vector): + return _jnp.dot(matrix, vector) + + +# One-hot encoding +def one_hot(indices, depth): + return _jnp.eye(depth)[indices] + + +# Scatter-add operation +def scatter_add(array, indices, updates): + return _jnp.zeros_like(array).at[indices].add(updates) + + +# Set diagonal elements of a matrix +def set_diag(matrix, values): + return matrix.at[_jnp.diag_indices_from(matrix)].set(values) + + +# Get lower triangle and flatten to vector +def tril_to_vec(matrix): + return _jnp.tril(matrix).ravel() + + +# Get upper triangle and flatten to vector +def triu_to_vec(matrix): + return _jnp.triu(matrix).ravel() + + +# Create diagonal matrix from vector +def vec_to_diag(vector): + return _jnp.diag(vector) + + +# Create matrix from diagonal, upper triangular, and lower triangular parts +def mat_from_diag_triu_tril(diag, triu, tril): + matrix = _jnp.diag(diag) + matrix = matrix.at[_jnp.triu_indices_from(matrix, k=1)].set(triu) + matrix = matrix.at[_jnp.tril_indices_from(matrix, k=-1)].set(tril) + return matrix \ No newline at end of file diff --git a/pyrecest/_backend/jax/autodiff.py b/pyrecest/_backend/jax/autodiff.py new file mode 100644 index 00000000..6652c62a --- /dev/null +++ b/pyrecest/_backend/jax/autodiff.py @@ -0,0 +1,128 @@ +""" +Wrapper around jax functions to be consistent with backends. +Based on autodiff.py by emilemathieu on +https://github.com/oxcsml/geomstats/blob/master/geomstats/_backend/jax/autodiff.py +""" + + +import jax.numpy as anp +from jax import vmap, grad +from jax import jacfwd +from jax import value_and_grad as _value_and_grad +from autograd.extend import defvjp, primitive # TODO: replace + + +def detach(x): + """Return a new tensor detached from the current graph. + + This is a placeholder in order to have consistent backend APIs. + + Parameters + ---------- + x : array-like + Tensor to detach. + """ + return x + + +def elementwise_grad(func): + """Wrap autograd elementwise_grad function. + + Parameters + ---------- + func : callable + Function for which the element-wise grad is computed. + """ + return vmap(grad(func))(func) # NOTE: cf https://github.com/google/jax/issues/564 + + +def custom_gradient(*grad_funcs): + """Decorate a function to define its custom gradient(s). + + Parameters + ---------- + *grad_funcs : callables + Custom gradient functions. + """ + + def decorator(func): + wrapped_function = primitive(func) + + def wrapped_grad_func(i, ans, *args, **kwargs): + grads = grad_funcs[i](*args, **kwargs) + if isinstance(grads, float): + return lambda g: g * grads + if grads.ndim == 2: + return lambda g: g[..., None] * grads + if grads.ndim == 3: + return lambda g: g[..., None, None] * grads + return lambda g: g * grads + + if len(grad_funcs) == 1: + defvjp( + wrapped_function, + lambda ans, *args, **kwargs: wrapped_grad_func(0, ans, *args, **kwargs), + ) + elif len(grad_funcs) == 2: + + defvjp( + wrapped_function, + lambda ans, *args, **kwargs: wrapped_grad_func(0, ans, *args, **kwargs), + lambda ans, *args, **kwargs: wrapped_grad_func(1, ans, *args, **kwargs), + ) + elif len(grad_funcs) == 3: + defvjp( + wrapped_function, + lambda ans, *args, **kwargs: wrapped_grad_func(0, ans, *args, **kwargs), + lambda ans, *args, **kwargs: wrapped_grad_func(1, ans, *args, **kwargs), + lambda ans, *args, **kwargs: wrapped_grad_func(2, ans, *args, **kwargs), + ) + else: + raise NotImplementedError( + "custom_gradient is not yet implemented " "for more than 3 gradients." + ) + + return wrapped_function + + return decorator + + +def jacobian(func): + """Wrap autograd jacobian function.""" + return jacfwd(func) + + +def value_and_grad(func, to_numpy=False): + """Wrap autograd value_and_grad function.""" + + def aux_value_and_grad(*args): + n_args = len(args) + value = func(*args) + + all_grads = [] + for i in range(n_args): + + def func_of_ith(*args): + reorg_args = args[1 : i + 1] + (args[0],) + args[i + 1 :] + return func(*reorg_args) + + new_args = (args[i],) + args[:i] + args[i + 1 :] + _, grad_i = _value_and_grad(func_of_ith)(*new_args) + all_grads.append(grad_i) + + if n_args == 1: + return value, all_grads[0] + return value, tuple(all_grads) + + return aux_value_and_grad + +unsupported_functions = [ + 'hessian', + 'hessian_vec', + 'jacobian_vec', + 'jacobian_and_hessian', + 'value_jacobian_and_hessian', +] +for func_name in unsupported_functions: + exec(f"{func_name} = lambda *args, **kwargs: NotImplementedError('This function is not supported in this JAX backend.')") + diff --git a/pyrecest/_backend/jax/fft.py b/pyrecest/_backend/jax/fft.py new file mode 100644 index 00000000..cbd95263 --- /dev/null +++ b/pyrecest/_backend/jax/fft.py @@ -0,0 +1,4 @@ +from jax.numpy.fft import ( + rfft, + irfft, +) \ No newline at end of file diff --git a/pyrecest/_backend/jax/linalg.py b/pyrecest/_backend/jax/linalg.py new file mode 100644 index 00000000..bb494c61 --- /dev/null +++ b/pyrecest/_backend/jax/linalg.py @@ -0,0 +1,28 @@ +"""JAX-based linear algebra backend.""" + +from jax.numpy.linalg import ( # NOQA + cholesky, + det, + eig, + eigh, + eigvalsh, + inv, + matrix_rank, + norm, + solve, + svd, + qr, +) + +unsupported_functions = [ + 'expm', + 'fractional_matrix_power', + 'is_single_matrix_pd', + 'logm', + 'quadratic_assignment', + 'solve_sylvester', + 'sqrtm', +] +for func_name in unsupported_functions: + exec(f"{func_name} = lambda *args, **kwargs: NotImplementedError('This function is not supported in this JAX backend.')") + diff --git a/pyrecest/_backend/jax/random.py b/pyrecest/_backend/jax/random.py new file mode 100644 index 00000000..4acee7bb --- /dev/null +++ b/pyrecest/_backend/jax/random.py @@ -0,0 +1,116 @@ +""" +Jax-based random backend. +Based on random.py by emilemathieu on +https://github.com/oxcsml/geomstats/blob/master/geomstats/_backend/jax/random.py +who says he was in inspired by https://github.com/wesselb/lab/blob/master/lab/jax/random.py +""" + +from numpy.random import ( # NOQA + seed, +) + +import jax +import sys + +backend = sys.modules[__name__] + + +def create_random_state(seed = 0): + return jax.random.PRNGKey(seed=seed) + + +backend.jax_global_random_state = jax.random.PRNGKey(seed=0) + + +def global_random_state(): + return backend.jax_global_random_state + + +def set_global_random_state(state): + backend.jax_global_random_state = state + + +def get_state(**kwargs): + has_state = 'state' in kwargs + state = kwargs.pop('state', backend.jax_global_random_state) + return state, has_state, kwargs + + +def set_state_return(has_state, state, res): + if has_state: + return state, res + else: + backend.jax_global_random_state = state + return res + + +def _rand(state, size, *args, **kwargs): + state, key = jax.random.split(state) + return state, jax.random.uniform(key, size, *args, **kwargs) + + +def rand(size, *args, **kwargs): + size = size if hasattr(size, "__iter__") else (size,) + state, has_state, kwargs = get_state(**kwargs) + state, res = _rand(state, size, *args, **kwargs) + return set_state_return(has_state, state, res) + + +uniform = rand + + +def _randint(state, size, *args, **kwargs): + state, key = jax.random.split(state) + return state, jax.random.uniform(key, size, *args, **kwargs) + + +def randint(size, *args, **kwargs): + size = size if hasattr(size, "__iter__") else (size,) + state, has_state, kwargs = get_state(**kwargs) + state, res = _randint(state, size, *args, **kwargs) + return set_state_return(has_state, state, res) + + +def _normal(state, size, *args, **kwargs): + state, key = jax.random.split(state) + return state, jax.random.normal(key, size, *args, **kwargs) + + +def normal(size, *args, **kwargs): + size = size if hasattr(size, "__iter__") else (size,) + state, has_state, kwargs = get_state(**kwargs) + state, res = _normal(state, size, *args, **kwargs) + return set_state_return(has_state, state, res) + + +def _choice(state, a, n, *args, **kwargs): + state, key = jax.random.split(state) + inds = jax.random.choice(key, a.shape[0], (n,), replace=True, *args, **kwargs) + choices = a[inds] + return state, choices[0] if n == 1 else choices + + +def choice(a, n, *args, **kwargs): + state, has_state, kwargs = get_state(**kwargs) + state, res = _choice(state, a, n, *args, **kwargs) + return set_state_return(has_state, state, res) + + +def _multivariate_normal(state, size, *args, **kwargs): + state, key = jax.random.split(state) + return state, jax.random.multivariate_normal(key, *args, **kwargs).sample(size) + + +def multivariate_normal(size, *args, **kwargs): + size = size if hasattr(size, "__iter__") else (size,) + state, has_state, kwargs = get_state(**kwargs) + state, res = _multivariate_normal(state, size, *args, **kwargs) + return set_state_return(has_state, state, res) + + +unsupported_functions = [ + 'multinomial', +] +for func_name in unsupported_functions: + exec(f"{func_name} = lambda *args, **kwargs: NotImplementedError('This function is not supported in this JAX backend.')") + From c219a800a665f31cd4dfff21f1b10a92b91d8f29 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 15:01:27 +0100 Subject: [PATCH 185/232] Tests for jax backend --- .github/workflows/tests.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 72c93b48..0c51f2ce 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -55,6 +55,15 @@ jobs: poetry env use python export PYRECEST_BACKEND=pytorch poetry run python -m pytest --rootdir . -v --strict-config --junitxml=junit_test_results_pytorch.xml ./pyrecest + env: + PYTHONPATH: ${{ github.workspace }} + + - name: Run tests with pytorch backend + if: always() + run: | + poetry env use python + export PYRECEST_BACKEND=jax + poetry run python -m pytest --rootdir . -v --strict-config --junitxml=junit_test_results_jax.xml ./pyrecest env: PYTHONPATH: ${{ github.workspace }} @@ -65,3 +74,4 @@ jobs: files: | junit_test_results_numpy.xml junit_test_results_pytorch.xml + junit_test_results_jax.xml From ca578bcd04e8c3b80014c725c261dddfe528e9ff Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 15:04:29 +0100 Subject: [PATCH 186/232] More --- .../distributions/test_abstract_hypertoroidal_distribution.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pyrecest/tests/distributions/test_abstract_hypertoroidal_distribution.py b/pyrecest/tests/distributions/test_abstract_hypertoroidal_distribution.py index 981e720b..a2a62af8 100644 --- a/pyrecest/tests/distributions/test_abstract_hypertoroidal_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hypertoroidal_distribution.py @@ -21,4 +21,5 @@ def test_angular_error(self): array(pi / 4), array(7 * pi / 4) ), pi / 2, + rtol=2e-07 ) From b85e7eacd7e5dc853cf23e06cffd861de9bc5657 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 15:26:02 +0100 Subject: [PATCH 187/232] Also install jax --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index be9d86b7..cb1cea26 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,6 +20,7 @@ shapely = "*" [tool.poetry.extras] healpy_support = ["healpy"] pytorch_support = ["torch"] +jax_support = ["jax"] [tool.poetry.group.dev.dependencies] healpy = "*" From c62d401fc4e3a2a09e6577813510464a12ef8f18 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 15:26:27 +0100 Subject: [PATCH 188/232] More --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 0c51f2ce..c9014f4a 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -31,7 +31,7 @@ jobs: python -m pip install --upgrade pip python -m pip install poetry poetry env use python - poetry install --extras "healpy_support" --extras "pytorch_support" + poetry install --extras "healpy_support" --extras "pytorch_support" --extras "jax_support" poetry run python -m pip install torch==2.1.0+cpu torchaudio==2.1.0+cpu -f https://download.pytorch.org/whl/torch_stable.html - name: List files and check Python and package versions From f6b66de9e9a01a03efadf7f98be057e1ea8ccd0d Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 15:26:46 +0100 Subject: [PATCH 189/232] More --- .../hyperhemispherical_uniform_distribution.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrecest/distributions/hypersphere_subset/hyperhemispherical_uniform_distribution.py b/pyrecest/distributions/hypersphere_subset/hyperhemispherical_uniform_distribution.py index 3961bf6b..44d74d4e 100644 --- a/pyrecest/distributions/hypersphere_subset/hyperhemispherical_uniform_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/hyperhemispherical_uniform_distribution.py @@ -47,5 +47,5 @@ def get_manifold_size(self) -> float: AbstractHypersphereSubsetDistribution.compute_unit_hypersphere_surface( self.dim ) - / 2 + / 2.0 ) From b156c032c0e08f901db6871de4d7d934d2861136 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 15:59:54 +0100 Subject: [PATCH 190/232] More --- .../test_toroidal_uniform_distribution.py | 2 +- pyrecest/tests/test_metrics.py | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pyrecest/tests/distributions/test_toroidal_uniform_distribution.py b/pyrecest/tests/distributions/test_toroidal_uniform_distribution.py index c354da79..253e0648 100644 --- a/pyrecest/tests/distributions/test_toroidal_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_toroidal_uniform_distribution.py @@ -19,7 +19,7 @@ def setUp(self): def test_pdf(self): self.assertTrue( - allclose(self.tud.pdf(self.x), (1 / (2 * pi) ** 2) * ones(self.x.shape[1])) + allclose(self.tud.pdf(self.x), (1 / (2 * pi) ** 2) * ones(self.x.shape[0])) ) def test_shift(self): diff --git a/pyrecest/tests/test_metrics.py b/pyrecest/tests/test_metrics.py index a05d9925..d350d69d 100644 --- a/pyrecest/tests/test_metrics.py +++ b/pyrecest/tests/test_metrics.py @@ -3,7 +3,7 @@ import numpy.testing as npt # pylint: disable=no-name-in-module,no-member -from pyrecest.backend import array, random, repeat +from pyrecest.backend import array, random, repeat, stack from pyrecest.utils.metrics import anees @@ -11,7 +11,7 @@ class TestANEES(unittest.TestCase): def setUp(self): self.groundtruths = array([[1.5, 2.5], [2.5, 3.5], [4.5, 5.5]]) self.uncertainties = array( - [[[1, 0.5], [0.5, 2]], [[1, 0], [0, 1]], [[0.5, 0], [0, 1.5]]] + [[[1.0, 0.5], [0.5, 2.0]], [[1.0, 0.0], [0.0, 1.0]], [[0.5, 0.0], [0.0, 1.5]]] ) self.num_samples = 10000 @@ -24,13 +24,13 @@ def test_ANEES_is_close_to_one(self): cov=self.uncertainties[i], size=self.num_samples, ) - samples.extend(samples_for_i) + samples.append(samples_for_i) - samples = array(samples) + samples_mat = stack(samples, axis=-1) repeated_groundtruths = repeat(self.groundtruths, self.num_samples, axis=0) repeated_uncertainties = repeat(self.uncertainties, self.num_samples, axis=0) - computed_ANEES = anees(samples, repeated_uncertainties, repeated_groundtruths) + computed_ANEES = anees(samples_mat, repeated_uncertainties, repeated_groundtruths) # Assert that computed ANEES is close to 1 with a tolerance of 0.05. npt.assert_almost_equal(computed_ANEES, self.groundtruths.shape[-1], decimal=2) From 0e27503a9a919a05aaf30f2720409a540e51b424 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 16:05:53 +0100 Subject: [PATCH 191/232] More --- .../hypertorus/toroidal_uniform_distribution.py | 5 ++++- .../distributions/test_toroidal_uniform_distribution.py | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/pyrecest/distributions/hypertorus/toroidal_uniform_distribution.py b/pyrecest/distributions/hypertorus/toroidal_uniform_distribution.py index b2eedda5..a28c7045 100644 --- a/pyrecest/distributions/hypertorus/toroidal_uniform_distribution.py +++ b/pyrecest/distributions/hypertorus/toroidal_uniform_distribution.py @@ -1,9 +1,12 @@ from .abstract_toroidal_distribution import AbstractToroidalDistribution from .hypertoroidal_uniform_distribution import HypertoroidalUniformDistribution - +import copy class ToroidalUniformDistribution( HypertoroidalUniformDistribution, AbstractToroidalDistribution ): def get_manifold_size(self): return AbstractToroidalDistribution.get_manifold_size(self) + + def shift(self, _): + return copy.deepcopy(self) \ No newline at end of file diff --git a/pyrecest/tests/distributions/test_toroidal_uniform_distribution.py b/pyrecest/tests/distributions/test_toroidal_uniform_distribution.py index 253e0648..a64b0808 100644 --- a/pyrecest/tests/distributions/test_toroidal_uniform_distribution.py +++ b/pyrecest/tests/distributions/test_toroidal_uniform_distribution.py @@ -15,7 +15,7 @@ class TestToroidalUniformDistribution(unittest.TestCase): def setUp(self): self.tud = ToroidalUniformDistribution() - self.x = tile(array([[1.0, 2.0, 3.0, 4.0, 5.0, 6.0]]), (2, 1)) + self.x = tile(array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]), (2, 1)).T def test_pdf(self): self.assertTrue( @@ -27,7 +27,7 @@ def test_shift(self): self.assertTrue( allclose( tud_shifted.pdf(self.x), - (1 / (2 * pi) ** 2) * ones(self.x.shape[1]), + (1 / (2 * pi) ** 2) * ones(self.x.shape[0]), ) ) From ecb38710796ee20ea2a954805848c916898bbcca Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 16:07:54 +0100 Subject: [PATCH 192/232] Commeted out jax tests --- .github/workflows/tests.yml | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index c9014f4a..9ffac245 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -58,14 +58,14 @@ jobs: env: PYTHONPATH: ${{ github.workspace }} - - name: Run tests with pytorch backend - if: always() - run: | - poetry env use python - export PYRECEST_BACKEND=jax - poetry run python -m pytest --rootdir . -v --strict-config --junitxml=junit_test_results_jax.xml ./pyrecest - env: - PYTHONPATH: ${{ github.workspace }} + #- name: Run tests with jax backend + # if: always() + # run: | + # poetry env use python + # export PYRECEST_BACKEND=jax + # poetry run python -m pytest --rootdir . -v --strict-config --junitxml=junit_test_results_jax.xml ./pyrecest + # env: + # PYTHONPATH: ${{ github.workspace }} - name: Publish test results if: always() @@ -74,4 +74,3 @@ jobs: files: | junit_test_results_numpy.xml junit_test_results_pytorch.xml - junit_test_results_jax.xml From cd63d974b0f30536e76625738967f21344db1019 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 16:32:00 +0100 Subject: [PATCH 193/232] More --- .../abstract_hypercylindrical_distribution.py | 33 +++++++++++++++---- .../abstract_linear_distribution.py | 2 +- .../nonperiodic/custom_linear_distribution.py | 2 +- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py b/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py index 8a2257e8..d5b7bf57 100644 --- a/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py +++ b/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py @@ -178,10 +178,21 @@ def condition_on_linear(self, input_lin, normalize=True): and input_lin.shape[0] == self.lin_dim ), "Input should be of size (lin_dim,)." - def f_cond_unnorm(x, input_lin=input_lin): - n_inputs = x.shape[0] if x.ndim > 1 else 1 + def f_cond_unnorm(xs, input_lin=input_lin): + + if xs.ndim == 0: + assert self.bound_dim == 1 + n_inputs = 1 + elif xs.ndim == 1 and self.bound_dim == 1: + n_inputs = xs.shape[0] + elif xs.ndim == 1: + assert self.bound_dim == xs.shape[0] + n_inputs = 1 + else: + n_inputs = xs.shape[0] + input_repeated = tile(input_lin, (n_inputs, 1)) - return self.pdf(column_stack((x, input_repeated))) + return self.pdf(column_stack((xs, input_repeated))) dist = CustomHypertoroidalDistribution(f_cond_unnorm, self.bound_dim) @@ -212,10 +223,20 @@ def condition_on_periodic(self, input_periodic, normalize=True): input_periodic = mod(input_periodic, 2.0 * pi) - def f_cond_unnorm(x, input_periodic=input_periodic): - n_inputs = x.shape[0] if x.ndim > 1 else 1 + def f_cond_unnorm(xs, input_periodic=input_periodic): + if xs.ndim == 0: + assert self.lin_dim == 1 + n_inputs = 1 + elif xs.ndim == 1 and self.lin_dim == 1: + n_inputs = xs.shape[0] + elif xs.ndim == 1: + assert self.lin_dim == xs.shape[0] + n_inputs = 1 + else: + n_inputs = xs.shape[0] + input_repeated = tile(input_periodic, (n_inputs, 1)) - return self.pdf(column_stack((input_repeated, x))) + return self.pdf(column_stack((input_repeated, xs))) dist = CustomLinearDistribution(f_cond_unnorm, self.lin_dim) diff --git a/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py b/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py index e422bfdb..ea0bf027 100644 --- a/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py +++ b/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py @@ -225,7 +225,7 @@ def f_for_nquad(*args): return squeeze(f(array(args).reshape(-1, dim))) if dim == 1: - result, _ = quad(f, left, right) + result, _ = quad(f_for_nquad, left, right) elif dim == 2: result, _ = nquad(f_for_nquad, [(left[0], right[0]), (left[1], right[1])]) elif dim == 3: diff --git a/pyrecest/distributions/nonperiodic/custom_linear_distribution.py b/pyrecest/distributions/nonperiodic/custom_linear_distribution.py index 079695f0..fdd3c0c0 100644 --- a/pyrecest/distributions/nonperiodic/custom_linear_distribution.py +++ b/pyrecest/distributions/nonperiodic/custom_linear_distribution.py @@ -45,7 +45,7 @@ def set_mean(self, new_mean): self.shift_by *= mean_offset def pdf(self, xs): - assert xs.shape[-1] == self.dim + assert self.dim == 1 and xs.ndim <= 1 or xs.shape[-1] == self.dim p = self.scale_by * self.f( # To ensure 2-d for broadcasting reshape(xs, (-1, self.dim)) From 7aead3136833b30045385f8eb4cc46dedf6045e4 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 16:32:17 +0100 Subject: [PATCH 194/232] Default numpy --- pyrecest/_backend/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyrecest/_backend/__init__.py b/pyrecest/_backend/__init__.py index 89266049..6b8d0935 100644 --- a/pyrecest/_backend/__init__.py +++ b/pyrecest/_backend/__init__.py @@ -13,9 +13,9 @@ def get_backend_name(): - # return os.environ.get("PYRECEST_BACKEND", "numpy") + return os.environ.get("PYRECEST_BACKEND", "numpy") #return os.environ.get("PYRECEST_BACKEND", "pytorch") - return os.environ.get("PYRECEST_BACKEND", "jax") + #return os.environ.get("PYRECEST_BACKEND", "jax") BACKEND_NAME = get_backend_name() From 2beb96a1a2fc36662220725f19e93930d02992e9 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 16:40:58 +0100 Subject: [PATCH 195/232] More.... --- .../nonperiodic/abstract_linear_distribution.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py b/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py index ea0bf027..b91e4c96 100644 --- a/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py +++ b/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py @@ -82,7 +82,7 @@ def sample_metropolis_hastings( if proposal is None: def proposal(x): - return x + random.randn(self.dim) + return x + random.normal(0.0, 1.0, (self.dim)) if start_point is None: start_point = ( @@ -100,12 +100,12 @@ def proposal(x): ) def mean_numerical(self): - mu = empty(self.dim) if self.dim == 1: - mu = quad( - lambda x: x * self.pdf(x), array(-float("inf")), array(float("inf")) - )[0] + mu = array(quad( + lambda x: x * self.pdf(array(x)), array(-float("inf")), array(float("inf")) + )[0]) elif self.dim == 2: + mu = empty(self.dim) mu[0] = dblquad( lambda x, y: x * self.pdf(array([x, y])), -float("inf"), @@ -121,7 +121,8 @@ def mean_numerical(self): lambda _: float("inf"), )[0] elif self.dim == 3: - + mu = empty(self.dim) + def integrand1(x, y, z): return x * self.pdf(array([x, y, z])) From a729774846226872470b6a5c3953de91ae4b948d Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 16:45:26 +0100 Subject: [PATCH 196/232] More... --- .../hypertorus/hypertoroidal_dirac_distribution.py | 4 +++- pyrecest/filters/abstract_particle_filter.py | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py b/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py index fb603dc4..df366e1c 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py @@ -41,7 +41,9 @@ def plot(self, *args, **kwargs): raise NotImplementedError("Plotting is not implemented") def set_mean(self, mean): - self.d = mod(self.d - self.mean_direction() + mean, 2.0 * pi) + dist = copy.deepcopy(self) + dist.d = mod(dist.d - dist.mean_direction() + mean, 2.0 * pi) + return dist def mean_direction(self): """ diff --git a/pyrecest/filters/abstract_particle_filter.py b/pyrecest/filters/abstract_particle_filter.py index 4ea9ce54..02a62210 100644 --- a/pyrecest/filters/abstract_particle_filter.py +++ b/pyrecest/filters/abstract_particle_filter.py @@ -40,8 +40,8 @@ def predict_nonlinear( self.filter_state.d = self.filter_state.d + noise else: for i in range(n_particles): - noise_curr = noise_distribution.set_mean(self.filter_state.d[i, :]) - self.filter_state.d[i, :] = noise_curr.sample(1) + noise_curr = noise_distribution.set_mean(self.filter_state.d[i]) + self.filter_state.d[i] = noise_curr.sample(1) def predict_nonlinear_nonadditive(self, f, samples, weights): assert ( From 55935b4b3450bc82358812c445f24648b8437f9f Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 17:26:42 +0100 Subject: [PATCH 197/232] More...... --- .../test_custom_hypercylindrical_distribution.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py b/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py index 05328c04..08b3efb3 100644 --- a/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py +++ b/pyrecest/tests/distributions/test_custom_hypercylindrical_distribution.py @@ -69,8 +69,8 @@ def test_condition_on_periodic(self): dist = self.chcd_vm_gauss_stacked.condition_on_periodic(array(1.0)) grid = meshgrid(arange(-3, 4), arange(-3, 4)) - self.grid_flat = array(grid).reshape(2, -1).T - npt.assert_allclose(dist.pdf(grid), self.gauss.pdf(grid)) + grid_flat = array(grid).reshape(2, -1).T + npt.assert_allclose(dist.pdf(grid_flat), self.gauss.pdf(grid_flat)) if __name__ == "__main__": From fd0ad7ce8c9f5b46788864d250ae927084e27185 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 17:29:47 +0100 Subject: [PATCH 198/232] More --- pyrecest/distributions/nonperiodic/linear_dirac_distribution.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrecest/distributions/nonperiodic/linear_dirac_distribution.py b/pyrecest/distributions/nonperiodic/linear_dirac_distribution.py index af551645..89e1320c 100644 --- a/pyrecest/distributions/nonperiodic/linear_dirac_distribution.py +++ b/pyrecest/distributions/nonperiodic/linear_dirac_distribution.py @@ -51,7 +51,7 @@ def weighted_samples_to_mean_and_cov(samples, weights=None): if weights is None: weights = ones(samples.shape[1]) / samples.shape[1] - mean = (samples * weights.reshape(-1, 1)).sum(dim=0) + mean = weights@samples deviation = samples - mean covariance = cov(deviation.T, aweights=weights, bias=True) From a7e6c902907f25bdd6cac76103334aee314149d0 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 17:30:06 +0100 Subject: [PATCH 199/232] More... --- pyrecest/_backend/jax/random.py | 2 +- .../hyperspherical_uniform_distribution.py | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/pyrecest/_backend/jax/random.py b/pyrecest/_backend/jax/random.py index 4acee7bb..21c35a06 100644 --- a/pyrecest/_backend/jax/random.py +++ b/pyrecest/_backend/jax/random.py @@ -98,7 +98,7 @@ def choice(a, n, *args, **kwargs): def _multivariate_normal(state, size, *args, **kwargs): state, key = jax.random.split(state) - return state, jax.random.multivariate_normal(key, *args, **kwargs).sample(size) + return state, jax.random.multivariate_normal(key, *args, **kwargs) def multivariate_normal(size, *args, **kwargs): diff --git a/pyrecest/distributions/hypersphere_subset/hyperspherical_uniform_distribution.py b/pyrecest/distributions/hypersphere_subset/hyperspherical_uniform_distribution.py index 49060aac..222040be 100644 --- a/pyrecest/distributions/hypersphere_subset/hyperspherical_uniform_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/hyperspherical_uniform_distribution.py @@ -2,7 +2,7 @@ from typing import Union # pylint: disable=no-name-in-module,no-member -from pyrecest.backend import cos, empty, int32, int64, linalg, random, sin, sqrt +from pyrecest.backend import cos, empty, int32, int64, linalg, random, sin, sqrt, stack from .abstract_hypersphere_subset_uniform_distribution import ( AbstractHypersphereSubsetUniformDistribution, @@ -29,11 +29,10 @@ def sample(self, n: Union[int, int32, int64]): self.dim + 1, ) ) - phi = 2 * pi * random.rand(n) - s[:, 2] = random.rand(n) * 2.0 - 1.0 - r = sqrt(1 - s[:, 2] ** 2) - s[:, 0] = r * cos(phi) - s[:, 1] = r * sin(phi) + phi = 2.0 * pi * random.rand(n) + sz = random.rand(n) * 2.0 - 1.0 + r = sqrt(1 - sz ** 2) + s = stack([r * cos(phi), r * sin(phi), sz], axis=1) else: samples_unnorm = random.normal(0.0, 1.0, (n, self.dim + 1)) s = samples_unnorm / linalg.norm(samples_unnorm, axis=1).reshape(-1, 1) From 7ac4c36805a118c2c06a344ee225523c0a8fed45 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 17:32:11 +0100 Subject: [PATCH 200/232] More. --- .../distributions/test_hyperspherical_dirac_distribution.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py b/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py index c2fa36d0..8ad8eb7c 100644 --- a/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_hyperspherical_dirac_distribution.py @@ -73,7 +73,7 @@ def f(x): ) def test_from_distribution(self): random.seed(0) - vmf = VonMisesFisherDistribution(array([1.0, 1.0, 1.0]) / sqrt(3), array(1.0)) + vmf = VonMisesFisherDistribution(array([1.0, 1.0, 1.0]) / sqrt(3), 1.0) dirac_dist = HypersphericalDiracDistribution.from_distribution(vmf, 100000) npt.assert_almost_equal( dirac_dist.mean_direction(), vmf.mean_direction(), decimal=2 From 6f0caca9b4aa7cdf2ff6d9b94f7f72f08692784d Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 17:34:33 +0100 Subject: [PATCH 201/232] More --- pyrecest/tests/distributions/test_linear_dirac_distribution.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrecest/tests/distributions/test_linear_dirac_distribution.py b/pyrecest/tests/distributions/test_linear_dirac_distribution.py index 5b06c89f..9c6705bd 100644 --- a/pyrecest/tests/distributions/test_linear_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_linear_dirac_distribution.py @@ -17,7 +17,7 @@ def test_from_distribution(self): C = wishart.rvs(3, eye(3)) hwn = GaussianDistribution(array([1.0, 2.0, 3.0]), array(C)) hwd = LinearDiracDistribution.from_distribution(hwn, 200000) - npt.assert_allclose(hwd.mean(), hwn.mean(), atol=0.005) + npt.assert_allclose(hwd.mean(), hwn.mean(), atol=0.008) npt.assert_allclose(hwd.covariance(), hwn.covariance(), rtol=0.1) def test_mean_and_cov(self): From 263d3195402b5bb311b9e9cf1823530d861f90c2 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 18:02:48 +0100 Subject: [PATCH 202/232] More... --- pyrecest/tests/test_metrics.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/pyrecest/tests/test_metrics.py b/pyrecest/tests/test_metrics.py index d350d69d..bd40a5a6 100644 --- a/pyrecest/tests/test_metrics.py +++ b/pyrecest/tests/test_metrics.py @@ -3,7 +3,7 @@ import numpy.testing as npt # pylint: disable=no-name-in-module,no-member -from pyrecest.backend import array, random, repeat, stack +from pyrecest.backend import array, random, repeat, vstack, expand_dims from pyrecest.utils.metrics import anees @@ -13,22 +13,27 @@ def setUp(self): self.uncertainties = array( [[[1.0, 0.5], [0.5, 2.0]], [[1.0, 0.0], [0.0, 1.0]], [[0.5, 0.0], [0.0, 1.5]]] ) - self.num_samples = 10000 + self.n_timesteps_constant = 10000 def test_ANEES_is_close_to_one(self): + """ Test that the ANEES is close to 1 when we sample from the groundtruths with the given uncertainties. + Simulate that the state stays constant for 10000 time steps, then changes, stays constant for another 10000 time steps + and then changes once more before staying constant for the remaining 10000 time steps. + """ samples = [] for i in range(len(self.groundtruths)): samples_for_i = random.multivariate_normal( mean=self.groundtruths[i], cov=self.uncertainties[i], - size=self.num_samples, + size=self.n_timesteps_constant, ) samples.append(samples_for_i) - samples_mat = stack(samples, axis=-1) - repeated_groundtruths = repeat(self.groundtruths, self.num_samples, axis=0) - repeated_uncertainties = repeat(self.uncertainties, self.num_samples, axis=0) + samples_mat = vstack(samples) + + repeated_groundtruths = repeat(self.groundtruths, repeats=self.n_timesteps_constant, axis=0) + repeated_uncertainties = repeat(self.uncertainties, repeats=self.n_timesteps_constant, axis=0) computed_ANEES = anees(samples_mat, repeated_uncertainties, repeated_groundtruths) From 2d455a9cc07ec90de0d17516ea3223c1930b04c3 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 18:04:52 +0100 Subject: [PATCH 203/232] Default to pytorch --- pyrecest/_backend/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyrecest/_backend/__init__.py b/pyrecest/_backend/__init__.py index 6b8d0935..2e6bfef3 100644 --- a/pyrecest/_backend/__init__.py +++ b/pyrecest/_backend/__init__.py @@ -13,8 +13,8 @@ def get_backend_name(): - return os.environ.get("PYRECEST_BACKEND", "numpy") - #return os.environ.get("PYRECEST_BACKEND", "pytorch") + #return os.environ.get("PYRECEST_BACKEND", "numpy") + return os.environ.get("PYRECEST_BACKEND", "pytorch") #return os.environ.get("PYRECEST_BACKEND", "jax") From 266bcd101d64c98234d10f820d60438db6f00d0b Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 18:21:48 +0100 Subject: [PATCH 204/232] More --- .../distributions/nonperiodic/gaussian_distribution.py | 8 +++++++- .../tests/distributions/test_gaussian_distribution.py | 4 ++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/pyrecest/distributions/nonperiodic/gaussian_distribution.py b/pyrecest/distributions/nonperiodic/gaussian_distribution.py index f348ad83..68e0ac09 100644 --- a/pyrecest/distributions/nonperiodic/gaussian_distribution.py +++ b/pyrecest/distributions/nonperiodic/gaussian_distribution.py @@ -46,12 +46,18 @@ def pdf(self, xs): pdfvals = mvn.pdf(xs, self.mu, self.C) elif pyrecest.backend.__name__ == "pyrecest.pytorch": + # Disable import errors for megalinter + import torch # pylint: disable=import-error # pylint: disable=import-error from torch.distributions import MultivariateNormal distribution = MultivariateNormal(self.mu, self.C) + if xs.ndim == 1 and self.dim == 1: + # For 1-D distributions, we need to reshape the input to a 2-D tensor + # to be able to use distribution.log_prob + xs = torch.reshape(xs, (-1, 1)) log_probs = distribution.log_prob(xs) - pdfvals = pyrecest.backend.exp(log_probs) + pdfvals = torch.exp(log_probs) return pdfvals diff --git a/pyrecest/tests/distributions/test_gaussian_distribution.py b/pyrecest/tests/distributions/test_gaussian_distribution.py index 683336ae..34cbcd15 100644 --- a/pyrecest/tests/distributions/test_gaussian_distribution.py +++ b/pyrecest/tests/distributions/test_gaussian_distribution.py @@ -60,7 +60,7 @@ def test_marginalization(self): grid = linspace(-10, 10, 30) dist_marginalized = g.marginalize_out(1) - def marginlized_1D_via_integrate(xs): + def marginalized_1D_via_integrate(xs): def integrand(y, x): return g.pdf(array([x, y])) @@ -75,7 +75,7 @@ def integrand(y, x): self.assertTrue( allclose( dist_marginalized.pdf(grid), - marginlized_1D_via_integrate(grid), + marginalized_1D_via_integrate(grid), atol=1e-9, ) ) From 6af2a10cc1e0281aa99ecd59f1dff857c643d3d9 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 19:29:03 +0200 Subject: [PATCH 205/232] More... --- .../abstract_custom_lin_bounded_cart_prod_distribution.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/pyrecest/distributions/cart_prod/abstract_custom_lin_bounded_cart_prod_distribution.py b/pyrecest/distributions/cart_prod/abstract_custom_lin_bounded_cart_prod_distribution.py index d51a8bff..6eeeab5e 100644 --- a/pyrecest/distributions/cart_prod/abstract_custom_lin_bounded_cart_prod_distribution.py +++ b/pyrecest/distributions/cart_prod/abstract_custom_lin_bounded_cart_prod_distribution.py @@ -28,10 +28,3 @@ def __init__(self, f_: Callable, bound_dim: int, lin_dim: int): AbstractCustomDistribution.__init__(self, f_) AbstractLinPeriodicCartProdDistribution.__init__(self, bound_dim, lin_dim) - - @staticmethod - def from_distribution(distribution: AbstractLinPeriodicCartProdDistribution): - chhd = AbstractCustomLinBoundedCartProdDistribution( - distribution.pdf, distribution.bound_dim, distribution.lin_dim - ) - return chhd From 95e960d148580f0c00143e8c4432ea0b2820d7e4 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 18:38:47 +0100 Subject: [PATCH 206/232] Minor fix --- .../filters/hypertoroidal_particle_filter.py | 23 ++++--------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/pyrecest/filters/hypertoroidal_particle_filter.py b/pyrecest/filters/hypertoroidal_particle_filter.py index ac262449..d5012af7 100644 --- a/pyrecest/filters/hypertoroidal_particle_filter.py +++ b/pyrecest/filters/hypertoroidal_particle_filter.py @@ -20,9 +20,6 @@ AbstractHypertoroidalDistribution, HypertoroidalDiracDistribution, ) -from pyrecest.distributions.circle.circular_dirac_distribution import ( - CircularDiracDistribution, -) from .abstract_hypertoroidal_filter import AbstractHypertoroidalFilter from .abstract_particle_filter import AbstractParticleFilter @@ -35,29 +32,17 @@ def __init__( dim: Union[int, int32, int64], ): if dim == 1: - # Prevents ambiguities if a vector is of size (dim,) or (n,) (for dim=1) - filter_state = CircularDiracDistribution( - linspace(0.0, 2.0 * pi, num=n_particles, endpoint=False) - ) + points = linspace(0.0, 2.0 * pi, num=n_particles, endpoint=False) else: - filter_state = HypertoroidalDiracDistribution( + points = ( tile( arange(0.0, 2.0 * pi, 2.0 * pi / n_particles), (dim, 1) - ).T.squeeze(), - dim=dim, + ).T.squeeze() ) + filter_state = HypertoroidalDiracDistribution(points, dim=1) AbstractHypertoroidalFilter.__init__(self, filter_state) AbstractParticleFilter.__init__(self, filter_state) - def set_state(self, new_state: AbstractHypertoroidalDistribution): - if not isinstance(new_state, HypertoroidalDiracDistribution): - # Convert to DiracDistribution if it is a different type of distribution - # Use .__class__ to convert it to CircularDiracDistribution - new_state = self.filter_state.__class__( - new_state.sample(self.filter_state.w.shape[0]) - ) - self.filter_state = copy.deepcopy(new_state) - def predict_nonlinear( self, f: Callable, From 019ed9703ebfa5321d53f8c554349737d2a53b6c Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 18:48:08 +0100 Subject: [PATCH 207/232] More --- pyrecest/sampling/hyperspherical_sampler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrecest/sampling/hyperspherical_sampler.py b/pyrecest/sampling/hyperspherical_sampler.py index 887fcfbe..740d6457 100644 --- a/pyrecest/sampling/hyperspherical_sampler.py +++ b/pyrecest/sampling/hyperspherical_sampler.py @@ -72,7 +72,7 @@ class AbstractSphericalCoordinatesBasedSampler(AbstractSphericalUniformSampler): @abstractmethod def get_grid_spherical_coordinates( self, - grid_density_parameter: int | list[int], + grid_density_parameter: int, ): raise NotImplementedError() From b7279423a878ccedf6f46d1d1499e41f533f4f35 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 18:54:36 +0100 Subject: [PATCH 208/232] More... --- pyrecest/sampling/hyperspherical_sampler.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/pyrecest/sampling/hyperspherical_sampler.py b/pyrecest/sampling/hyperspherical_sampler.py index 740d6457..1572c2c6 100644 --- a/pyrecest/sampling/hyperspherical_sampler.py +++ b/pyrecest/sampling/hyperspherical_sampler.py @@ -56,7 +56,7 @@ def sample_stochastic(self, n_samples: int, dim: int): return HypersphericalUniformDistribution(dim).sample(n_samples) @abstractmethod - def get_grid(self, grid_density_parameter: int | list[int], dim: int): + def get_grid(self, grid_density_parameter, dim: int): raise NotImplementedError() @@ -76,10 +76,10 @@ def get_grid_spherical_coordinates( ): raise NotImplementedError() - def get_grid(self, grid_density_parameter: int, dim: int = 2): + def get_grid(self, grid_density_parameter, dim: int = 2): assert ( dim == 2 - ), "AbstractSphericalCoordinatesBasedSampler is supposed to be used for the circle (which is one-dimensional) only." + ), "AbstractSphericalCoordinatesBasedSampler is supposed to be used for the sphere, i.e. dim=2" phi, theta, grid_specific_description = self.get_grid_spherical_coordinates( grid_density_parameter ) @@ -90,8 +90,11 @@ def get_grid(self, grid_density_parameter: int, dim: int = 2): class HealpixSampler(AbstractHypersphericalUniformSampler): - def get_grid(self, grid_density_parameter: int): + def get_grid(self, grid_density_parameter, dim: int = 2): import healpy as hp + assert ( + dim == 2 + ), "HealpixSampler is supposed to be used for the sphere, i.e. dim=2" n_side = grid_density_parameter n_areas = hp.nside2npix(n_side) @@ -175,12 +178,15 @@ def quaternion_to_hopf_yershova(q): # pylint: disable=too-many-locals class HealpixHopfSampler(AbstractHopfBasedS3Sampler): - def get_grid(self, grid_density_parameter: int | list[int]): + def get_grid(self, grid_density_parameter, dim: int = 3): """ Hopf coordinates are (θ, ϕ, ψ) where θ and ϕ are the angles for the sphere and ψ is the angle on the circle First parameter is the number of points on the sphere, second parameter is the number of points on the circle. """ import healpy as hp + assert ( + dim == 3 + ), "HealpixHopfSampler is supposed to be used for the 3-sphere, i.e. dim=3" if isinstance(grid_density_parameter, int): grid_density_parameter = [grid_density_parameter] @@ -225,7 +231,7 @@ def get_grid(self, grid_density_parameter: int | list[int]): class FibonacciHopfSampler(AbstractHopfBasedS3Sampler): - def get_grid(self, grid_density_parameter: int | list[int]): + def get_grid(self, grid_density_parameter): """ Hopf coordinates are (θ, ϕ, ψ) where θ and ϕ are the angles for the sphere and ψ is the angle on the circle First parameter is the number of points on the sphere, second parameter is the number of points on the circle. From 9174ca8c04a334683694aa481e25f5f95a1669ae Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 19:04:06 +0100 Subject: [PATCH 209/232] More.... --- pyrecest/distributions/abstract_dirac_distribution.py | 4 +--- .../hypertorus/hypertoroidal_dirac_distribution.py | 6 ++---- pyrecest/evaluation/configure_for_filter.py | 2 +- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/pyrecest/distributions/abstract_dirac_distribution.py b/pyrecest/distributions/abstract_dirac_distribution.py index e1d8997d..d8b4ce86 100644 --- a/pyrecest/distributions/abstract_dirac_distribution.py +++ b/pyrecest/distributions/abstract_dirac_distribution.py @@ -52,9 +52,7 @@ def normalize(self) -> "AbstractDiracDistribution": dist.normalize_in_place() return dist - def apply_function( - self, f: Callable, f_supports_multiple: bool = True - ) -> "AbstractDiracDistribution": + def apply_function(self, f: Callable, f_supports_multiple: bool = True): """ Apply a function to the Dirac locations and return a new distribution. diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py b/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py index df366e1c..8d4fe953 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py @@ -66,10 +66,8 @@ def trigonometric_moment(self, n: Union[int, int32, int64]): """ return sum(exp(1j * n * self.d.T) * tile(self.w, (self.dim, 1)), axis=1) - def apply_function( - self, f: Callable, f_supports_multiple: bool = True - ) -> "HypertoroidalDiracDistribution": - dist: HypertoroidalDiracDistribution = super().apply_function( + def apply_function(self, f: Callable, f_supports_multiple: bool = True): + dist = super().apply_function( f, f_supports_multiple ) dist.d = mod(dist.d, 2.0 * pi) diff --git a/pyrecest/evaluation/configure_for_filter.py b/pyrecest/evaluation/configure_for_filter.py index 1d3558a0..ab9b3362 100644 --- a/pyrecest/evaluation/configure_for_filter.py +++ b/pyrecest/evaluation/configure_for_filter.py @@ -69,7 +69,7 @@ def prediction_routine(curr_input): # type: ignore filter_obj = HypertoroidalParticleFilter( no_particles, scenario_config["initial_prior"].dim ) - filter_obj.set_state(scenario_config["initial_prior"]) + filter_obj.filter_state = scenario_config["initial_prior"] if "gen_next_state_with_noise" in scenario_config: From 505caf465dc58de2ed919112a6cb835b34232702 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 19:16:18 +0100 Subject: [PATCH 210/232] Linter fixes etc --- .github/workflows/tests.yml | 2 +- pyrecest/__init__.py | 2 +- .../abstract_hypercylindrical_distribution.py | 5 ++-- .../hyperspherical_uniform_distribution.py | 2 +- .../hypertoroidal_dirac_distribution.py | 4 +-- .../toroidal_uniform_distribution.py | 6 +++-- .../abstract_linear_distribution.py | 12 ++++++--- .../nonperiodic/gaussian_distribution.py | 3 ++- .../nonperiodic/linear_dirac_distribution.py | 2 +- .../filters/hypertoroidal_particle_filter.py | 9 +++---- pyrecest/sampling/hyperspherical_sampler.py | 2 ++ ...est_abstract_hypertoroidal_distribution.py | 2 +- pyrecest/tests/test_metrics.py | 26 +++++++++++++------ 13 files changed, 45 insertions(+), 32 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 9ffac245..87f13df6 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -56,7 +56,7 @@ jobs: export PYRECEST_BACKEND=pytorch poetry run python -m pytest --rootdir . -v --strict-config --junitxml=junit_test_results_pytorch.xml ./pyrecest env: - PYTHONPATH: ${{ github.workspace }} + PYTHONPATH: ${{ github.workspace }} #- name: Run tests with jax backend # if: always() diff --git a/pyrecest/__init__.py b/pyrecest/__init__.py index 8cff810a..b1413bfd 100644 --- a/pyrecest/__init__.py +++ b/pyrecest/__init__.py @@ -1 +1 @@ -import pyrecest._backend \ No newline at end of file +import pyrecest._backend # noqa \ No newline at end of file diff --git a/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py b/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py index d5b7bf57..95b212d9 100644 --- a/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py +++ b/pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py @@ -179,7 +179,6 @@ def condition_on_linear(self, input_lin, normalize=True): ), "Input should be of size (lin_dim,)." def f_cond_unnorm(xs, input_lin=input_lin): - if xs.ndim == 0: assert self.bound_dim == 1 n_inputs = 1 @@ -190,7 +189,7 @@ def f_cond_unnorm(xs, input_lin=input_lin): n_inputs = 1 else: n_inputs = xs.shape[0] - + input_repeated = tile(input_lin, (n_inputs, 1)) return self.pdf(column_stack((xs, input_repeated))) @@ -234,7 +233,7 @@ def f_cond_unnorm(xs, input_periodic=input_periodic): n_inputs = 1 else: n_inputs = xs.shape[0] - + input_repeated = tile(input_periodic, (n_inputs, 1)) return self.pdf(column_stack((input_repeated, xs))) diff --git a/pyrecest/distributions/hypersphere_subset/hyperspherical_uniform_distribution.py b/pyrecest/distributions/hypersphere_subset/hyperspherical_uniform_distribution.py index 222040be..07493810 100644 --- a/pyrecest/distributions/hypersphere_subset/hyperspherical_uniform_distribution.py +++ b/pyrecest/distributions/hypersphere_subset/hyperspherical_uniform_distribution.py @@ -31,7 +31,7 @@ def sample(self, n: Union[int, int32, int64]): ) phi = 2.0 * pi * random.rand(n) sz = random.rand(n) * 2.0 - 1.0 - r = sqrt(1 - sz ** 2) + r = sqrt(1 - sz**2) s = stack([r * cos(phi), r * sin(phi), sz], axis=1) else: samples_unnorm = random.normal(0.0, 1.0, (n, self.dim + 1)) diff --git a/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py b/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py index 8d4fe953..a670c693 100644 --- a/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py +++ b/pyrecest/distributions/hypertorus/hypertoroidal_dirac_distribution.py @@ -67,9 +67,7 @@ def trigonometric_moment(self, n: Union[int, int32, int64]): return sum(exp(1j * n * self.d.T) * tile(self.w, (self.dim, 1)), axis=1) def apply_function(self, f: Callable, f_supports_multiple: bool = True): - dist = super().apply_function( - f, f_supports_multiple - ) + dist = super().apply_function(f, f_supports_multiple) dist.d = mod(dist.d, 2.0 * pi) return dist diff --git a/pyrecest/distributions/hypertorus/toroidal_uniform_distribution.py b/pyrecest/distributions/hypertorus/toroidal_uniform_distribution.py index a28c7045..cf438096 100644 --- a/pyrecest/distributions/hypertorus/toroidal_uniform_distribution.py +++ b/pyrecest/distributions/hypertorus/toroidal_uniform_distribution.py @@ -1,6 +1,8 @@ +import copy + from .abstract_toroidal_distribution import AbstractToroidalDistribution from .hypertoroidal_uniform_distribution import HypertoroidalUniformDistribution -import copy + class ToroidalUniformDistribution( HypertoroidalUniformDistribution, AbstractToroidalDistribution @@ -9,4 +11,4 @@ def get_manifold_size(self): return AbstractToroidalDistribution.get_manifold_size(self) def shift(self, _): - return copy.deepcopy(self) \ No newline at end of file + return copy.deepcopy(self) diff --git a/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py b/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py index b91e4c96..75f5d9f3 100644 --- a/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py +++ b/pyrecest/distributions/nonperiodic/abstract_linear_distribution.py @@ -101,9 +101,13 @@ def proposal(x): def mean_numerical(self): if self.dim == 1: - mu = array(quad( - lambda x: x * self.pdf(array(x)), array(-float("inf")), array(float("inf")) - )[0]) + mu = array( + quad( + lambda x: x * self.pdf(array(x)), + array(-float("inf")), + array(float("inf")), + )[0] + ) elif self.dim == 2: mu = empty(self.dim) mu[0] = dblquad( @@ -122,7 +126,7 @@ def mean_numerical(self): )[0] elif self.dim == 3: mu = empty(self.dim) - + def integrand1(x, y, z): return x * self.pdf(array([x, y, z])) diff --git a/pyrecest/distributions/nonperiodic/gaussian_distribution.py b/pyrecest/distributions/nonperiodic/gaussian_distribution.py index 68e0ac09..5db75e55 100644 --- a/pyrecest/distributions/nonperiodic/gaussian_distribution.py +++ b/pyrecest/distributions/nonperiodic/gaussian_distribution.py @@ -47,7 +47,8 @@ def pdf(self, xs): pdfvals = mvn.pdf(xs, self.mu, self.C) elif pyrecest.backend.__name__ == "pyrecest.pytorch": # Disable import errors for megalinter - import torch # pylint: disable=import-error + import torch # pylint: disable=import-error + # pylint: disable=import-error from torch.distributions import MultivariateNormal diff --git a/pyrecest/distributions/nonperiodic/linear_dirac_distribution.py b/pyrecest/distributions/nonperiodic/linear_dirac_distribution.py index 89e1320c..7971a914 100644 --- a/pyrecest/distributions/nonperiodic/linear_dirac_distribution.py +++ b/pyrecest/distributions/nonperiodic/linear_dirac_distribution.py @@ -51,7 +51,7 @@ def weighted_samples_to_mean_and_cov(samples, weights=None): if weights is None: weights = ones(samples.shape[1]) / samples.shape[1] - mean = weights@samples + mean = weights @ samples deviation = samples - mean covariance = cov(deviation.T, aweights=weights, bias=True) diff --git a/pyrecest/filters/hypertoroidal_particle_filter.py b/pyrecest/filters/hypertoroidal_particle_filter.py index d5012af7..38037e8c 100644 --- a/pyrecest/filters/hypertoroidal_particle_filter.py +++ b/pyrecest/filters/hypertoroidal_particle_filter.py @@ -1,4 +1,3 @@ -import copy from collections.abc import Callable from math import pi from typing import Union @@ -34,11 +33,9 @@ def __init__( if dim == 1: points = linspace(0.0, 2.0 * pi, num=n_particles, endpoint=False) else: - points = ( - tile( - arange(0.0, 2.0 * pi, 2.0 * pi / n_particles), (dim, 1) - ).T.squeeze() - ) + points = tile( + arange(0.0, 2.0 * pi, 2.0 * pi / n_particles), (dim, 1) + ).T.squeeze() filter_state = HypertoroidalDiracDistribution(points, dim=1) AbstractHypertoroidalFilter.__init__(self, filter_state) AbstractParticleFilter.__init__(self, filter_state) diff --git a/pyrecest/sampling/hyperspherical_sampler.py b/pyrecest/sampling/hyperspherical_sampler.py index 1572c2c6..e92875c0 100644 --- a/pyrecest/sampling/hyperspherical_sampler.py +++ b/pyrecest/sampling/hyperspherical_sampler.py @@ -92,6 +92,7 @@ def get_grid(self, grid_density_parameter, dim: int = 2): class HealpixSampler(AbstractHypersphericalUniformSampler): def get_grid(self, grid_density_parameter, dim: int = 2): import healpy as hp + assert ( dim == 2 ), "HealpixSampler is supposed to be used for the sphere, i.e. dim=2" @@ -184,6 +185,7 @@ def get_grid(self, grid_density_parameter, dim: int = 3): First parameter is the number of points on the sphere, second parameter is the number of points on the circle. """ import healpy as hp + assert ( dim == 3 ), "HealpixHopfSampler is supposed to be used for the 3-sphere, i.e. dim=3" diff --git a/pyrecest/tests/distributions/test_abstract_hypertoroidal_distribution.py b/pyrecest/tests/distributions/test_abstract_hypertoroidal_distribution.py index a2a62af8..b0692ef5 100644 --- a/pyrecest/tests/distributions/test_abstract_hypertoroidal_distribution.py +++ b/pyrecest/tests/distributions/test_abstract_hypertoroidal_distribution.py @@ -21,5 +21,5 @@ def test_angular_error(self): array(pi / 4), array(7 * pi / 4) ), pi / 2, - rtol=2e-07 + rtol=2e-07, ) diff --git a/pyrecest/tests/test_metrics.py b/pyrecest/tests/test_metrics.py index bd40a5a6..914d2c75 100644 --- a/pyrecest/tests/test_metrics.py +++ b/pyrecest/tests/test_metrics.py @@ -3,7 +3,7 @@ import numpy.testing as npt # pylint: disable=no-name-in-module,no-member -from pyrecest.backend import array, random, repeat, vstack, expand_dims +from pyrecest.backend import array, random, repeat, vstack from pyrecest.utils.metrics import anees @@ -11,14 +11,18 @@ class TestANEES(unittest.TestCase): def setUp(self): self.groundtruths = array([[1.5, 2.5], [2.5, 3.5], [4.5, 5.5]]) self.uncertainties = array( - [[[1.0, 0.5], [0.5, 2.0]], [[1.0, 0.0], [0.0, 1.0]], [[0.5, 0.0], [0.0, 1.5]]] + [ + [[1.0, 0.5], [0.5, 2.0]], + [[1.0, 0.0], [0.0, 1.0]], + [[0.5, 0.0], [0.0, 1.5]], + ] ) self.n_timesteps_constant = 10000 def test_ANEES_is_close_to_one(self): - """ Test that the ANEES is close to 1 when we sample from the groundtruths with the given uncertainties. + """Test that the ANEES is close to 1 when we sample from the groundtruths with the given uncertainties. Simulate that the state stays constant for 10000 time steps, then changes, stays constant for another 10000 time steps - and then changes once more before staying constant for the remaining 10000 time steps. + and then changes once more before staying constant for the remaining 10000 time steps. """ samples = [] @@ -31,11 +35,17 @@ def test_ANEES_is_close_to_one(self): samples.append(samples_for_i) samples_mat = vstack(samples) - - repeated_groundtruths = repeat(self.groundtruths, repeats=self.n_timesteps_constant, axis=0) - repeated_uncertainties = repeat(self.uncertainties, repeats=self.n_timesteps_constant, axis=0) - computed_ANEES = anees(samples_mat, repeated_uncertainties, repeated_groundtruths) + repeated_groundtruths = repeat( + self.groundtruths, repeats=self.n_timesteps_constant, axis=0 + ) + repeated_uncertainties = repeat( + self.uncertainties, repeats=self.n_timesteps_constant, axis=0 + ) + + computed_ANEES = anees( + samples_mat, repeated_uncertainties, repeated_groundtruths + ) # Assert that computed ANEES is close to 1 with a tolerance of 0.05. npt.assert_almost_equal(computed_ANEES, self.groundtruths.shape[-1], decimal=2) From b2d083ca01bb6f28784dabb3bd572af2681f93e2 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Tue, 24 Oct 2023 20:52:39 +0200 Subject: [PATCH 211/232] More --- pyrecest/sampling/hyperspherical_sampler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrecest/sampling/hyperspherical_sampler.py b/pyrecest/sampling/hyperspherical_sampler.py index e92875c0..204d43eb 100644 --- a/pyrecest/sampling/hyperspherical_sampler.py +++ b/pyrecest/sampling/hyperspherical_sampler.py @@ -196,7 +196,7 @@ def get_grid(self, grid_density_parameter, dim: int = 3): s3_points_list = [] for i in range(grid_density_parameter[0] + 1): - if grid_density_parameter.shape[0] == 2: + if len(grid_density_parameter) == 2: n_sample_circle = grid_density_parameter[1] else: n_sample_circle = 2**i * 6 From bc137e124ab0cc66e4e0895f8482bb38cf6fef31 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Wed, 25 Oct 2023 10:18:03 +0100 Subject: [PATCH 212/232] More... --- .../cart_prod/lin_hypersphere_cart_prod_dirac_distribution.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyrecest/distributions/cart_prod/lin_hypersphere_cart_prod_dirac_distribution.py b/pyrecest/distributions/cart_prod/lin_hypersphere_cart_prod_dirac_distribution.py index 6cf72e63..a0cb0083 100644 --- a/pyrecest/distributions/cart_prod/lin_hypersphere_cart_prod_dirac_distribution.py +++ b/pyrecest/distributions/cart_prod/lin_hypersphere_cart_prod_dirac_distribution.py @@ -1,5 +1,5 @@ # pylint: disable=redefined-builtin,no-name-in-module,no-member -from pyrecest.backend import abs, linalg, max +from pyrecest.backend import abs, linalg, amax from ..abstract_se3_distribution import AbstractSE3Distribution from .lin_bounded_cart_prod_dirac_distribution import ( @@ -12,7 +12,7 @@ class LinHypersphereCartProdDiracDistribution( ): def __init__(self, bound_dim, d, w=None): assert ( - max(abs(linalg.norm(d[:, : (bound_dim + 1)], None, -1) - 1), 0) < 1e-5 + amax(abs(linalg.norm(d[:, : (bound_dim + 1)], None, -1) - 1), 0) < 1e-5 ), "The hypersphere ssubset part of d must be normalized" AbstractSE3Distribution.__init__(self) LinBoundedCartProdDiracDistribution.__init__(self, d, w) From a1fedb1e17fbad95afb1724e09339a92f57dc120 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Wed, 25 Oct 2023 11:34:59 +0100 Subject: [PATCH 213/232] Try --- pyrecest/filters/abstract_particle_filter.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/pyrecest/filters/abstract_particle_filter.py b/pyrecest/filters/abstract_particle_filter.py index 02a62210..3288a062 100644 --- a/pyrecest/filters/abstract_particle_filter.py +++ b/pyrecest/filters/abstract_particle_filter.py @@ -56,7 +56,19 @@ def predict_nonlinear_nonadditive(self, f, samples, weights): for i in range(n_particles): d[i, :] = f(self.filter_state.d[i, :], noise_samples[i]) - self.filter_state.d = d + self._filter_state.d = d + + @property + def filter_state(self): + return self._filter_state + + @filter_state.setter + def filter_state(self, new_state): + if self._filter_state is not None and not isinstance(new_state, type(self.filter_state)): + # Sample if it does not inherit from the previous distribution + samples = new_state.sample(self.filter_state.w.shape[0]) + assert samples.shape == self.filter_state.d.shape + self._filter_state.d = samples def update_identity( self, meas_noise, measurement, shift_instead_of_add: bool = True From f1d76e125ed31ab6622d12a1cfc876e58c532378 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Wed, 25 Oct 2023 11:39:30 +0100 Subject: [PATCH 214/232] More --- pyrecest/filters/von_mises_filter.py | 9 --------- .../tests/filters/test_circular_particle_filter.py | 14 +++++++------- .../tests/filters/test_global_nearest_neighbor.py | 2 +- .../filters/test_hypertoroidal_particle_filter.py | 6 +++--- .../tests/filters/test_toroidal_particle_filter.py | 2 +- pyrecest/tests/filters/test_von_mises_filter.py | 6 +++--- 6 files changed, 15 insertions(+), 24 deletions(-) diff --git a/pyrecest/filters/von_mises_filter.py b/pyrecest/filters/von_mises_filter.py index 369898bf..87f47951 100644 --- a/pyrecest/filters/von_mises_filter.py +++ b/pyrecest/filters/von_mises_filter.py @@ -28,15 +28,6 @@ def __init__(self): """ AbstractCircularFilter.__init__(self, VonMisesDistribution(0, 1)) - def set_state(self, new_state: VonMisesDistribution): - """ - Sets the current system state - - Parameters: - new_state (VonMisesDistribution) : new state - """ - self.filter_state = copy.deepcopy(new_state) - def predict_identity(self, vmSys: VonMisesDistribution): """ Predicts assuming identity system model, i.e., diff --git a/pyrecest/tests/filters/test_circular_particle_filter.py b/pyrecest/tests/filters/test_circular_particle_filter.py index fe3d21fe..0f03067b 100644 --- a/pyrecest/tests/filters/test_circular_particle_filter.py +++ b/pyrecest/tests/filters/test_circular_particle_filter.py @@ -29,7 +29,7 @@ def setUp(self): def test_estimate(self): self.assertTrue(allclose(self.dist.trigonometric_moment(1), 0.0, atol=1e-10)) - def test_set_state(self): + def test_setting_state(self): # sanity check self.filter.filter_state = self.dist dist1 = self.filter.filter_state @@ -60,7 +60,7 @@ def f(x): self.assertIsInstance(dist2, HypertoroidalDiracDistribution) self.assertEqual(dist2.dim, 1) - self.filter.set_state(self.dist) + self.filter.filter_state = self.dist self.filter.predict_identity(self.wn) dist2_identity = self.filter.filter_state self.assertIsInstance(dist2_identity, HypertoroidalDiracDistribution) @@ -69,7 +69,7 @@ def f(x): def test_nonlinear_prediction_without_noise(self): # nonlinear test without noise - self.filter.set_state(self.dist) + self.filter.filter_state = self.dist def f(x): return x**2 @@ -85,7 +85,7 @@ def f(x): def test_update(self): # test update random.seed(0) - self.filter.set_state(self.dist) + self.filter.filter_state = self.dist def h(x): return x @@ -98,7 +98,7 @@ def likelihood(z, x): self.filter.update_nonlinear_using_likelihood(likelihood, z) dist3a = self.filter.filter_state self.assertIsInstance(dist3a, CircularDiracDistribution) - self.filter.set_state(self.dist) + self.filter.filter_state = self.dist self.filter.update_identity(self.wn, z) dist3b = self.filter.filter_state self.assertIsInstance(dist3b, CircularDiracDistribution) @@ -108,7 +108,7 @@ def test_association_likelihood(self): array([1.0, 2.0, 3.0]), array([1 / 3, 1 / 3, 1 / 3]) ) pf = CircularParticleFilter(3) - pf.set_state(dist) + pf.filter_state = dist self.assertAlmostEqual( pf.association_likelihood(CircularUniformDistribution()), @@ -120,7 +120,7 @@ def test_association_likelihood(self): 1.0 / (2.0 * pi), ) - self.filter.set_state(CircularDiracDistribution(arange(0.0, 1.1, 0.1))) + self.filter.filter_state = CircularDiracDistribution(arange(0.0, 1.1, 0.1)) def likelihood1(_, x): return (x == 0.5) + 0.0 # To convert it to double regardless of the backend diff --git a/pyrecest/tests/filters/test_global_nearest_neighbor.py b/pyrecest/tests/filters/test_global_nearest_neighbor.py index 114a3e80..f62be53e 100644 --- a/pyrecest/tests/filters/test_global_nearest_neighbor.py +++ b/pyrecest/tests/filters/test_global_nearest_neighbor.py @@ -64,7 +64,7 @@ def setUp(self): (self.all_different_meas_covs, array([[2.0, -0.5], [-0.5, 0.5]])) ) - def test_set_state_sets_correct_state(self): + def test_setting_state_sets_correct_state(self): tracker = GlobalNearestNeighbor() tracker.filter_state = self.kfs_init self.assertEqual( diff --git a/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py b/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py index 178d51cb..683496ec 100644 --- a/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py +++ b/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py @@ -21,8 +21,8 @@ def setUp(self): self.forced_mean = array([1.0, 2.0, 3.0]) random.seed(self.seed) - def test_set_state(self): - self.hpf.set_state(self.hwnd) + def test_setting_state(self): + self.hpf.filter_state = self.hwnd def test_predict_identity(self): self.hpf.predict_identity( @@ -38,7 +38,7 @@ def test_update_identity(self): self.assertEqual(self.hpf.get_point_estimate().shape, (3,)) def test_predict_update_cycle_3D(self): - self.hpf.set_state(self.hwnd) + self.hpf.filter_state = self.hwnd for _ in range(10): self.test_predict_identity() for _ in range(3): diff --git a/pyrecest/tests/filters/test_toroidal_particle_filter.py b/pyrecest/tests/filters/test_toroidal_particle_filter.py index 888d6058..319e11a3 100644 --- a/pyrecest/tests/filters/test_toroidal_particle_filter.py +++ b/pyrecest/tests/filters/test_toroidal_particle_filter.py @@ -19,7 +19,7 @@ def test_toroidal_particle_filter(self): mu = array([1.0, 1.0]) + pi / 2.0 hwnd = ToroidalWrappedNormalDistribution(mu, C) tpf = ToroidalParticleFilter(200) - tpf.set_state(hwnd) + tpf.filter_state = hwnd forced_mean = array([1.0, 1.0]) for _ in range(50): diff --git a/pyrecest/tests/filters/test_von_mises_filter.py b/pyrecest/tests/filters/test_von_mises_filter.py index 04221807..a588aeb4 100644 --- a/pyrecest/tests/filters/test_von_mises_filter.py +++ b/pyrecest/tests/filters/test_von_mises_filter.py @@ -13,7 +13,7 @@ def setUp(self): self.curr_filter = VonMisesFilter() self.vm_prior = VonMisesDistribution(2.1, 1.3) - def test_set_state(self): + def test_setting_state(self): vm = self.vm_prior self.curr_filter.filter_state = vm vm1 = self.curr_filter.filter_state @@ -24,7 +24,7 @@ def test_set_state(self): def test_prediction(self): sysnoise = VonMisesDistribution(0, 0.3) - self.curr_filter.set_state(self.vm_prior) + self.curr_filter.filter_state = self.vm_prior self.curr_filter.predict_identity(sysnoise) self.assertIsInstance(self.curr_filter.filter_state, VonMisesDistribution) self.assertEqual(self.curr_filter.filter_state.mu, 2.1) @@ -34,7 +34,7 @@ def test_update(self): meas_noise = VonMisesDistribution(0.0, 1.3) meas = array(1.1) - self.curr_filter.set_state(self.vm_prior) + self.curr_filter.filter_state = self.vm_prior self.curr_filter.update_identity(meas_noise, meas) self.assertIsInstance(self.curr_filter.filter_state, VonMisesDistribution) npt.assert_allclose( From 5381e17410739755f8b493564b210f34a7f7c1ab Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Wed, 25 Oct 2023 12:20:02 +0100 Subject: [PATCH 215/232] Fixes --- pyrecest/filters/abstract_particle_filter.py | 10 ++++++++-- pyrecest/filters/hypertoroidal_particle_filter.py | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/pyrecest/filters/abstract_particle_filter.py b/pyrecest/filters/abstract_particle_filter.py index 3288a062..b97a4341 100644 --- a/pyrecest/filters/abstract_particle_filter.py +++ b/pyrecest/filters/abstract_particle_filter.py @@ -64,11 +64,17 @@ def filter_state(self): @filter_state.setter def filter_state(self, new_state): - if self._filter_state is not None and not isinstance(new_state, type(self.filter_state)): + if self._filter_state is None: + self._filter_state = new_state + elif isinstance(new_state, type(self.filter_state)): + assert self.filter_state.d.shape == new_state.d.shape # This also ensures the dimension and type stays the same + self.filter_state = new_state + else: # Sample if it does not inherit from the previous distribution samples = new_state.sample(self.filter_state.w.shape[0]) - assert samples.shape == self.filter_state.d.shape + assert samples.shape == self.filter_state.d.shape # This also ensures the dimension and type stays the same self._filter_state.d = samples + self._filter_state.w = ones_like(self.filter_state.w) / self.filter_state.w.shape[0] def update_identity( self, meas_noise, measurement, shift_instead_of_add: bool = True diff --git a/pyrecest/filters/hypertoroidal_particle_filter.py b/pyrecest/filters/hypertoroidal_particle_filter.py index 38037e8c..1e3ca2af 100644 --- a/pyrecest/filters/hypertoroidal_particle_filter.py +++ b/pyrecest/filters/hypertoroidal_particle_filter.py @@ -36,7 +36,7 @@ def __init__( points = tile( arange(0.0, 2.0 * pi, 2.0 * pi / n_particles), (dim, 1) ).T.squeeze() - filter_state = HypertoroidalDiracDistribution(points, dim=1) + filter_state = HypertoroidalDiracDistribution(points, dim=dim) AbstractHypertoroidalFilter.__init__(self, filter_state) AbstractParticleFilter.__init__(self, filter_state) From 4c140fbbd211a0170a0c2f49209e1f8ecb223cf9 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Wed, 25 Oct 2023 13:34:05 +0100 Subject: [PATCH 216/232] More.... --- .../test_hypertoroidal_dirac_distribution.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py b/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py index 474a0690..bac3336f 100644 --- a/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py @@ -6,11 +6,12 @@ # pylint: disable=redefined-builtin,no-name-in-module,no-member # pylint: disable=no-name-in-module,no-member -from pyrecest.backend import array, exp, mod, ones_like, outer, random, sum +from pyrecest.backend import array, exp, mod, random, sum, zeros_like from pyrecest.distributions import ( HypertoroidalDiracDistribution, ToroidalDiracDistribution, ) +from pyrecest.distributions import AbstractHypertoroidalDistribution class TestHypertoroidalDiracDistribution(unittest.TestCase): @@ -78,13 +79,13 @@ def test_shift(self): w = array([0.3, 0.3, 0.3, 0.05, 0.05]) twd = HypertoroidalDiracDistribution(d, w) - s = array([1, -3, 6]) + s = array([1.0, -3.0, 6.0]) twd_shifted = twd.shift(s) self.assertIsInstance(twd_shifted, HypertoroidalDiracDistribution) npt.assert_array_almost_equal(twd.w, twd_shifted.w) npt.assert_array_almost_equal( - twd.d, - mod(twd_shifted.d - outer(ones_like(w), s), 2 * pi), + AbstractHypertoroidalDistribution.angular_error(twd.d, twd_shifted.d - s), + zeros_like(twd.d), decimal=10, ) @@ -92,7 +93,7 @@ def test_shift(self): def get_pseudorandom_hypertoroidal_wd(dim=2): random.seed(0) n = 20 - d = 2 * pi * random.rand(n, dim) + d = 2.0 * pi * random.rand(n, dim) w = random.rand(n) w = w / sum(w) hwd = HypertoroidalDiracDistribution(d, w) From 577c41b45be28b4d343afec3a8df0f444a414abf Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Wed, 25 Oct 2023 13:40:25 +0100 Subject: [PATCH 217/232] More --- pyrecest/filters/abstract_particle_filter.py | 2 +- pyrecest/tests/filters/test_circular_particle_filter.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pyrecest/filters/abstract_particle_filter.py b/pyrecest/filters/abstract_particle_filter.py index b97a4341..da10ad75 100644 --- a/pyrecest/filters/abstract_particle_filter.py +++ b/pyrecest/filters/abstract_particle_filter.py @@ -68,7 +68,7 @@ def filter_state(self, new_state): self._filter_state = new_state elif isinstance(new_state, type(self.filter_state)): assert self.filter_state.d.shape == new_state.d.shape # This also ensures the dimension and type stays the same - self.filter_state = new_state + self._filter_state = new_state else: # Sample if it does not inherit from the previous distribution samples = new_state.sample(self.filter_state.w.shape[0]) diff --git a/pyrecest/tests/filters/test_circular_particle_filter.py b/pyrecest/tests/filters/test_circular_particle_filter.py index 0f03067b..e4a95210 100644 --- a/pyrecest/tests/filters/test_circular_particle_filter.py +++ b/pyrecest/tests/filters/test_circular_particle_filter.py @@ -4,7 +4,7 @@ import numpy.testing as npt # pylint: disable=no-name-in-module,no-member -from pyrecest.backend import allclose, arange, array, random +from pyrecest.backend import allclose, arange, array, random, linspace from pyrecest.distributions import ( HypertoroidalDiracDistribution, WrappedNormalDistribution, @@ -120,7 +120,7 @@ def test_association_likelihood(self): 1.0 / (2.0 * pi), ) - self.filter.filter_state = CircularDiracDistribution(arange(0.0, 1.1, 0.1)) + self.filter.filter_state = CircularDiracDistribution(linspace(0.0, 1.1, 30)) def likelihood1(_, x): return (x == 0.5) + 0.0 # To convert it to double regardless of the backend From 7277ad809f7fd2fbbb88adc64bffabdc1f979f64 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Wed, 25 Oct 2023 14:03:44 +0100 Subject: [PATCH 218/232] More --- pyrecest/filters/abstract_particle_filter.py | 6 +++--- pyrecest/tests/filters/test_circular_particle_filter.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pyrecest/filters/abstract_particle_filter.py b/pyrecest/filters/abstract_particle_filter.py index da10ad75..abdc8f65 100644 --- a/pyrecest/filters/abstract_particle_filter.py +++ b/pyrecest/filters/abstract_particle_filter.py @@ -1,5 +1,5 @@ from collections.abc import Callable - +import copy # pylint: disable=redefined-builtin,no-name-in-module,no-member # pylint: disable=no-name-in-module,no-member from pyrecest.backend import ndim, ones_like, random, sum, zeros @@ -65,10 +65,10 @@ def filter_state(self): @filter_state.setter def filter_state(self, new_state): if self._filter_state is None: - self._filter_state = new_state + self._filter_state = copy.deepcopy(new_state) elif isinstance(new_state, type(self.filter_state)): assert self.filter_state.d.shape == new_state.d.shape # This also ensures the dimension and type stays the same - self._filter_state = new_state + self._filter_state = copy.deepcopy(new_state) else: # Sample if it does not inherit from the previous distribution samples = new_state.sample(self.filter_state.w.shape[0]) diff --git a/pyrecest/tests/filters/test_circular_particle_filter.py b/pyrecest/tests/filters/test_circular_particle_filter.py index e4a95210..d542f77d 100644 --- a/pyrecest/tests/filters/test_circular_particle_filter.py +++ b/pyrecest/tests/filters/test_circular_particle_filter.py @@ -74,7 +74,7 @@ def test_nonlinear_prediction_without_noise(self): def f(x): return x**2 - no_noise = CircularDiracDistribution(array([0])) + no_noise = CircularDiracDistribution(array([0.0])) self.filter.predict_nonlinear(f, no_noise) predicted = self.filter.filter_state self.assertIsInstance(predicted, HypertoroidalDiracDistribution) From 8a9890a0ced82d8e182e99cbdcf17a3ea49dcf92 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Wed, 25 Oct 2023 14:21:31 +0100 Subject: [PATCH 219/232] More... --- pyrecest/filters/circular_particle_filter.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/pyrecest/filters/circular_particle_filter.py b/pyrecest/filters/circular_particle_filter.py index 72dea3ac..b599e3f9 100644 --- a/pyrecest/filters/circular_particle_filter.py +++ b/pyrecest/filters/circular_particle_filter.py @@ -1,11 +1,13 @@ from typing import Union - +from math import pi # pylint: disable=redefined-builtin,no-name-in-module,no-member # pylint: disable=no-name-in-module,no-member -from pyrecest.backend import float64, int32, int64, sum +from pyrecest.backend import float64, int32, int64, sum, linspace from .hypertoroidal_particle_filter import HypertoroidalParticleFilter - +from .abstract_hypertoroidal_filter import AbstractHypertoroidalFilter +from .abstract_particle_filter import AbstractParticleFilter +from pyrecest.distributions import CircularDiracDistribution class CircularParticleFilter(HypertoroidalParticleFilter): def __init__(self, n_particles: Union[int, int32, int64]) -> None: @@ -14,7 +16,10 @@ def __init__(self, n_particles: Union[int, int32, int64]) -> None: :param n_particles: number of particles """ - super().__init__(n_particles, 1) + filter_state = CircularDiracDistribution(linspace(0.0, 2.0 * pi, n_particles)) + AbstractHypertoroidalFilter.__init__(self, filter_state) + AbstractParticleFilter.__init__(self, filter_state) + def compute_association_likelihood(self, likelihood) -> float64: """ From 55fb75f58e5f48fbf6215669b4e5c943eb73d26c Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Wed, 25 Oct 2023 14:21:53 +0100 Subject: [PATCH 220/232] More.. --- pyrecest/filters/circular_particle_filter.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pyrecest/filters/circular_particle_filter.py b/pyrecest/filters/circular_particle_filter.py index b599e3f9..ddf68fdb 100644 --- a/pyrecest/filters/circular_particle_filter.py +++ b/pyrecest/filters/circular_particle_filter.py @@ -1,7 +1,6 @@ from typing import Union from math import pi # pylint: disable=redefined-builtin,no-name-in-module,no-member -# pylint: disable=no-name-in-module,no-member from pyrecest.backend import float64, int32, int64, sum, linspace from .hypertoroidal_particle_filter import HypertoroidalParticleFilter From b14b47705a250ce1a5ab1d48ad323e7c9fc4b579 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Wed, 25 Oct 2023 14:33:44 +0100 Subject: [PATCH 221/232] More..... --- pyrecest/filters/abstract_particle_filter.py | 8 ++++---- pyrecest/tests/filters/test_circular_particle_filter.py | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pyrecest/filters/abstract_particle_filter.py b/pyrecest/filters/abstract_particle_filter.py index abdc8f65..50573af0 100644 --- a/pyrecest/filters/abstract_particle_filter.py +++ b/pyrecest/filters/abstract_particle_filter.py @@ -97,14 +97,14 @@ def update_nonlinear_using_likelihood(self, likelihood, measurement=None): likelihood = likelihood.pdf if measurement is None: - self.filter_state = self.filter_state.reweigh(likelihood) + self._filter_state = self.filter_state.reweigh(likelihood) else: - self.filter_state = self.filter_state.reweigh( + self._filter_state = self.filter_state.reweigh( lambda x: likelihood(measurement, x) ) - self.filter_state.d = self.filter_state.sample(self.filter_state.w.shape[0]) - self.filter_state.w = ( + self._filter_state.d = self.filter_state.sample(self.filter_state.w.shape[0]) + self._filter_state.w = ( 1 / self.filter_state.w.shape[0] * ones_like(self.filter_state.w) ) diff --git a/pyrecest/tests/filters/test_circular_particle_filter.py b/pyrecest/tests/filters/test_circular_particle_filter.py index d542f77d..02a3711a 100644 --- a/pyrecest/tests/filters/test_circular_particle_filter.py +++ b/pyrecest/tests/filters/test_circular_particle_filter.py @@ -123,13 +123,13 @@ def test_association_likelihood(self): self.filter.filter_state = CircularDiracDistribution(linspace(0.0, 1.1, 30)) def likelihood1(_, x): - return (x == 0.5) + 0.0 # To convert it to double regardless of the backend + return (x == 1.1) + 0.0 # To convert it to double regardless of the backend self.filter.update_nonlinear_using_likelihood(likelihood1, 42) estimation = self.filter.filter_state self.assertIsInstance(estimation, CircularDiracDistribution) for i in range(len(estimation.d)): - self.assertEqual(estimation.d[i], 0.5) + self.assertEqual(estimation.d[i], 1.1) # test update with single parameter likelihood random.seed(0) From 945477999ddd923f3e628f49583fcabc588fe656 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Wed, 25 Oct 2023 14:46:00 +0100 Subject: [PATCH 222/232] More --- pyrecest/filters/abstract_nearest_neighbor_tracker.py | 7 ++++++- pyrecest/tests/filters/test_global_nearest_neighbor.py | 4 ++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/pyrecest/filters/abstract_nearest_neighbor_tracker.py b/pyrecest/filters/abstract_nearest_neighbor_tracker.py index c9726231..1005846e 100644 --- a/pyrecest/filters/abstract_nearest_neighbor_tracker.py +++ b/pyrecest/filters/abstract_nearest_neighbor_tracker.py @@ -4,6 +4,8 @@ # pylint: disable=no-name-in-module,no-member from pyrecest.backend import dstack, empty, ndim +# pylint: disable=no-name-in-module,no-member +import pyrecest.backend from pyrecest.distributions import GaussianDistribution from .abstract_euclidean_filter import AbstractEuclideanFilter @@ -111,8 +113,11 @@ def predict_linear(self, system_matrices, sys_noises, inputs=None): self.store_prior_estimates() def update_linear(self, measurements, measurement_matrix, covMatsMeas): + assert ( + pyrecest.backend.__name__ == "pyrecest.numpy" + ), "Only supported for numpy backend" if len(self.filter_bank) == 0: - print("Currently, there are zero targets") + warnings.warn("Currently, there are zero targets") return assert ( measurement_matrix.shape[0] == measurements.shape[0] diff --git a/pyrecest/tests/filters/test_global_nearest_neighbor.py b/pyrecest/tests/filters/test_global_nearest_neighbor.py index f62be53e..80eae910 100644 --- a/pyrecest/tests/filters/test_global_nearest_neighbor.py +++ b/pyrecest/tests/filters/test_global_nearest_neighbor.py @@ -264,6 +264,10 @@ def test_association_with_clutter(self): measurements[:, association] + 0.1, perfect_meas_ordered + 0.1 ) + @unittest.skipIf( + pyrecest.backend.__name__ == "pyrecest.pytorch", + reason="Not supported on PyTorch backend", + ) def test_update_with_and_without_clutter(self): tracker_no_clut = GlobalNearestNeighbor() tracker_clut = GlobalNearestNeighbor() From 08aae6dfb0c38a459baef33ae0598c0eabef2731 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Wed, 25 Oct 2023 14:48:22 +0100 Subject: [PATCH 223/232] More --- pyrecest/filters/circular_particle_filter.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pyrecest/filters/circular_particle_filter.py b/pyrecest/filters/circular_particle_filter.py index ddf68fdb..0ddad063 100644 --- a/pyrecest/filters/circular_particle_filter.py +++ b/pyrecest/filters/circular_particle_filter.py @@ -9,6 +9,7 @@ from pyrecest.distributions import CircularDiracDistribution class CircularParticleFilter(HypertoroidalParticleFilter): + # pylint: disable=non-parent-init-called,super-init-not-called def __init__(self, n_particles: Union[int, int32, int64]) -> None: """ Initialize the CircularParticleFilter. From 276bdf884c44480605b97ffd14eaa4f503064114 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Wed, 25 Oct 2023 14:48:55 +0100 Subject: [PATCH 224/232] More. --- pyrecest/filters/circular_particle_filter.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pyrecest/filters/circular_particle_filter.py b/pyrecest/filters/circular_particle_filter.py index 0ddad063..ebd85a3a 100644 --- a/pyrecest/filters/circular_particle_filter.py +++ b/pyrecest/filters/circular_particle_filter.py @@ -20,7 +20,6 @@ def __init__(self, n_particles: Union[int, int32, int64]) -> None: AbstractHypertoroidalFilter.__init__(self, filter_state) AbstractParticleFilter.__init__(self, filter_state) - def compute_association_likelihood(self, likelihood) -> float64: """ Compute the likelihood of association based on the PDF of the likelihood From ab2ad0213fffa51675e22c6445d71f0618694954 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Wed, 25 Oct 2023 15:11:47 +0100 Subject: [PATCH 225/232] More... --- pyrecest/tests/filters/test_euclidean_particle_filter.py | 9 ++++----- .../tests/filters/test_hypertoroidal_particle_filter.py | 6 +++--- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/pyrecest/tests/filters/test_euclidean_particle_filter.py b/pyrecest/tests/filters/test_euclidean_particle_filter.py index 543e5267..838e5180 100644 --- a/pyrecest/tests/filters/test_euclidean_particle_filter.py +++ b/pyrecest/tests/filters/test_euclidean_particle_filter.py @@ -48,20 +48,19 @@ def f(x, w): npt.assert_allclose(est, self.prior.mu + mean(samples, axis=0), atol=0.1) def test_predict_update_cycle_3d_forced_particle_pos_no_pred(self): - self.pf.filter_state = self.prior.set_mean(ones(3) + pi / 2.0) - force_first_particle_pos = array([1.1, 2.0, 3.0]) self.pf.filter_state.d[0, :] = force_first_particle_pos - for _ in range(50): + for _ in range(10): # jscpd:ignore-start + self.pf.predict_identity(GaussianDistribution(zeros_like(self.mu), self.C_prior)) self.assertEqual(self.pf.get_point_estimate().shape, (3,)) - for _ in range(3): + for _ in range(4): self.pf.update_identity(self.sys_noise_default, self.forced_mean) # jscpd:ignore-end self.assertEqual(self.pf.get_point_estimate().shape, (3,)) npt.assert_allclose( - self.pf.get_point_estimate(), force_first_particle_pos, atol=1e-10 + self.pf.get_point_estimate(), force_first_particle_pos, atol=0.2 ) diff --git a/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py b/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py index 683496ec..d19dd3f8 100644 --- a/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py +++ b/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py @@ -4,7 +4,7 @@ import numpy.testing as npt # pylint: disable=no-name-in-module,no-member -from pyrecest.backend import array, random, zeros +from pyrecest.backend import array, random, zeros, zeros_like from pyrecest.distributions import HypertoroidalWNDistribution from pyrecest.filters import HypertoroidalParticleFilter @@ -15,7 +15,7 @@ def setUp(self): self.covariance_matrix = array( [[0.7, 0.4, 0.2], [0.4, 0.6, 0.1], [0.2, 0.1, 1]] ) - self.mu = array([1, 1, 1]) + pi / 2 + self.mu = array([1.0, 1.0, 1.0]) + pi / 2 self.hwnd = HypertoroidalWNDistribution(self.mu, self.covariance_matrix) self.hpf = HypertoroidalParticleFilter(500, 3) self.forced_mean = array([1.0, 2.0, 3.0]) @@ -40,7 +40,7 @@ def test_update_identity(self): def test_predict_update_cycle_3D(self): self.hpf.filter_state = self.hwnd for _ in range(10): - self.test_predict_identity() + self.hpf.predict_identity(HypertoroidalWNDistribution(zeros_like(self.mu), self.covariance_matrix)) for _ in range(3): self.test_update_identity() npt.assert_allclose(self.hpf.get_point_estimate(), self.forced_mean, atol=0.1) From 101e893feb5b56dbd3d0d9db0c8b5853a15adfae Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Wed, 25 Oct 2023 15:18:58 +0100 Subject: [PATCH 226/232] More --- pyrecest/filters/circular_particle_filter.py | 2 +- pyrecest/tests/filters/test_circular_particle_filter.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyrecest/filters/circular_particle_filter.py b/pyrecest/filters/circular_particle_filter.py index ebd85a3a..c3038067 100644 --- a/pyrecest/filters/circular_particle_filter.py +++ b/pyrecest/filters/circular_particle_filter.py @@ -16,7 +16,7 @@ def __init__(self, n_particles: Union[int, int32, int64]) -> None: :param n_particles: number of particles """ - filter_state = CircularDiracDistribution(linspace(0.0, 2.0 * pi, n_particles)) + filter_state = CircularDiracDistribution(linspace(0.0, 2.0 * pi, n_particles, endpoint=False)) AbstractHypertoroidalFilter.__init__(self, filter_state) AbstractParticleFilter.__init__(self, filter_state) diff --git a/pyrecest/tests/filters/test_circular_particle_filter.py b/pyrecest/tests/filters/test_circular_particle_filter.py index 02a3711a..b9329bc6 100644 --- a/pyrecest/tests/filters/test_circular_particle_filter.py +++ b/pyrecest/tests/filters/test_circular_particle_filter.py @@ -27,7 +27,7 @@ def setUp(self): self.wn = WrappedNormalDistribution(array(1.3), array(0.8)) def test_estimate(self): - self.assertTrue(allclose(self.dist.trigonometric_moment(1), 0.0, atol=1e-10)) + npt.assert_array_almost_equal(self.dist.trigonometric_moment(1), 0.0) def test_setting_state(self): # sanity check From e6bfb02af6e13f3dd493de7e8e0603406e475a34 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Wed, 25 Oct 2023 15:33:05 +0100 Subject: [PATCH 227/232] More... --- pyrecest/_backend/pytorch/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrecest/_backend/pytorch/__init__.py b/pyrecest/_backend/pytorch/__init__.py index 94c40e5c..4208e9c1 100644 --- a/pyrecest/_backend/pytorch/__init__.py +++ b/pyrecest/_backend/pytorch/__init__.py @@ -132,7 +132,7 @@ def _raise_not_implemented_error(*args, **kwargs): arctan2 = _box_binary_scalar(target=_torch.atan2) -mod = _box_binary_scalar(target=_torch.fmod, box_x2=False) +mod = _box_binary_scalar(target=_torch.remainder, box_x2=False) power = _box_binary_scalar(target=_torch.pow, box_x2=False) From dea6d8a5008957c984e4463cf4e214c604918805 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Wed, 25 Oct 2023 17:20:07 +0200 Subject: [PATCH 228/232] More --- pyrecest/sampling/hyperspherical_sampler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrecest/sampling/hyperspherical_sampler.py b/pyrecest/sampling/hyperspherical_sampler.py index 204d43eb..e9694723 100644 --- a/pyrecest/sampling/hyperspherical_sampler.py +++ b/pyrecest/sampling/hyperspherical_sampler.py @@ -211,7 +211,7 @@ def get_grid(self, grid_density_parameter, dim: int = 3): healpix_points = empty((numpixels, 2)) for j in range(numpixels): theta, phi = hp.pix2ang(nside, j, nest=True) - healpix_points[j] = [theta, phi] + healpix_points[j] = array([theta, phi]) for j in range(len(healpix_points)): for k in range(len(psi_points)): From 590cce9ceaf2e81584e9133e278b6ccdde922f81 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Wed, 25 Oct 2023 16:30:07 +0100 Subject: [PATCH 229/232] More --- pyrecest/_backend/pytorch/__init__.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pyrecest/_backend/pytorch/__init__.py b/pyrecest/_backend/pytorch/__init__.py index 4208e9c1..6a5331ba 100644 --- a/pyrecest/_backend/pytorch/__init__.py +++ b/pyrecest/_backend/pytorch/__init__.py @@ -432,10 +432,8 @@ def linspace(start, stop, num=50, endpoint=True, dtype=None): if not (start_is_array or stop_is_array) and endpoint: return _torch.linspace(start=start, end=stop, steps=num, dtype=dtype) - elif not (start_is_array or stop_is_array): # Added for pyrecest + elif not endpoint: # Added for pyrecest return _torch.arange(start=start, end=stop, step=(stop-start)/num, dtype=dtype) - elif endpoint: - raise ValueError("endpoint=False not supported for vectors") if not start_is_array: start = _torch.tensor(start) From f73bc0d8f21f1befca6eece554788ca3a0d702ad Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Wed, 25 Oct 2023 17:17:40 +0100 Subject: [PATCH 230/232] Cleanup --- pyrecest/__init__.py | 2 +- pyrecest/_backend/__init__.py | 2 -- ...ypersphere_cart_prod_dirac_distribution.py | 2 +- .../abstract_nearest_neighbor_tracker.py | 5 +++-- pyrecest/filters/abstract_particle_filter.py | 19 +++++++++++++------ pyrecest/filters/circular_particle_filter.py | 16 ++++++++++------ pyrecest/filters/von_mises_filter.py | 1 - .../test_hypertoroidal_dirac_distribution.py | 2 +- .../filters/test_circular_particle_filter.py | 2 +- .../filters/test_euclidean_particle_filter.py | 5 +++-- .../test_hypertoroidal_particle_filter.py | 4 +++- 11 files changed, 36 insertions(+), 24 deletions(-) diff --git a/pyrecest/__init__.py b/pyrecest/__init__.py index b1413bfd..8856bac1 100644 --- a/pyrecest/__init__.py +++ b/pyrecest/__init__.py @@ -1 +1 @@ -import pyrecest._backend # noqa \ No newline at end of file +import pyrecest._backend # noqa diff --git a/pyrecest/_backend/__init__.py b/pyrecest/_backend/__init__.py index 2e6bfef3..00133682 100644 --- a/pyrecest/_backend/__init__.py +++ b/pyrecest/_backend/__init__.py @@ -13,9 +13,7 @@ def get_backend_name(): - #return os.environ.get("PYRECEST_BACKEND", "numpy") return os.environ.get("PYRECEST_BACKEND", "pytorch") - #return os.environ.get("PYRECEST_BACKEND", "jax") BACKEND_NAME = get_backend_name() diff --git a/pyrecest/distributions/cart_prod/lin_hypersphere_cart_prod_dirac_distribution.py b/pyrecest/distributions/cart_prod/lin_hypersphere_cart_prod_dirac_distribution.py index a0cb0083..27747ea1 100644 --- a/pyrecest/distributions/cart_prod/lin_hypersphere_cart_prod_dirac_distribution.py +++ b/pyrecest/distributions/cart_prod/lin_hypersphere_cart_prod_dirac_distribution.py @@ -1,5 +1,5 @@ # pylint: disable=redefined-builtin,no-name-in-module,no-member -from pyrecest.backend import abs, linalg, amax +from pyrecest.backend import abs, amax, linalg from ..abstract_se3_distribution import AbstractSE3Distribution from .lin_bounded_cart_prod_dirac_distribution import ( diff --git a/pyrecest/filters/abstract_nearest_neighbor_tracker.py b/pyrecest/filters/abstract_nearest_neighbor_tracker.py index 1005846e..021f4cbe 100644 --- a/pyrecest/filters/abstract_nearest_neighbor_tracker.py +++ b/pyrecest/filters/abstract_nearest_neighbor_tracker.py @@ -2,10 +2,11 @@ import warnings from abc import abstractmethod -# pylint: disable=no-name-in-module,no-member -from pyrecest.backend import dstack, empty, ndim # pylint: disable=no-name-in-module,no-member import pyrecest.backend + +# pylint: disable=no-name-in-module,no-member +from pyrecest.backend import dstack, empty, ndim from pyrecest.distributions import GaussianDistribution from .abstract_euclidean_filter import AbstractEuclideanFilter diff --git a/pyrecest/filters/abstract_particle_filter.py b/pyrecest/filters/abstract_particle_filter.py index 50573af0..9982d013 100644 --- a/pyrecest/filters/abstract_particle_filter.py +++ b/pyrecest/filters/abstract_particle_filter.py @@ -1,5 +1,6 @@ -from collections.abc import Callable import copy +from collections.abc import Callable + # pylint: disable=redefined-builtin,no-name-in-module,no-member # pylint: disable=no-name-in-module,no-member from pyrecest.backend import ndim, ones_like, random, sum, zeros @@ -57,24 +58,30 @@ def predict_nonlinear_nonadditive(self, f, samples, weights): d[i, :] = f(self.filter_state.d[i, :], noise_samples[i]) self._filter_state.d = d - + @property def filter_state(self): return self._filter_state - + @filter_state.setter def filter_state(self, new_state): if self._filter_state is None: self._filter_state = copy.deepcopy(new_state) elif isinstance(new_state, type(self.filter_state)): - assert self.filter_state.d.shape == new_state.d.shape # This also ensures the dimension and type stays the same + assert ( + self.filter_state.d.shape == new_state.d.shape + ) # This also ensures the dimension and type stays the same self._filter_state = copy.deepcopy(new_state) else: # Sample if it does not inherit from the previous distribution samples = new_state.sample(self.filter_state.w.shape[0]) - assert samples.shape == self.filter_state.d.shape # This also ensures the dimension and type stays the same + assert ( + samples.shape == self.filter_state.d.shape + ) # This also ensures the dimension and type stays the same self._filter_state.d = samples - self._filter_state.w = ones_like(self.filter_state.w) / self.filter_state.w.shape[0] + self._filter_state.w = ( + ones_like(self.filter_state.w) / self.filter_state.w.shape[0] + ) def update_identity( self, meas_noise, measurement, shift_instead_of_add: bool = True diff --git a/pyrecest/filters/circular_particle_filter.py b/pyrecest/filters/circular_particle_filter.py index c3038067..0de70619 100644 --- a/pyrecest/filters/circular_particle_filter.py +++ b/pyrecest/filters/circular_particle_filter.py @@ -1,12 +1,14 @@ -from typing import Union from math import pi +from typing import Union + # pylint: disable=redefined-builtin,no-name-in-module,no-member -from pyrecest.backend import float64, int32, int64, sum, linspace +from pyrecest.backend import float64, int32, int64, linspace, sum +from pyrecest.distributions import CircularDiracDistribution -from .hypertoroidal_particle_filter import HypertoroidalParticleFilter from .abstract_hypertoroidal_filter import AbstractHypertoroidalFilter from .abstract_particle_filter import AbstractParticleFilter -from pyrecest.distributions import CircularDiracDistribution +from .hypertoroidal_particle_filter import HypertoroidalParticleFilter + class CircularParticleFilter(HypertoroidalParticleFilter): # pylint: disable=non-parent-init-called,super-init-not-called @@ -16,10 +18,12 @@ def __init__(self, n_particles: Union[int, int32, int64]) -> None: :param n_particles: number of particles """ - filter_state = CircularDiracDistribution(linspace(0.0, 2.0 * pi, n_particles, endpoint=False)) + filter_state = CircularDiracDistribution( + linspace(0.0, 2.0 * pi, n_particles, endpoint=False) + ) AbstractHypertoroidalFilter.__init__(self, filter_state) AbstractParticleFilter.__init__(self, filter_state) - + def compute_association_likelihood(self, likelihood) -> float64: """ Compute the likelihood of association based on the PDF of the likelihood diff --git a/pyrecest/filters/von_mises_filter.py b/pyrecest/filters/von_mises_filter.py index 87f47951..72addffd 100644 --- a/pyrecest/filters/von_mises_filter.py +++ b/pyrecest/filters/von_mises_filter.py @@ -1,4 +1,3 @@ -import copy import warnings from math import pi diff --git a/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py b/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py index bac3336f..b305bc73 100644 --- a/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py +++ b/pyrecest/tests/distributions/test_hypertoroidal_dirac_distribution.py @@ -8,10 +8,10 @@ # pylint: disable=no-name-in-module,no-member from pyrecest.backend import array, exp, mod, random, sum, zeros_like from pyrecest.distributions import ( + AbstractHypertoroidalDistribution, HypertoroidalDiracDistribution, ToroidalDiracDistribution, ) -from pyrecest.distributions import AbstractHypertoroidalDistribution class TestHypertoroidalDiracDistribution(unittest.TestCase): diff --git a/pyrecest/tests/filters/test_circular_particle_filter.py b/pyrecest/tests/filters/test_circular_particle_filter.py index b9329bc6..554185b5 100644 --- a/pyrecest/tests/filters/test_circular_particle_filter.py +++ b/pyrecest/tests/filters/test_circular_particle_filter.py @@ -4,7 +4,7 @@ import numpy.testing as npt # pylint: disable=no-name-in-module,no-member -from pyrecest.backend import allclose, arange, array, random, linspace +from pyrecest.backend import arange, array, linspace, random from pyrecest.distributions import ( HypertoroidalDiracDistribution, WrappedNormalDistribution, diff --git a/pyrecest/tests/filters/test_euclidean_particle_filter.py b/pyrecest/tests/filters/test_euclidean_particle_filter.py index 838e5180..bb3d139e 100644 --- a/pyrecest/tests/filters/test_euclidean_particle_filter.py +++ b/pyrecest/tests/filters/test_euclidean_particle_filter.py @@ -1,5 +1,4 @@ import unittest -from math import pi import numpy.testing as npt @@ -52,7 +51,9 @@ def test_predict_update_cycle_3d_forced_particle_pos_no_pred(self): self.pf.filter_state.d[0, :] = force_first_particle_pos for _ in range(10): # jscpd:ignore-start - self.pf.predict_identity(GaussianDistribution(zeros_like(self.mu), self.C_prior)) + self.pf.predict_identity( + GaussianDistribution(zeros_like(self.mu), self.C_prior) + ) self.assertEqual(self.pf.get_point_estimate().shape, (3,)) for _ in range(4): self.pf.update_identity(self.sys_noise_default, self.forced_mean) diff --git a/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py b/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py index d19dd3f8..004ccd8d 100644 --- a/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py +++ b/pyrecest/tests/filters/test_hypertoroidal_particle_filter.py @@ -40,7 +40,9 @@ def test_update_identity(self): def test_predict_update_cycle_3D(self): self.hpf.filter_state = self.hwnd for _ in range(10): - self.hpf.predict_identity(HypertoroidalWNDistribution(zeros_like(self.mu), self.covariance_matrix)) + self.hpf.predict_identity( + HypertoroidalWNDistribution(zeros_like(self.mu), self.covariance_matrix) + ) for _ in range(3): self.test_update_identity() npt.assert_allclose(self.hpf.get_point_estimate(), self.forced_mean, atol=0.1) From f715e792ae1a0d838e2a5bbbd18562b91d379f3c Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Wed, 25 Oct 2023 17:20:10 +0100 Subject: [PATCH 231/232] Set default to numpy --- pyrecest/_backend/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrecest/_backend/__init__.py b/pyrecest/_backend/__init__.py index 00133682..7bf66b50 100644 --- a/pyrecest/_backend/__init__.py +++ b/pyrecest/_backend/__init__.py @@ -13,7 +13,7 @@ def get_backend_name(): - return os.environ.get("PYRECEST_BACKEND", "pytorch") + return os.environ.get("PYRECEST_BACKEND", "numpy") BACKEND_NAME = get_backend_name() From 33e4451a1a54fe7f8903b1a5b9a23a0732d34843 Mon Sep 17 00:00:00 2001 From: Florian Pfaff Date: Wed, 25 Oct 2023 17:20:47 +0100 Subject: [PATCH 232/232] More --- pyrecest/_backend/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrecest/_backend/__init__.py b/pyrecest/_backend/__init__.py index 7bf66b50..5e2a5008 100644 --- a/pyrecest/_backend/__init__.py +++ b/pyrecest/_backend/__init__.py @@ -294,7 +294,7 @@ def _create_backend_module(self, backend_name): f"attribute '{attribute_name}'" ) - # raise RuntimeError(error) from None + raise RuntimeError(error) from None else: setattr(new_submodule, attribute_name, attribute)